diff --git a/CMake/Target.cmake b/CMake/Target.cmake index 984b093e3..74594f097 100644 --- a/CMake/Target.cmake +++ b/CMake/Target.cmake @@ -415,8 +415,8 @@ function(exp_add_mirror_info_source_generation_target) add_custom_command( OUTPUT ${output_source} - COMMAND "$" ${dynamic_arg} "-i" ${input_header_file} "-o" ${output_source} ${inc_args} ${fwk_dir_args} - DEPENDS MirrorTool ${input_header_file} + COMMAND "$" ${dynamic_arg} "-i" ${input_header_file} "-o" ${output_source} ${inc_args} ${fwk_dir_args} + DEPENDS MirrorSourceGenerator ${input_header_file} ) endforeach() endforeach () @@ -424,7 +424,7 @@ function(exp_add_mirror_info_source_generation_target) set(custom_target_name "${arg_NAME}.Generated") add_custom_target( ${custom_target_name} - DEPENDS MirrorTool ${output_sources} + DEPENDS MirrorSourceGenerator ${output_sources} ) set_target_properties(${custom_target_name} PROPERTIES FOLDER ${AUX_TARGETS_FOLDER}) set(${arg_OUTPUT_SRC} ${output_sources} PARENT_SCOPE) diff --git a/CMakeLists.txt b/CMakeLists.txt index c006e38c4..429c25758 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,7 +40,7 @@ else () endif () add_subdirectory(Engine) -add_subdirectory(Tool) +add_subdirectory(Program) add_subdirectory(Sample) if (BUILD_EDITOR) diff --git a/Editor/Include/Editor/Widget/IconWidgets.h b/Editor/Include/Editor/Widget/IconWidgets.h new file mode 100644 index 000000000..843223a32 --- /dev/null +++ b/Editor/Include/Editor/Widget/IconWidgets.h @@ -0,0 +1,10 @@ +#pragma once + +#include +#include + +namespace Editor::Widgets { + std::string Label(const char* inIcon, std::string_view inText); + std::string Label(const char* inIcon, std::string_view inText, std::string_view inId); + bool IconButton(const char* inId, const char* inIcon, const char* inTooltip); +} diff --git a/Editor/Include/Editor/Widget/TablerIcons.h b/Editor/Include/Editor/Widget/TablerIcons.h new file mode 100644 index 000000000..b57ec7eb3 --- /dev/null +++ b/Editor/Include/Editor/Widget/TablerIcons.h @@ -0,0 +1,5342 @@ +#pragma once + +// Generated from @tabler/icons-webfont v3.45.0 by Tool/Scripts/IconFontGenerator/tabler.py. +namespace Editor::Icons::Tabler { + inline constexpr char aB[] = "\xee\xb0\xb6"; + inline constexpr char aB2[] = "\xef\x89\x9f"; + inline constexpr char aBOff[] = "\xef\x82\xa6"; + inline constexpr char abacus[] = "\xef\x81\x9c"; + inline constexpr char abacusOff[] = "\xef\x8e\xb6"; + inline constexpr char abc[] = "\xef\x95\xa7"; + inline constexpr char accessPoint[] = "\xee\xb4\x9b"; + inline constexpr char accessPointOff[] = "\xee\xb4\x9a"; + inline constexpr char accessible[] = "\xee\xae\xa9"; + inline constexpr char accessibleOff[] = "\xef\x82\xa7"; + inline constexpr char acorn[] = "\xf0\x90\x89\x95"; + inline constexpr char acrobatic[] = "\xf0\x90\x89\x94"; + inline constexpr char activity[] = "\xee\xb4\xa3"; + inline constexpr char activityHeartbeat[] = "\xef\x83\x9b"; + inline constexpr char ad[] = "\xee\xa8\x82"; + inline constexpr char ad2[] = "\xee\xbc\x9f"; + inline constexpr char adCircle[] = "\xef\x9e\x9e"; + inline constexpr char adCircleOff[] = "\xef\x9e\x9d"; + inline constexpr char adOff[] = "\xef\x8e\xb7"; + inline constexpr char addressBook[] = "\xef\x80\xa1"; + inline constexpr char addressBookOff[] = "\xef\x8e\xb8"; + inline constexpr char adjustments[] = "\xee\xa8\x83"; + inline constexpr char adjustmentsAlt[] = "\xee\xb0\xb7"; + inline constexpr char adjustmentsBolt[] = "\xef\x9f\xbb"; + inline constexpr char adjustmentsCancel[] = "\xef\x9f\xbc"; + inline constexpr char adjustmentsCheck[] = "\xef\x9f\xbd"; + inline constexpr char adjustmentsCode[] = "\xef\x9f\xbe"; + inline constexpr char adjustmentsCog[] = "\xef\x9f\xbf"; + inline constexpr char adjustmentsDollar[] = "\xef\xa0\x80"; + inline constexpr char adjustmentsDown[] = "\xef\xa0\x81"; + inline constexpr char adjustmentsExclamation[] = "\xef\xa0\x82"; + inline constexpr char adjustmentsHeart[] = "\xef\xa0\x83"; + inline constexpr char adjustmentsHorizontal[] = "\xee\xb0\xb8"; + inline constexpr char adjustmentsMinus[] = "\xef\xa0\x84"; + inline constexpr char adjustmentsOff[] = "\xef\x82\xa8"; + inline constexpr char adjustmentsPause[] = "\xef\xa0\x85"; + inline constexpr char adjustmentsPin[] = "\xef\xa0\x86"; + inline constexpr char adjustmentsPlus[] = "\xef\xa0\x87"; + inline constexpr char adjustmentsQuestion[] = "\xef\xa0\x88"; + inline constexpr char adjustmentsSearch[] = "\xef\xa0\x89"; + inline constexpr char adjustmentsShare[] = "\xef\xa0\x8a"; + inline constexpr char adjustmentsSpark[] = "\xef\xbe\xbe"; + inline constexpr char adjustmentsStar[] = "\xef\xa0\x8b"; + inline constexpr char adjustmentsUp[] = "\xef\xa0\x8c"; + inline constexpr char adjustmentsX[] = "\xef\xa0\x8d"; + inline constexpr char aerialLift[] = "\xee\xb7\xbe"; + inline constexpr char affiliate[] = "\xee\xb7\xbf"; + inline constexpr char ai[] = "\xef\xbb\xa7"; + inline constexpr char aiAgent[] = "\xf0\x90\x87\xb9"; + inline constexpr char aiAgents[] = "\xf0\x90\x87\xb8"; + inline constexpr char aiGateway[] = "\xf0\x90\x87\xb7"; + inline constexpr char airBalloon[] = "\xef\x92\xa6"; + inline constexpr char airConditioning[] = "\xef\x8e\xa2"; + inline constexpr char airConditioningDisabled[] = "\xef\x95\x82"; + inline constexpr char airTrafficControl[] = "\xef\xac\x81"; + inline constexpr char alarm[] = "\xee\xa8\x84"; + inline constexpr char alarmAverage[] = "\xef\xb2\x9e"; + inline constexpr char alarmMinus[] = "\xef\x98\xb0"; + inline constexpr char alarmOff[] = "\xef\x82\xa9"; + inline constexpr char alarmPlus[] = "\xef\x98\xb1"; + inline constexpr char alarmSmoke[] = "\xf0\x90\x82\xb6"; + inline constexpr char alarmSnooze[] = "\xef\x98\xb2"; + inline constexpr char album[] = "\xef\x80\xa2"; + inline constexpr char albumOff[] = "\xef\x8e\xb9"; + inline constexpr char alertCircle[] = "\xee\xa8\x85"; + inline constexpr char alertCircleOff[] = "\xef\xb1\xa5"; + inline constexpr char alertHexagon[] = "\xef\xa0\x8e"; + inline constexpr char alertHexagonOff[] = "\xef\xb1\xa6"; + inline constexpr char alertOctagon[] = "\xee\xb3\x86"; + inline constexpr char alertSmall[] = "\xef\xa0\x8f"; + inline constexpr char alertSmallOff[] = "\xef\xb1\xa7"; + inline constexpr char alertSquare[] = "\xef\xa0\x91"; + inline constexpr char alertSquareRounded[] = "\xef\xa0\x90"; + inline constexpr char alertSquareRoundedOff[] = "\xef\xb1\xa8"; + inline constexpr char alertTriangle[] = "\xee\xa8\x86"; + inline constexpr char alertTriangleOff[] = "\xef\xb1\xa9"; + inline constexpr char alien[] = "\xee\xaf\x9e"; + inline constexpr char alignBoxBottomCenter[] = "\xef\x94\xb0"; + inline constexpr char alignBoxBottomLeft[] = "\xef\x94\xb1"; + inline constexpr char alignBoxBottomRight[] = "\xef\x94\xb2"; + inline constexpr char alignBoxCenterBottom[] = "\xef\xab\x8b"; + inline constexpr char alignBoxCenterMiddle[] = "\xef\x9e\x9f"; + inline constexpr char alignBoxCenterStretch[] = "\xef\xab\x8c"; + inline constexpr char alignBoxCenterTop[] = "\xef\xab\x8d"; + inline constexpr char alignBoxLeftBottom[] = "\xef\x94\xb3"; + inline constexpr char alignBoxLeftMiddle[] = "\xef\x94\xb4"; + inline constexpr char alignBoxLeftStretch[] = "\xef\xab\x8e"; + inline constexpr char alignBoxLeftTop[] = "\xef\x94\xb5"; + inline constexpr char alignBoxRightBottom[] = "\xef\x94\xb6"; + inline constexpr char alignBoxRightMiddle[] = "\xef\x94\xb7"; + inline constexpr char alignBoxRightStretch[] = "\xef\xab\x8f"; + inline constexpr char alignBoxRightTop[] = "\xef\x94\xb8"; + inline constexpr char alignBoxTopCenter[] = "\xef\x94\xb9"; + inline constexpr char alignBoxTopLeft[] = "\xef\x94\xba"; + inline constexpr char alignBoxTopRight[] = "\xef\x94\xbb"; + inline constexpr char alignCenter[] = "\xee\xa8\x87"; + inline constexpr char alignJustified[] = "\xee\xa8\x88"; + inline constexpr char alignLeft[] = "\xee\xa8\x89"; + inline constexpr char alignLeft2[] = "\xef\xbc\x80"; + inline constexpr char alignRight[] = "\xee\xa8\x8a"; + inline constexpr char alignRight2[] = "\xef\xbb\xbf"; + inline constexpr char alpha[] = "\xef\x95\x83"; + inline constexpr char alphabetArabic[] = "\xef\xbc\xaf"; + inline constexpr char alphabetBangla[] = "\xef\xbc\xae"; + inline constexpr char alphabetCyrillic[] = "\xef\x87\x9f"; + inline constexpr char alphabetGreek[] = "\xef\x87\xa0"; + inline constexpr char alphabetHebrew[] = "\xef\xbc\xad"; + inline constexpr char alphabetKorean[] = "\xef\xbc\xac"; + inline constexpr char alphabetLatin[] = "\xef\x87\xa1"; + inline constexpr char alphabetPolish[] = "\xf0\x90\x86\xb1"; + inline constexpr char alphabetRunes[] = "\xf0\x90\x86\xb0"; + inline constexpr char alphabetThai[] = "\xef\xbc\xab"; + inline constexpr char alt[] = "\xef\xb1\x94"; + inline constexpr char ambulance[] = "\xee\xaf\xb5"; + inline constexpr char ampersand[] = "\xef\x88\xa9"; + inline constexpr char analyze[] = "\xef\x8e\xa3"; + inline constexpr char analyzeOff[] = "\xef\x8e\xba"; + inline constexpr char anchor[] = "\xee\xad\xb6"; + inline constexpr char anchorOff[] = "\xef\x83\xb7"; + inline constexpr char angle[] = "\xee\xbc\xa0"; + inline constexpr char ankh[] = "\xef\x87\x8d"; + inline constexpr char antenna[] = "\xef\x82\x94"; + inline constexpr char antennaBars1[] = "\xee\xb3\x87"; + inline constexpr char antennaBars2[] = "\xee\xb3\x88"; + inline constexpr char antennaBars3[] = "\xee\xb3\x89"; + inline constexpr char antennaBars4[] = "\xee\xb3\x8a"; + inline constexpr char antennaBars5[] = "\xee\xb3\x8b"; + inline constexpr char antennaBarsOff[] = "\xef\x82\xaa"; + inline constexpr char antennaOff[] = "\xef\x8e\xbb"; + inline constexpr char aperture[] = "\xee\xad\x98"; + inline constexpr char apertureOff[] = "\xef\x8e\xbc"; + inline constexpr char api[] = "\xee\xbf\xbd"; + inline constexpr char apiApp[] = "\xee\xbf\xbc"; + inline constexpr char apiAppOff[] = "\xef\x82\xab"; + inline constexpr char apiBook[] = "\xf0\x90\x88\x8b"; + inline constexpr char apiOff[] = "\xef\x83\xb8"; + inline constexpr char appWindow[] = "\xee\xbf\xa6"; + inline constexpr char appWindowBottom[] = "\xf0\x90\x89\xb8"; + inline constexpr char appWindowBottomLeft[] = "\xf0\x90\x89\xba"; + inline constexpr char appWindowBottomRight[] = "\xf0\x90\x89\xb9"; + inline constexpr char appWindowCenter[] = "\xf0\x90\x89\xb7"; + inline constexpr char apple[] = "\xee\xbc\xa1"; + inline constexpr char apps[] = "\xee\xae\xb6"; + inline constexpr char appsOff[] = "\xef\x82\xac"; + inline constexpr char archeryArrow[] = "\xef\xb1\x95"; + inline constexpr char archive[] = "\xee\xa8\x8b"; + inline constexpr char archiveOff[] = "\xef\x82\xad"; + inline constexpr char armchair[] = "\xee\xbe\x9e"; + inline constexpr char armchair2[] = "\xee\xbf\xa7"; + inline constexpr char armchair2Off[] = "\xef\x8e\xbd"; + inline constexpr char armchairOff[] = "\xef\x8e\xbe"; + inline constexpr char arrowAutofitContent[] = "\xee\xbc\xb1"; + inline constexpr char arrowAutofitDown[] = "\xee\xbc\xb2"; + inline constexpr char arrowAutofitHeight[] = "\xee\xbc\xb3"; + inline constexpr char arrowAutofitLeft[] = "\xee\xbc\xb4"; + inline constexpr char arrowAutofitRight[] = "\xee\xbc\xb5"; + inline constexpr char arrowAutofitUp[] = "\xee\xbc\xb6"; + inline constexpr char arrowAutofitWidth[] = "\xee\xbc\xb7"; + inline constexpr char arrowBack[] = "\xee\xa8\x8c"; + inline constexpr char arrowBackUp[] = "\xee\xad\xb7"; + inline constexpr char arrowBackUpDouble[] = "\xef\xa7\xac"; + inline constexpr char arrowBadgeDown[] = "\xef\x98\x8b"; + inline constexpr char arrowBadgeLeft[] = "\xef\x98\x8c"; + inline constexpr char arrowBadgeRight[] = "\xef\x98\x8d"; + inline constexpr char arrowBadgeUp[] = "\xef\x98\x8e"; + inline constexpr char arrowBarBoth[] = "\xef\xab\x9d"; + inline constexpr char arrowBarDown[] = "\xee\xa8\x8d"; + inline constexpr char arrowBarLeft[] = "\xee\xa8\x8e"; + inline constexpr char arrowBarRight[] = "\xee\xa8\x8f"; + inline constexpr char arrowBarToDown[] = "\xee\xb2\x88"; + inline constexpr char arrowBarToDownDashed[] = "\xf0\x90\x85\xa4"; + inline constexpr char arrowBarToLeft[] = "\xee\xb2\x89"; + inline constexpr char arrowBarToLeftDashed[] = "\xf0\x90\x85\xa3"; + inline constexpr char arrowBarToRight[] = "\xee\xb2\x8a"; + inline constexpr char arrowBarToRightDashed[] = "\xf0\x90\x85\xa2"; + inline constexpr char arrowBarToUp[] = "\xee\xb2\x8b"; + inline constexpr char arrowBarToUpDashed[] = "\xf0\x90\x85\xa1"; + inline constexpr char arrowBarUp[] = "\xee\xa8\x90"; + inline constexpr char arrowBearLeft[] = "\xef\x81\x85"; + inline constexpr char arrowBearLeft2[] = "\xef\x81\x84"; + inline constexpr char arrowBearRight[] = "\xef\x81\x87"; + inline constexpr char arrowBearRight2[] = "\xef\x81\x86"; + inline constexpr char arrowBigDown[] = "\xee\xb7\x9a"; + inline constexpr char arrowBigDownLine[] = "\xee\xbf\xa8"; + inline constexpr char arrowBigDownLines[] = "\xee\xbf\xa9"; + inline constexpr char arrowBigLeft[] = "\xee\xb7\x9b"; + inline constexpr char arrowBigLeftLine[] = "\xee\xbf\xaa"; + inline constexpr char arrowBigLeftLines[] = "\xee\xbf\xab"; + inline constexpr char arrowBigRight[] = "\xee\xb7\x9c"; + inline constexpr char arrowBigRightLine[] = "\xee\xbf\xac"; + inline constexpr char arrowBigRightLines[] = "\xee\xbf\xad"; + inline constexpr char arrowBigUp[] = "\xee\xb7\x9d"; + inline constexpr char arrowBigUpLine[] = "\xee\xbf\xae"; + inline constexpr char arrowBigUpLines[] = "\xee\xbf\xaf"; + inline constexpr char arrowBounce[] = "\xef\x8e\xa4"; + inline constexpr char arrowCapsule[] = "\xef\xab\x9e"; + inline constexpr char arrowCurveLeft[] = "\xef\x81\x88"; + inline constexpr char arrowCurveRight[] = "\xef\x81\x89"; + inline constexpr char arrowDown[] = "\xee\xa8\x96"; + inline constexpr char arrowDownBar[] = "\xee\xb6\x98"; + inline constexpr char arrowDownCircle[] = "\xee\xa8\x91"; + inline constexpr char arrowDownDashed[] = "\xf0\x90\x81\xaa"; + inline constexpr char arrowDownFromArc[] = "\xef\xb6\x86"; + inline constexpr char arrowDownLeft[] = "\xee\xa8\x93"; + inline constexpr char arrowDownLeftCircle[] = "\xee\xa8\x92"; + inline constexpr char arrowDownRhombus[] = "\xef\x98\x9d"; + inline constexpr char arrowDownRight[] = "\xee\xa8\x95"; + inline constexpr char arrowDownRightCircle[] = "\xee\xa8\x94"; + inline constexpr char arrowDownSquare[] = "\xee\xb6\x9a"; + inline constexpr char arrowDownTail[] = "\xee\xb6\x9b"; + inline constexpr char arrowDownToArc[] = "\xef\xb6\x87"; + inline constexpr char arrowElbowLeft[] = "\xef\xa7\xad"; + inline constexpr char arrowElbowRight[] = "\xef\xa7\xae"; + inline constexpr char arrowFork[] = "\xef\x81\x8a"; + inline constexpr char arrowForkTriple[] = "\xf0\x90\x89\xb6"; + inline constexpr char arrowForward[] = "\xee\xa8\x97"; + inline constexpr char arrowForwardUp[] = "\xee\xad\xb8"; + inline constexpr char arrowForwardUpDouble[] = "\xef\xa7\xaf"; + inline constexpr char arrowGuide[] = "\xef\x88\xaa"; + inline constexpr char arrowIteration[] = "\xef\x95\xb8"; + inline constexpr char arrowLeft[] = "\xee\xa8\x99"; + inline constexpr char arrowLeftBar[] = "\xee\xb6\x9c"; + inline constexpr char arrowLeftCircle[] = "\xee\xa8\x98"; + inline constexpr char arrowLeftDashed[] = "\xf0\x90\x81\xa9"; + inline constexpr char arrowLeftFromArc[] = "\xef\xb6\x88"; + inline constexpr char arrowLeftRhombus[] = "\xef\x98\x9e"; + inline constexpr char arrowLeftRight[] = "\xef\x81\x8b"; + inline constexpr char arrowLeftSquare[] = "\xee\xb6\x9d"; + inline constexpr char arrowLeftTail[] = "\xee\xb6\x9e"; + inline constexpr char arrowLeftToArc[] = "\xef\xb6\x89"; + inline constexpr char arrowLoopLeft[] = "\xee\xb6\x9f"; + inline constexpr char arrowLoopLeft2[] = "\xef\x81\x8c"; + inline constexpr char arrowLoopRight[] = "\xee\xb6\xa0"; + inline constexpr char arrowLoopRight2[] = "\xef\x81\x8d"; + inline constexpr char arrowMerge[] = "\xef\x81\x8e"; + inline constexpr char arrowMergeAltLeft[] = "\xef\xb2\x9f"; + inline constexpr char arrowMergeAltRight[] = "\xef\xb2\xa0"; + inline constexpr char arrowMergeBoth[] = "\xef\x88\xbb"; + inline constexpr char arrowMergeLeft[] = "\xef\x88\xbc"; + inline constexpr char arrowMergeRight[] = "\xef\x88\xbd"; + inline constexpr char arrowMoveDown[] = "\xef\x8a\xba"; + inline constexpr char arrowMoveLeft[] = "\xef\x8a\xbb"; + inline constexpr char arrowMoveRight[] = "\xef\x8a\xbc"; + inline constexpr char arrowMoveUp[] = "\xef\x8a\xbd"; + inline constexpr char arrowNarrowDown[] = "\xee\xa8\x9a"; + inline constexpr char arrowNarrowDownDashed[] = "\xf0\x90\x81\xa8"; + inline constexpr char arrowNarrowLeft[] = "\xee\xa8\x9b"; + inline constexpr char arrowNarrowLeftDashed[] = "\xf0\x90\x81\xa7"; + inline constexpr char arrowNarrowRight[] = "\xee\xa8\x9c"; + inline constexpr char arrowNarrowRightDashed[] = "\xf0\x90\x81\xa6"; + inline constexpr char arrowNarrowUp[] = "\xee\xa8\x9d"; + inline constexpr char arrowNarrowUpDashed[] = "\xf0\x90\x81\xa5"; + inline constexpr char arrowRampLeft[] = "\xee\xb4\xbc"; + inline constexpr char arrowRampLeft2[] = "\xef\x81\x8f"; + inline constexpr char arrowRampLeft3[] = "\xef\x81\x90"; + inline constexpr char arrowRampRight[] = "\xee\xb4\xbd"; + inline constexpr char arrowRampRight2[] = "\xef\x81\x91"; + inline constexpr char arrowRampRight3[] = "\xef\x81\x92"; + inline constexpr char arrowRight[] = "\xee\xa8\x9f"; + inline constexpr char arrowRightBar[] = "\xee\xb6\xa1"; + inline constexpr char arrowRightCircle[] = "\xee\xa8\x9e"; + inline constexpr char arrowRightDashed[] = "\xf0\x90\x81\xa4"; + inline constexpr char arrowRightFromArc[] = "\xef\xb6\x8a"; + inline constexpr char arrowRightRhombus[] = "\xef\x98\x9f"; + inline constexpr char arrowRightSquare[] = "\xee\xb6\xa2"; + inline constexpr char arrowRightTail[] = "\xee\xb6\xa3"; + inline constexpr char arrowRightToArc[] = "\xef\xb6\x8b"; + inline constexpr char arrowRotaryFirstLeft[] = "\xef\x81\x93"; + inline constexpr char arrowRotaryFirstRight[] = "\xef\x81\x94"; + inline constexpr char arrowRotaryLastLeft[] = "\xef\x81\x95"; + inline constexpr char arrowRotaryLastRight[] = "\xef\x81\x96"; + inline constexpr char arrowRotaryLeft[] = "\xef\x81\x97"; + inline constexpr char arrowRotaryRight[] = "\xef\x81\x98"; + inline constexpr char arrowRotaryStraight[] = "\xef\x81\x99"; + inline constexpr char arrowRoundaboutLeft[] = "\xef\x88\xab"; + inline constexpr char arrowRoundaboutRight[] = "\xef\x88\xac"; + inline constexpr char arrowSharpTurnLeft[] = "\xef\x81\x9a"; + inline constexpr char arrowSharpTurnRight[] = "\xef\x81\x9b"; + inline constexpr char arrowUp[] = "\xee\xa8\xa5"; + inline constexpr char arrowUpBar[] = "\xee\xb6\xa4"; + inline constexpr char arrowUpCircle[] = "\xee\xa8\xa0"; + inline constexpr char arrowUpDashed[] = "\xf0\x90\x81\xa3"; + inline constexpr char arrowUpFromArc[] = "\xef\xb6\x8c"; + inline constexpr char arrowUpLeft[] = "\xee\xa8\xa2"; + inline constexpr char arrowUpLeftCircle[] = "\xee\xa8\xa1"; + inline constexpr char arrowUpRhombus[] = "\xef\x98\xa0"; + inline constexpr char arrowUpRight[] = "\xee\xa8\xa4"; + inline constexpr char arrowUpRightCircle[] = "\xee\xa8\xa3"; + inline constexpr char arrowUpSquare[] = "\xee\xb6\xa6"; + inline constexpr char arrowUpTail[] = "\xee\xb6\xa7"; + inline constexpr char arrowUpToArc[] = "\xef\xb6\x8d"; + inline constexpr char arrowWaveLeftDown[] = "\xee\xb6\xa8"; + inline constexpr char arrowWaveLeftUp[] = "\xee\xb6\xa9"; + inline constexpr char arrowWaveRightDown[] = "\xee\xb6\xaa"; + inline constexpr char arrowWaveRightUp[] = "\xee\xb6\xab"; + inline constexpr char arrowZigZag[] = "\xef\x92\xa7"; + inline constexpr char arrowsCross[] = "\xee\xbf\xbe"; + inline constexpr char arrowsDiagonal[] = "\xee\xa8\xa7"; + inline constexpr char arrowsDiagonal2[] = "\xee\xa8\xa6"; + inline constexpr char arrowsDiagonalMinimize[] = "\xee\xbc\xb9"; + inline constexpr char arrowsDiagonalMinimize2[] = "\xee\xbc\xb8"; + inline constexpr char arrowsDiff[] = "\xef\x8a\x96"; + inline constexpr char arrowsDoubleNeSw[] = "\xee\xb7\x9e"; + inline constexpr char arrowsDoubleNwSe[] = "\xee\xb7\x9f"; + inline constexpr char arrowsDoubleSeNw[] = "\xee\xb7\xa0"; + inline constexpr char arrowsDoubleSwNe[] = "\xee\xb7\xa1"; + inline constexpr char arrowsDown[] = "\xee\xb6\xad"; + inline constexpr char arrowsDownUp[] = "\xee\xb6\xac"; + inline constexpr char arrowsExchange[] = "\xef\x87\xb4"; + inline constexpr char arrowsExchange2[] = "\xef\x87\xb3"; + inline constexpr char arrowsHorizontal[] = "\xee\xad\x99"; + inline constexpr char arrowsJoin[] = "\xee\xb6\xaf"; + inline constexpr char arrowsJoin2[] = "\xee\xb6\xae"; + inline constexpr char arrowsLeft[] = "\xee\xb6\xb1"; + inline constexpr char arrowsLeftDown[] = "\xee\xb8\x80"; + inline constexpr char arrowsLeftRight[] = "\xee\xb6\xb0"; + inline constexpr char arrowsMaximize[] = "\xee\xa8\xa8"; + inline constexpr char arrowsMinimize[] = "\xee\xa8\xa9"; + inline constexpr char arrowsMove[] = "\xef\x88\xaf"; + inline constexpr char arrowsMoveHorizontal[] = "\xef\x88\xad"; + inline constexpr char arrowsMoveVertical[] = "\xef\x88\xae"; + inline constexpr char arrowsRandom[] = "\xef\x82\x95"; + inline constexpr char arrowsRight[] = "\xee\xb6\xb3"; + inline constexpr char arrowsRightDown[] = "\xee\xb8\x81"; + inline constexpr char arrowsRightLeft[] = "\xee\xb6\xb2"; + inline constexpr char arrowsShuffle[] = "\xef\x80\x80"; + inline constexpr char arrowsShuffle2[] = "\xee\xbf\xbf"; + inline constexpr char arrowsSort[] = "\xee\xad\x9a"; + inline constexpr char arrowsSplit[] = "\xee\xb6\xb5"; + inline constexpr char arrowsSplit2[] = "\xee\xb6\xb4"; + inline constexpr char arrowsTransferDown[] = "\xef\x8b\x8c"; + inline constexpr char arrowsTransferUp[] = "\xef\x8b\x8d"; + inline constexpr char arrowsTransferUpDown[] = "\xef\xbe\xac"; + inline constexpr char arrowsUp[] = "\xee\xb6\xb7"; + inline constexpr char arrowsUpDown[] = "\xee\xb6\xb6"; + inline constexpr char arrowsUpLeft[] = "\xee\xb8\x82"; + inline constexpr char arrowsUpRight[] = "\xee\xb8\x83"; + inline constexpr char arrowsVertical[] = "\xee\xad\x9b"; + inline constexpr char artboard[] = "\xee\xa8\xaa"; + inline constexpr char artboardOff[] = "\xef\x82\xae"; + inline constexpr char article[] = "\xef\x87\xa2"; + inline constexpr char articleOff[] = "\xef\x8e\xbf"; + inline constexpr char aspectRatio[] = "\xee\xb4\xb0"; + inline constexpr char aspectRatioOff[] = "\xef\x82\xaf"; + inline constexpr char assembly[] = "\xef\x89\x8d"; + inline constexpr char assemblyOff[] = "\xef\x8f\x80"; + inline constexpr char asset[] = "\xef\x87\x8e"; + inline constexpr char asterisk[] = "\xee\xbf\x95"; + inline constexpr char asteriskSimple[] = "\xee\xbf\x94"; + inline constexpr char at[] = "\xee\xa8\xab"; + inline constexpr char atOff[] = "\xef\x82\xb0"; + inline constexpr char atom[] = "\xee\xad\xb9"; + inline constexpr char atom2[] = "\xee\xaf\x9f"; + inline constexpr char atomOff[] = "\xef\x83\xb9"; + inline constexpr char augmentedReality[] = "\xef\x80\xa3"; + inline constexpr char augmentedReality2[] = "\xef\x8d\xbe"; + inline constexpr char augmentedRealityOff[] = "\xef\x8f\x81"; + inline constexpr char auth2fa[] = "\xee\xb2\xa0"; + inline constexpr char automaticGearbox[] = "\xef\xb2\x89"; + inline constexpr char automation[] = "\xef\xbb\xb8"; + inline constexpr char avocado[] = "\xef\xb6\x8e"; + inline constexpr char award[] = "\xee\xa8\xac"; + inline constexpr char awardOff[] = "\xef\x83\xba"; + inline constexpr char axe[] = "\xee\xbe\x9f"; + inline constexpr char axisX[] = "\xee\xbd\x85"; + inline constexpr char axisY[] = "\xee\xbd\x86"; + inline constexpr char babyBottle[] = "\xef\x97\x92"; + inline constexpr char babyCarriage[] = "\xef\x81\x9d"; + inline constexpr char background[] = "\xef\xb4\xac"; + inline constexpr char backhoe[] = "\xee\xb6\x86"; + inline constexpr char backpack[] = "\xee\xbd\x87"; + inline constexpr char backpackOff[] = "\xef\x8f\x82"; + inline constexpr char backslash[] = "\xef\xaa\xb9"; + inline constexpr char backspace[] = "\xee\xa8\xad"; + inline constexpr char badge[] = "\xee\xbf\x82"; + inline constexpr char badge2k[] = "\xf0\x90\x82\xb5"; + inline constexpr char badge3d[] = "\xef\x95\x95"; + inline constexpr char badge3k[] = "\xf0\x90\x82\xb4"; + inline constexpr char badge4k[] = "\xef\x95\x96"; + inline constexpr char badge5k[] = "\xf0\x90\x82\xb3"; + inline constexpr char badge8k[] = "\xef\x95\x97"; + inline constexpr char badgeAd[] = "\xef\x95\x98"; + inline constexpr char badgeAdOff[] = "\xef\xb6\x8f"; + inline constexpr char badgeAr[] = "\xef\x95\x99"; + inline constexpr char badgeCc[] = "\xef\x95\x9a"; + inline constexpr char badgeHd[] = "\xef\x95\x9b"; + inline constexpr char badgeOff[] = "\xef\x83\xbb"; + inline constexpr char badgeSd[] = "\xef\x95\x9c"; + inline constexpr char badgeTm[] = "\xef\x95\x9d"; + inline constexpr char badgeVo[] = "\xef\x95\x9e"; + inline constexpr char badgeVr[] = "\xef\x95\x9f"; + inline constexpr char badgeWc[] = "\xef\x95\xa0"; + inline constexpr char badges[] = "\xee\xbf\x83"; + inline constexpr char badgesOff[] = "\xef\x83\xbc"; + inline constexpr char baguette[] = "\xef\x8e\xa5"; + inline constexpr char ballAmericanFootball[] = "\xee\xb8\x84"; + inline constexpr char ballAmericanFootballOff[] = "\xef\x8f\x83"; + inline constexpr char ballBaseball[] = "\xee\xbe\xa0"; + inline constexpr char ballBasketball[] = "\xee\xb0\xa8"; + inline constexpr char ballBowling[] = "\xee\xb0\xa9"; + inline constexpr char ballFootball[] = "\xee\xb8\x86"; + inline constexpr char ballFootballOff[] = "\xee\xb8\x85"; + inline constexpr char ballTennis[] = "\xee\xb0\xaa"; + inline constexpr char ballVolleyball[] = "\xee\xb0\xab"; + inline constexpr char balloon[] = "\xee\xbc\xba"; + inline constexpr char balloonOff[] = "\xef\x83\xbd"; + inline constexpr char ballpen[] = "\xef\x81\xae"; + inline constexpr char ballpenOff[] = "\xef\x82\xb1"; + inline constexpr char ban[] = "\xee\xa8\xae"; + inline constexpr char banana[] = "\xf0\x90\x89\x93"; + inline constexpr char bandage[] = "\xee\xad\xba"; + inline constexpr char bandageOff[] = "\xef\x8f\x84"; + inline constexpr char barbell[] = "\xee\xbf\xb0"; + inline constexpr char barbellOff[] = "\xef\x82\xb2"; + inline constexpr char barcode[] = "\xee\xaf\x86"; + inline constexpr char barcodeOff[] = "\xef\x82\xb3"; + inline constexpr char barrel[] = "\xef\x82\xb4"; + inline constexpr char barrelOff[] = "\xef\x83\xbe"; + inline constexpr char barrierBlock[] = "\xef\x80\x8e"; + inline constexpr char barrierBlockOff[] = "\xef\x82\xb5"; + inline constexpr char baseline[] = "\xef\x80\xa4"; + inline constexpr char baselineDensityLarge[] = "\xef\xa7\xb0"; + inline constexpr char baselineDensityMedium[] = "\xef\xa7\xb1"; + inline constexpr char baselineDensitySmall[] = "\xef\xa7\xb2"; + inline constexpr char basket[] = "\xee\xaf\xa1"; + inline constexpr char basketBolt[] = "\xef\xad\x83"; + inline constexpr char basketCancel[] = "\xef\xad\x84"; + inline constexpr char basketCheck[] = "\xef\xad\x85"; + inline constexpr char basketCode[] = "\xef\xad\x86"; + inline constexpr char basketCog[] = "\xef\xad\x87"; + inline constexpr char basketDiscount[] = "\xef\xad\x88"; + inline constexpr char basketDollar[] = "\xef\xad\x89"; + inline constexpr char basketDown[] = "\xef\xad\x8a"; + inline constexpr char basketExclamation[] = "\xef\xad\x8b"; + inline constexpr char basketHeart[] = "\xef\xad\x8c"; + inline constexpr char basketMinus[] = "\xef\xad\x8d"; + inline constexpr char basketOff[] = "\xef\x82\xb6"; + inline constexpr char basketPause[] = "\xef\xad\x8e"; + inline constexpr char basketPin[] = "\xef\xad\x8f"; + inline constexpr char basketPlus[] = "\xef\xad\x90"; + inline constexpr char basketQuestion[] = "\xef\xad\x91"; + inline constexpr char basketSearch[] = "\xef\xad\x92"; + inline constexpr char basketShare[] = "\xef\xad\x93"; + inline constexpr char basketStar[] = "\xef\xad\x94"; + inline constexpr char basketUp[] = "\xef\xad\x95"; + inline constexpr char basketX[] = "\xef\xad\x96"; + inline constexpr char bat[] = "\xef\x8a\x84"; + inline constexpr char bath[] = "\xee\xbd\x88"; + inline constexpr char bathOff[] = "\xef\x83\xbf"; + inline constexpr char battery[] = "\xee\xa8\xb4"; + inline constexpr char battery1[] = "\xee\xa8\xaf"; + inline constexpr char battery2[] = "\xee\xa8\xb0"; + inline constexpr char battery3[] = "\xee\xa8\xb1"; + inline constexpr char battery4[] = "\xee\xa8\xb2"; + inline constexpr char batteryAutomotive[] = "\xee\xb8\x87"; + inline constexpr char batteryCharging[] = "\xee\xa8\xb3"; + inline constexpr char batteryCharging2[] = "\xee\xbc\xbb"; + inline constexpr char batteryEco[] = "\xee\xbc\xbc"; + inline constexpr char batteryExclamation[] = "\xef\xbc\x9d"; + inline constexpr char batteryOff[] = "\xee\xb4\x9c"; + inline constexpr char batterySpark[] = "\xef\xbe\xbd"; + inline constexpr char batteryVertical[] = "\xef\xbc\x93"; + inline constexpr char batteryVertical1[] = "\xef\xbc\x9c"; + inline constexpr char batteryVertical2[] = "\xef\xbc\x9b"; + inline constexpr char batteryVertical3[] = "\xef\xbc\x9a"; + inline constexpr char batteryVertical4[] = "\xef\xbc\x99"; + inline constexpr char batteryVerticalCharging[] = "\xef\xbc\x97"; + inline constexpr char batteryVerticalCharging2[] = "\xef\xbc\x98"; + inline constexpr char batteryVerticalEco[] = "\xef\xbc\x96"; + inline constexpr char batteryVerticalExclamation[] = "\xef\xbc\x95"; + inline constexpr char batteryVerticalOff[] = "\xef\xbc\x94"; + inline constexpr char beach[] = "\xee\xbc\xbd"; + inline constexpr char beachOff[] = "\xef\x82\xb7"; + inline constexpr char bed[] = "\xee\xad\x9c"; + inline constexpr char bedFlat[] = "\xef\xb2\xa1"; + inline constexpr char bedOff[] = "\xef\x84\x80"; + inline constexpr char beer[] = "\xee\xbe\xa1"; + inline constexpr char beerOff[] = "\xef\x84\x81"; + inline constexpr char bell[] = "\xee\xa8\xb5"; + inline constexpr char bellBolt[] = "\xef\xa0\x92"; + inline constexpr char bellCancel[] = "\xef\xa0\x93"; + inline constexpr char bellCheck[] = "\xef\xa0\x94"; + inline constexpr char bellCode[] = "\xef\xa0\x95"; + inline constexpr char bellCog[] = "\xef\xa0\x96"; + inline constexpr char bellDollar[] = "\xef\xa0\x97"; + inline constexpr char bellDown[] = "\xef\xa0\x98"; + inline constexpr char bellExclamation[] = "\xef\xa0\x99"; + inline constexpr char bellHeart[] = "\xef\xa0\x9a"; + inline constexpr char bellMinus[] = "\xee\xb7\xa2"; + inline constexpr char bellOff[] = "\xee\xb3\xa9"; + inline constexpr char bellPause[] = "\xef\xa0\x9b"; + inline constexpr char bellPin[] = "\xef\xa0\x9c"; + inline constexpr char bellPlus[] = "\xee\xb7\xa3"; + inline constexpr char bellQuestion[] = "\xef\xa0\x9d"; + inline constexpr char bellRinging[] = "\xee\xb4\x87"; + inline constexpr char bellRinging2[] = "\xee\xb7\xa4"; + inline constexpr char bellSchool[] = "\xef\x81\x9e"; + inline constexpr char bellSearch[] = "\xef\xa0\x9e"; + inline constexpr char bellShare[] = "\xef\xa0\x9f"; + inline constexpr char bellStar[] = "\xef\xa0\xa0"; + inline constexpr char bellUp[] = "\xef\xa0\xa1"; + inline constexpr char bellX[] = "\xee\xb7\xa5"; + inline constexpr char bellZ[] = "\xee\xbf\xb1"; + inline constexpr char beta[] = "\xef\x95\x84"; + inline constexpr char bible[] = "\xee\xbf\x84"; + inline constexpr char bike[] = "\xee\xa8\xb6"; + inline constexpr char bikeOff[] = "\xef\x82\xb8"; + inline constexpr char binary[] = "\xee\xb8\x88"; + inline constexpr char binaryOff[] = "\xef\x8f\x85"; + inline constexpr char binaryTree[] = "\xef\x97\x94"; + inline constexpr char binaryTree2[] = "\xef\x97\x93"; + inline constexpr char binoculars[] = "\xef\xbb\xbe"; + inline constexpr char biohazard[] = "\xee\xb2\xb8"; + inline constexpr char biohazardOff[] = "\xef\x82\xb9"; + inline constexpr char blade[] = "\xef\x92\xbd"; + inline constexpr char bleach[] = "\xef\x8b\xb3"; + inline constexpr char bleachChlorine[] = "\xef\x8b\xb0"; + inline constexpr char bleachNoChlorine[] = "\xef\x8b\xb1"; + inline constexpr char bleachOff[] = "\xef\x8b\xb2"; + inline constexpr char blendMode[] = "\xef\xba\xb0"; + inline constexpr char blender[] = "\xef\xb2\xa2"; + inline constexpr char blind[] = "\xf0\x90\x86\xaf"; + inline constexpr char blob[] = "\xef\xba\xaf"; + inline constexpr char blockquote[] = "\xee\xb8\x89"; + inline constexpr char blocks[] = "\xf0\x90\x82\xb2"; + inline constexpr char bluetooth[] = "\xee\xa8\xb7"; + inline constexpr char bluetoothConnected[] = "\xee\xb3\xaa"; + inline constexpr char bluetoothOff[] = "\xee\xb3\xab"; + inline constexpr char bluetoothX[] = "\xef\x82\x81"; + inline constexpr char blur[] = "\xee\xbe\x8c"; + inline constexpr char blurOff[] = "\xef\x8f\x86"; + inline constexpr char bmp[] = "\xef\x8e\xa6"; + inline constexpr char bodyScan[] = "\xef\xb2\xa3"; + inline constexpr char bold[] = "\xee\xad\xbb"; + inline constexpr char boldOff[] = "\xef\x82\xba"; + inline constexpr char bolt[] = "\xee\xa8\xb8"; + inline constexpr char boltOff[] = "\xee\xb3\xac"; + inline constexpr char bomb[] = "\xef\x96\x9c"; + inline constexpr char bone[] = "\xee\xb6\xb8"; + inline constexpr char boneOff[] = "\xef\x82\xbb"; + inline constexpr char bong[] = "\xef\x8e\xa7"; + inline constexpr char bongOff[] = "\xef\x8f\x87"; + inline constexpr char book[] = "\xee\xa8\xb9"; + inline constexpr char book2[] = "\xee\xbf\x85"; + inline constexpr char bookDownload[] = "\xef\x81\xb0"; + inline constexpr char bookOff[] = "\xef\x82\xbc"; + inline constexpr char bookUpload[] = "\xef\x81\xb1"; + inline constexpr char bookmark[] = "\xee\xa8\xba"; + inline constexpr char bookmarkAi[] = "\xef\xb2\x8a"; + inline constexpr char bookmarkEdit[] = "\xef\xa9\x9e"; + inline constexpr char bookmarkMinus[] = "\xef\xa9\x9f"; + inline constexpr char bookmarkOff[] = "\xee\xb3\xad"; + inline constexpr char bookmarkPlus[] = "\xef\xa9\xa0"; + inline constexpr char bookmarkQuestion[] = "\xef\xa9\xa1"; + inline constexpr char bookmarks[] = "\xee\xb4\x88"; + inline constexpr char bookmarksOff[] = "\xef\x82\xbd"; + inline constexpr char books[] = "\xee\xbf\xb2"; + inline constexpr char booksOff[] = "\xef\x82\xbe"; + inline constexpr char boom[] = "\xef\xb6\xbe"; + inline constexpr char borderAll[] = "\xee\xa8\xbb"; + inline constexpr char borderBottom[] = "\xee\xa8\xbc"; + inline constexpr char borderBottomPlus[] = "\xef\xb6\xbd"; + inline constexpr char borderCornerIos[] = "\xef\xb6\x98"; + inline constexpr char borderCornerPill[] = "\xef\xb5\xa2"; + inline constexpr char borderCornerRounded[] = "\xef\xb5\xa3"; + inline constexpr char borderCornerSquare[] = "\xef\xb5\xa4"; + inline constexpr char borderCorners[] = "\xef\x9e\xa0"; + inline constexpr char borderHorizontal[] = "\xee\xa8\xbd"; + inline constexpr char borderInner[] = "\xee\xa8\xbe"; + inline constexpr char borderLeft[] = "\xee\xa8\xbf"; + inline constexpr char borderLeftPlus[] = "\xef\xb6\xbc"; + inline constexpr char borderNone[] = "\xee\xa9\x80"; + inline constexpr char borderOuter[] = "\xee\xa9\x81"; + inline constexpr char borderRadius[] = "\xee\xad\xbc"; + inline constexpr char borderRight[] = "\xee\xa9\x82"; + inline constexpr char borderRightPlus[] = "\xef\xb6\xbb"; + inline constexpr char borderSides[] = "\xef\x9e\xa1"; + inline constexpr char borderStyle[] = "\xee\xb8\x8a"; + inline constexpr char borderStyle2[] = "\xee\xbc\xa2"; + inline constexpr char borderTop[] = "\xee\xa9\x83"; + inline constexpr char borderTopPlus[] = "\xef\xb6\xba"; + inline constexpr char borderVertical[] = "\xee\xa9\x84"; + inline constexpr char botId[] = "\xf0\x90\x87\xb6"; + inline constexpr char bottle[] = "\xee\xbc\x8b"; + inline constexpr char bottleOff[] = "\xef\x8f\x88"; + inline constexpr char bounceLeft[] = "\xef\x96\x9d"; + inline constexpr char bounceRight[] = "\xef\x96\x9e"; + inline constexpr char bow[] = "\xef\x82\x96"; + inline constexpr char bowl[] = "\xef\x93\xba"; + inline constexpr char bowlChopsticks[] = "\xef\xb6\x90"; + inline constexpr char bowlSpoon[] = "\xef\xb6\x91"; + inline constexpr char bowling[] = "\xf0\x90\x82\xb1"; + inline constexpr char box[] = "\xee\xa9\x85"; + inline constexpr char boxAlignBottom[] = "\xef\x8a\xa8"; + inline constexpr char boxAlignBottomLeft[] = "\xef\x8b\x8e"; + inline constexpr char boxAlignBottomRight[] = "\xef\x8b\x8f"; + inline constexpr char boxAlignLeft[] = "\xef\x8a\xa9"; + inline constexpr char boxAlignRight[] = "\xef\x8a\xaa"; + inline constexpr char boxAlignTop[] = "\xef\x8a\xab"; + inline constexpr char boxAlignTopLeft[] = "\xef\x8b\x90"; + inline constexpr char boxAlignTopRight[] = "\xef\x8b\x91"; + inline constexpr char boxMargin[] = "\xee\xb8\x8b"; + inline constexpr char boxModel[] = "\xee\xb8\x8c"; + inline constexpr char boxModel2[] = "\xee\xbc\xa3"; + inline constexpr char boxModel2Off[] = "\xef\x8f\x89"; + inline constexpr char boxModelOff[] = "\xef\x8f\x8a"; + inline constexpr char boxMultiple[] = "\xee\xb8\x97"; + inline constexpr char boxMultiple0[] = "\xee\xb8\x8d"; + inline constexpr char boxMultiple1[] = "\xee\xb8\x8e"; + inline constexpr char boxMultiple2[] = "\xee\xb8\x8f"; + inline constexpr char boxMultiple3[] = "\xee\xb8\x90"; + inline constexpr char boxMultiple4[] = "\xee\xb8\x91"; + inline constexpr char boxMultiple5[] = "\xee\xb8\x92"; + inline constexpr char boxMultiple6[] = "\xee\xb8\x93"; + inline constexpr char boxMultiple7[] = "\xee\xb8\x94"; + inline constexpr char boxMultiple8[] = "\xee\xb8\x95"; + inline constexpr char boxMultiple9[] = "\xee\xb8\x96"; + inline constexpr char boxOff[] = "\xef\x84\x82"; + inline constexpr char boxPadding[] = "\xee\xb8\x98"; + inline constexpr char braces[] = "\xee\xaf\x8c"; + inline constexpr char bracesOff[] = "\xef\x82\xbf"; + inline constexpr char brackets[] = "\xee\xaf\x8d"; + inline constexpr char bracketsAngle[] = "\xef\xb2\xb2"; + inline constexpr char bracketsAngleOff[] = "\xef\xb2\xb1"; + inline constexpr char bracketsContain[] = "\xef\x87\xa5"; + inline constexpr char bracketsContainEnd[] = "\xef\x87\xa3"; + inline constexpr char bracketsContainStart[] = "\xef\x87\xa4"; + inline constexpr char bracketsOff[] = "\xef\x83\x80"; + inline constexpr char braille[] = "\xef\x95\x85"; + inline constexpr char brain[] = "\xef\x96\x9f"; + inline constexpr char brand4chan[] = "\xef\x92\x94"; + inline constexpr char brandAbstract[] = "\xef\x92\x95"; + inline constexpr char brandAdobe[] = "\xef\x83\x9c"; + inline constexpr char brandAdobeAfterEffects[] = "\xef\xbc\xaa"; + inline constexpr char brandAdobeIllustrator[] = "\xef\xbc\xa9"; + inline constexpr char brandAdobeIndesign[] = "\xef\xbc\xa8"; + inline constexpr char brandAdobePhotoshop[] = "\xef\xbc\xa7"; + inline constexpr char brandAdobePremiere[] = "\xef\xbc\xa6"; + inline constexpr char brandAdobeXd[] = "\xef\xbc\xa5"; + inline constexpr char brandAdonisJs[] = "\xef\x92\x96"; + inline constexpr char brandAirbnb[] = "\xee\xb5\xa8"; + inline constexpr char brandAirtable[] = "\xee\xbd\xaa"; + inline constexpr char brandAlgolia[] = "\xef\x8e\x90"; + inline constexpr char brandAlipay[] = "\xef\x9e\xa2"; + inline constexpr char brandAlpineJs[] = "\xef\x8c\xa4"; + inline constexpr char brandAmazon[] = "\xef\x88\xb0"; + inline constexpr char brandAmd[] = "\xef\x99\x93"; + inline constexpr char brandAmie[] = "\xef\xbe\xab"; + inline constexpr char brandAmigo[] = "\xef\x97\xb9"; + inline constexpr char brandAmongUs[] = "\xef\x88\x85"; + inline constexpr char brandAndroid[] = "\xee\xb0\x96"; + inline constexpr char brandAngular[] = "\xee\xbd\xab"; + inline constexpr char brandAnsible[] = "\xef\xa9\xb0"; + inline constexpr char brandAo3[] = "\xef\x97\xa8"; + inline constexpr char brandAppgallery[] = "\xef\x88\xb1"; + inline constexpr char brandApple[] = "\xee\xb0\x97"; + inline constexpr char brandAppleArcade[] = "\xee\xb5\xa9"; + inline constexpr char brandAppleNews[] = "\xef\xbc\xa4"; + inline constexpr char brandApplePodcast[] = "\xef\x87\xa6"; + inline constexpr char brandAppstore[] = "\xee\xb4\xa4"; + inline constexpr char brandArc[] = "\xef\xba\xae"; + inline constexpr char brandAsana[] = "\xee\xb7\x85"; + inline constexpr char brandAstro[] = "\xef\xb6\xb9"; + inline constexpr char brandAudible[] = "\xf0\x90\x89\x92"; + inline constexpr char brandAuth0[] = "\xef\xb2\xb3"; + inline constexpr char brandAws[] = "\xef\xa9\x8c"; + inline constexpr char brandAzure[] = "\xef\xa9\x8d"; + inline constexpr char brandBackbone[] = "\xef\x8c\xa5"; + inline constexpr char brandBadoo[] = "\xef\x88\x86"; + inline constexpr char brandBaidu[] = "\xef\x97\xa9"; + inline constexpr char brandBandcamp[] = "\xef\x88\x87"; + inline constexpr char brandBandlab[] = "\xef\x97\xba"; + inline constexpr char brandBeats[] = "\xef\x88\x88"; + inline constexpr char brandBebo[] = "\xef\xbe\xaa"; + inline constexpr char brandBehance[] = "\xee\xb1\xae"; + inline constexpr char brandBilibili[] = "\xef\x9b\x92"; + inline constexpr char brandBinance[] = "\xef\x96\xa0"; + inline constexpr char brandBing[] = "\xee\xb7\x86"; + inline constexpr char brandBitbucket[] = "\xee\xb7\x87"; + inline constexpr char brandBlackberry[] = "\xef\x95\xa8"; + inline constexpr char brandBlender[] = "\xef\x8c\xa6"; + inline constexpr char brandBlogger[] = "\xef\x8d\x9a"; + inline constexpr char brandBluesky[] = "\xef\xb5\xb5"; + inline constexpr char brandBooking[] = "\xee\xb7\x88"; + inline constexpr char brandBootstrap[] = "\xee\xbc\xbe"; + inline constexpr char brandBulma[] = "\xef\x8c\xa7"; + inline constexpr char brandBumble[] = "\xef\x97\xbb"; + inline constexpr char brandBunpo[] = "\xef\x93\x8f"; + inline constexpr char brandCSharp[] = "\xef\x80\x83"; + inline constexpr char brandCake[] = "\xef\x9e\xa3"; + inline constexpr char brandCakephp[] = "\xef\x9e\xaf"; + inline constexpr char brandCampaignmonitor[] = "\xef\x8c\xa8"; + inline constexpr char brandCarbon[] = "\xef\x8d\x88"; + inline constexpr char brandCashapp[] = "\xef\x8e\x91"; + inline constexpr char brandChrome[] = "\xee\xb0\x98"; + inline constexpr char brandCinema4d[] = "\xef\xa9\xb1"; + inline constexpr char brandCitymapper[] = "\xef\x97\xbc"; + inline constexpr char brandCloudflare[] = "\xef\xa9\x8e"; + inline constexpr char brandCodecov[] = "\xef\x8c\xa9"; + inline constexpr char brandCodepen[] = "\xee\xb1\xaf"; + inline constexpr char brandCodesandbox[] = "\xee\xb5\xaa"; + inline constexpr char brandCohost[] = "\xef\x97\x95"; + inline constexpr char brandCoinbase[] = "\xef\x88\x89"; + inline constexpr char brandComedyCentral[] = "\xef\x88\x97"; + inline constexpr char brandCoreos[] = "\xef\x97\xbd"; + inline constexpr char brandCouchdb[] = "\xef\x98\x8f"; + inline constexpr char brandCouchsurfing[] = "\xef\x8e\x92"; + inline constexpr char brandCpp[] = "\xef\x97\xbe"; + inline constexpr char brandCraft[] = "\xef\xa9\xb2"; + inline constexpr char brandCrunchbase[] = "\xef\x9f\xa3"; + inline constexpr char brandCss3[] = "\xee\xb5\xab"; + inline constexpr char brandCtemplar[] = "\xef\x93\x90"; + inline constexpr char brandCucumber[] = "\xee\xbd\xac"; + inline constexpr char brandCupra[] = "\xef\x93\x91"; + inline constexpr char brandCypress[] = "\xef\x8c\xb3"; + inline constexpr char brandD3[] = "\xef\x89\x8e"; + inline constexpr char brandDatabricks[] = "\xef\xb1\x81"; + inline constexpr char brandDaysCounter[] = "\xef\x93\x92"; + inline constexpr char brandDcos[] = "\xef\x8c\xaa"; + inline constexpr char brandDebian[] = "\xee\xbd\x97"; + inline constexpr char brandDeezer[] = "\xef\x9e\x8b"; + inline constexpr char brandDeliveroo[] = "\xef\x93\x93"; + inline constexpr char brandDeno[] = "\xef\x89\x8f"; + inline constexpr char brandDenodo[] = "\xef\x98\x90"; + inline constexpr char brandDeviantart[] = "\xee\xb3\xbb"; + inline constexpr char brandDigg[] = "\xef\xa9\xb3"; + inline constexpr char brandDingtalk[] = "\xef\x97\xaa"; + inline constexpr char brandDiscord[] = "\xee\xb3\xa3"; + inline constexpr char brandDisney[] = "\xef\x88\x8a"; + inline constexpr char brandDisqus[] = "\xee\xb7\x89"; + inline constexpr char brandDjango[] = "\xef\x8d\x89"; + inline constexpr char brandDocker[] = "\xee\xb7\x8a"; + inline constexpr char brandDoctrine[] = "\xee\xbd\xad"; + inline constexpr char brandDolbyDigital[] = "\xef\x93\x94"; + inline constexpr char brandDouban[] = "\xef\x97\xbf"; + inline constexpr char brandDribbble[] = "\xee\xb0\x99"; + inline constexpr char brandDropbox[] = "\xf0\x90\x86\x8a"; + inline constexpr char brandDrops[] = "\xef\x93\x95"; + inline constexpr char brandDrupal[] = "\xef\x8e\x93"; + inline constexpr char brandEdge[] = "\xee\xb3\xbc"; + inline constexpr char brandElastic[] = "\xef\x98\x91"; + inline constexpr char brandElectronicArts[] = "\xef\xa9\xb4"; + inline constexpr char brandEmber[] = "\xef\x92\x97"; + inline constexpr char brandEnvato[] = "\xef\x8e\x94"; + inline constexpr char brandEtsy[] = "\xef\x99\x94"; + inline constexpr char brandEvernote[] = "\xef\x98\x80"; + inline constexpr char brandFacebook[] = "\xee\xb0\x9a"; + inline constexpr char brandFeedly[] = "\xef\xa9\xb5"; + inline constexpr char brandFigma[] = "\xee\xb2\x93"; + inline constexpr char brandFilezilla[] = "\xef\xa9\xb6"; + inline constexpr char brandFinder[] = "\xef\x88\x98"; + inline constexpr char brandFirebase[] = "\xee\xbd\xae"; + inline constexpr char brandFirefox[] = "\xee\xb3\xbd"; + inline constexpr char brandFiverr[] = "\xef\x9e\xa4"; + inline constexpr char brandFlickr[] = "\xee\xb3\xbe"; + inline constexpr char brandFlightradar24[] = "\xef\x93\x96"; + inline constexpr char brandFlipboard[] = "\xef\x88\x8b"; + inline constexpr char brandFlutter[] = "\xef\x8e\x95"; + inline constexpr char brandFortnite[] = "\xef\x89\xa0"; + inline constexpr char brandFoursquare[] = "\xee\xb3\xbf"; + inline constexpr char brandFramer[] = "\xee\xb0\x9b"; + inline constexpr char brandFramerMotion[] = "\xef\x9e\x8c"; + inline constexpr char brandFunimation[] = "\xef\x99\x95"; + inline constexpr char brandGatsby[] = "\xef\x8e\x96"; + inline constexpr char brandGit[] = "\xee\xbd\xaf"; + inline constexpr char brandGithub[] = "\xee\xb0\x9c"; + inline constexpr char brandGithubCopilot[] = "\xef\x92\xa8"; + inline constexpr char brandGitlab[] = "\xee\xb0\x9d"; + inline constexpr char brandGmail[] = "\xee\xbe\xa2"; + inline constexpr char brandGolang[] = "\xef\x9e\x8d"; + inline constexpr char brandGoogle[] = "\xee\xb0\x9f"; + inline constexpr char brandGoogleAnalytics[] = "\xee\xb7\x8b"; + inline constexpr char brandGoogleBigQuery[] = "\xef\x98\x92"; + inline constexpr char brandGoogleDrive[] = "\xee\xb0\x9e"; + inline constexpr char brandGoogleFit[] = "\xef\x8a\x97"; + inline constexpr char brandGoogleHome[] = "\xef\x98\x81"; + inline constexpr char brandGoogleMaps[] = "\xef\xa9\x8f"; + inline constexpr char brandGoogleOne[] = "\xef\x88\xb2"; + inline constexpr char brandGooglePhotos[] = "\xef\x88\x8c"; + inline constexpr char brandGooglePlay[] = "\xee\xb4\xa5"; + inline constexpr char brandGooglePodcasts[] = "\xef\x99\x96"; + inline constexpr char brandGrammarly[] = "\xef\x8c\xab"; + inline constexpr char brandGraphql[] = "\xef\x8c\xac"; + inline constexpr char brandGravatar[] = "\xee\xb7\x8c"; + inline constexpr char brandGrindr[] = "\xef\x88\x8d"; + inline constexpr char brandGuardian[] = "\xef\x93\xbb"; + inline constexpr char brandGumroad[] = "\xef\x97\x96"; + inline constexpr char brandHackerrank[] = "\xef\xbc\xa3"; + inline constexpr char brandHbo[] = "\xef\x99\x97"; + inline constexpr char brandHeadlessui[] = "\xef\x8c\xad"; + inline constexpr char brandHexo[] = "\xef\xa9\x90"; + inline constexpr char brandHipchat[] = "\xee\xb7\x8d"; + inline constexpr char brandHtml5[] = "\xee\xb5\xac"; + inline constexpr char brandInertia[] = "\xef\x8d\x8a"; + inline constexpr char brandInfakt[] = "\xf0\x90\x88\x8a"; + inline constexpr char brandInstagram[] = "\xee\xb0\xa0"; + inline constexpr char brandIntercom[] = "\xef\x87\x8f"; + inline constexpr char brandItch[] = "\xef\xa8\xa2"; + inline constexpr char brandJavascript[] = "\xee\xbc\x8c"; + inline constexpr char brandJira[] = "\xf0\x90\x88\xb1"; + inline constexpr char brandJuejin[] = "\xef\x9e\xb0"; + inline constexpr char brandKakaoTalk[] = "\xef\xb4\xad"; + inline constexpr char brandKbin[] = "\xef\xab\x90"; + inline constexpr char brandKick[] = "\xef\xa8\xa3"; + inline constexpr char brandKickstarter[] = "\xee\xb7\x8e"; + inline constexpr char brandKotlin[] = "\xee\xb5\xad"; + inline constexpr char brandLaravel[] = "\xef\x8d\x8b"; + inline constexpr char brandLastfm[] = "\xef\x80\x81"; + inline constexpr char brandLeetcode[] = "\xef\xa9\x91"; + inline constexpr char brandLetterboxd[] = "\xef\xa8\xa4"; + inline constexpr char brandLine[] = "\xef\x9f\xa8"; + inline constexpr char brandLinkedin[] = "\xee\xb2\x8c"; + inline constexpr char brandLinktree[] = "\xef\x87\xa7"; + inline constexpr char brandLinqpad[] = "\xef\x95\xa2"; + inline constexpr char brandLivewire[] = "\xef\xb5\xb6"; + inline constexpr char brandLoom[] = "\xee\xbd\xb0"; + inline constexpr char brandMailgun[] = "\xef\x8c\xae"; + inline constexpr char brandMantine[] = "\xef\x8c\xaf"; + inline constexpr char brandMastercard[] = "\xee\xbd\x89"; + inline constexpr char brandMastodon[] = "\xef\x89\x90"; + inline constexpr char brandMatrix[] = "\xef\x97\xab"; + inline constexpr char brandMcdonalds[] = "\xef\x89\x91"; + inline constexpr char brandMedium[] = "\xee\xb1\xb0"; + inline constexpr char brandMeetup[] = "\xef\xb1\xaa"; + inline constexpr char brandMercedes[] = "\xef\x81\xb2"; + inline constexpr char brandMessenger[] = "\xee\xb1\xb1"; + inline constexpr char brandMeta[] = "\xee\xbe\xb0"; + inline constexpr char brandMetabrainz[] = "\xef\xbc\x92"; + inline constexpr char brandMinecraft[] = "\xef\xab\xaf"; + inline constexpr char brandMiniprogram[] = "\xef\x98\x82"; + inline constexpr char brandMixpanel[] = "\xef\x8e\x97"; + inline constexpr char brandMonday[] = "\xef\x88\x99"; + inline constexpr char brandMongodb[] = "\xef\x98\x93"; + inline constexpr char brandMyOppo[] = "\xef\x93\x97"; + inline constexpr char brandMysql[] = "\xef\x98\x94"; + inline constexpr char brandNationalGeographic[] = "\xef\x98\x83"; + inline constexpr char brandNem[] = "\xef\x96\xa1"; + inline constexpr char brandNetbeans[] = "\xee\xbd\xb1"; + inline constexpr char brandNeteaseMusic[] = "\xef\x98\x84"; + inline constexpr char brandNetflix[] = "\xee\xb7\x8f"; + inline constexpr char brandNexo[] = "\xef\x96\xa2"; + inline constexpr char brandNextcloud[] = "\xef\x93\x98"; + inline constexpr char brandNextjs[] = "\xef\x83\x9d"; + inline constexpr char brandNodejs[] = "\xef\xab\xa0"; + inline constexpr char brandNordVpn[] = "\xef\x8d\xbf"; + inline constexpr char brandNotion[] = "\xee\xbd\xbb"; + inline constexpr char brandNpm[] = "\xef\x95\xa9"; + inline constexpr char brandNuxt[] = "\xef\x83\x9e"; + inline constexpr char brandNytimes[] = "\xee\xbe\x8d"; + inline constexpr char brandOauth[] = "\xef\xa9\x92"; + inline constexpr char brandOffice[] = "\xef\x8e\x98"; + inline constexpr char brandOkRu[] = "\xef\x8e\x99"; + inline constexpr char brandOnedrive[] = "\xef\x97\x97"; + inline constexpr char brandOnlyfans[] = "\xef\x98\x85"; + inline constexpr char brandOpenSource[] = "\xee\xb7\x90"; + inline constexpr char brandOpenai[] = "\xef\x9e\x8e"; + inline constexpr char brandOpenvpn[] = "\xef\x8e\x9a"; + inline constexpr char brandOpera[] = "\xee\xb0\xa1"; + inline constexpr char brandPagekit[] = "\xee\xb7\x91"; + inline constexpr char brandParsinta[] = "\xef\xb1\x82"; + inline constexpr char brandPatreon[] = "\xee\xb7\x92"; + inline constexpr char brandPaypal[] = "\xee\xb0\xa2"; + inline constexpr char brandPaypay[] = "\xef\x97\xac"; + inline constexpr char brandPeanut[] = "\xef\x8e\x9b"; + inline constexpr char brandPepsi[] = "\xef\x89\xa1"; + inline constexpr char brandPhp[] = "\xee\xbd\xb2"; + inline constexpr char brandPicsart[] = "\xef\x93\x99"; + inline constexpr char brandPinterest[] = "\xee\xb2\x8d"; + inline constexpr char brandPlanetscale[] = "\xef\x9e\x8f"; + inline constexpr char brandPnpm[] = "\xef\xb5\xb7"; + inline constexpr char brandPocket[] = "\xee\xb4\x80"; + inline constexpr char brandPolymer[] = "\xef\x92\x98"; + inline constexpr char brandPowershell[] = "\xef\x97\xad"; + inline constexpr char brandPrintables[] = "\xef\xb4\x9b"; + inline constexpr char brandPrisma[] = "\xef\x92\x99"; + inline constexpr char brandProducthunt[] = "\xee\xb7\x93"; + inline constexpr char brandPushbullet[] = "\xef\x8c\xb0"; + inline constexpr char brandPushover[] = "\xef\x88\x8e"; + inline constexpr char brandPython[] = "\xee\xb4\x81"; + inline constexpr char brandQq[] = "\xef\x98\x86"; + inline constexpr char brandRadixUi[] = "\xef\x9e\x90"; + inline constexpr char brandReact[] = "\xef\x8d\x8c"; + inline constexpr char brandReactNative[] = "\xee\xbd\xb3"; + inline constexpr char brandReason[] = "\xef\x92\x9a"; + inline constexpr char brandReddit[] = "\xee\xb2\x8e"; + inline constexpr char brandRedhat[] = "\xef\x8c\xb1"; + inline constexpr char brandRedux[] = "\xef\x8e\xa8"; + inline constexpr char brandRevolut[] = "\xef\x93\x9a"; + inline constexpr char brandRumble[] = "\xef\xab\x91"; + inline constexpr char brandRust[] = "\xef\xa9\x93"; + inline constexpr char brandSafari[] = "\xee\xb0\xa3"; + inline constexpr char brandSamsungpass[] = "\xef\x93\x9b"; + inline constexpr char brandSass[] = "\xee\xb7\x94"; + inline constexpr char brandSentry[] = "\xee\xb7\x95"; + inline constexpr char brandSharik[] = "\xef\x93\x9c"; + inline constexpr char brandShazam[] = "\xee\xb7\x96"; + inline constexpr char brandShopee[] = "\xef\x89\x92"; + inline constexpr char brandSignal[] = "\xf0\x90\x89\xb5"; + inline constexpr char brandSketch[] = "\xee\xb0\xa4"; + inline constexpr char brandSkype[] = "\xee\xb4\x82"; + inline constexpr char brandSlack[] = "\xee\xb1\xb2"; + inline constexpr char brandSnapchat[] = "\xee\xb0\xa5"; + inline constexpr char brandSnapseed[] = "\xef\x89\x93"; + inline constexpr char brandSnowflake[] = "\xef\x98\x95"; + inline constexpr char brandSocketIo[] = "\xef\x92\x9b"; + inline constexpr char brandSolidjs[] = "\xef\x97\xae"; + inline constexpr char brandSoundcloud[] = "\xee\xb5\xae"; + inline constexpr char brandSpacehey[] = "\xef\x93\xbc"; + inline constexpr char brandSpeedtest[] = "\xef\xa9\xb7"; + inline constexpr char brandSpotify[] = "\xee\xb4\x83"; + inline constexpr char brandStackoverflow[] = "\xee\xbd\x98"; + inline constexpr char brandStackshare[] = "\xef\x98\x87"; + inline constexpr char brandSteam[] = "\xee\xb5\xaf"; + inline constexpr char brandStellar[] = "\xf0\x90\x89\x83"; + inline constexpr char brandStocktwits[] = "\xef\xb5\xb8"; + inline constexpr char brandStorj[] = "\xef\xa9\x94"; + inline constexpr char brandStorybook[] = "\xef\x8c\xb2"; + inline constexpr char brandStorytel[] = "\xef\x98\x88"; + inline constexpr char brandStrava[] = "\xef\x89\x94"; + inline constexpr char brandStripe[] = "\xee\xb7\x97"; + inline constexpr char brandSublimeText[] = "\xee\xbd\xb4"; + inline constexpr char brandSugarizer[] = "\xef\x9e\xa5"; + inline constexpr char brandSupabase[] = "\xef\x9b\x93"; + inline constexpr char brandSuperhuman[] = "\xef\x94\x8c"; + inline constexpr char brandSupernova[] = "\xef\x92\x9c"; + inline constexpr char brandSurfshark[] = "\xef\x89\x95"; + inline constexpr char brandSvelte[] = "\xef\x83\x9f"; + inline constexpr char brandSwift[] = "\xef\xa9\x95"; + inline constexpr char brandSymfony[] = "\xef\x98\x96"; + inline constexpr char brandTabler[] = "\xee\xb2\x8f"; + inline constexpr char brandTabnine[] = "\xf0\x90\x86\xae"; + inline constexpr char brandTailwind[] = "\xee\xb2\xa1"; + inline constexpr char brandTaobao[] = "\xef\x97\xaf"; + inline constexpr char brandTeams[] = "\xef\xab\x9f"; + inline constexpr char brandTed[] = "\xef\x99\x98"; + inline constexpr char brandTelegram[] = "\xee\xb0\xa6"; + inline constexpr char brandTerraform[] = "\xef\xa9\x96"; + inline constexpr char brandTesla[] = "\xf0\x90\x82\x99"; + inline constexpr char brandTether[] = "\xef\x96\xa3"; + inline constexpr char brandThingiverse[] = "\xef\xb4\x9c"; + inline constexpr char brandThreads[] = "\xef\xac\x82"; + inline constexpr char brandThreejs[] = "\xef\x97\xb0"; + inline constexpr char brandTidal[] = "\xee\xb5\xb0"; + inline constexpr char brandTiktok[] = "\xee\xb1\xb3"; + inline constexpr char brandTinder[] = "\xee\xb5\xb1"; + inline constexpr char brandTopbuzz[] = "\xef\x94\x8d"; + inline constexpr char brandTorchain[] = "\xef\x96\xa4"; + inline constexpr char brandToyota[] = "\xef\x89\xa2"; + inline constexpr char brandTrello[] = "\xef\x8e\x9d"; + inline constexpr char brandTripadvisor[] = "\xef\x80\x82"; + inline constexpr char brandTumblr[] = "\xee\xb4\x84"; + inline constexpr char brandTwilio[] = "\xef\x98\x97"; + inline constexpr char brandTwitch[] = "\xee\xb4\x85"; + inline constexpr char brandTwitter[] = "\xee\xb0\xa7"; + inline constexpr char brandTypescript[] = "\xef\x97\xb1"; + inline constexpr char brandUber[] = "\xee\xbd\xb5"; + inline constexpr char brandUbuntu[] = "\xee\xbd\x99"; + inline constexpr char brandUnity[] = "\xef\x92\x9d"; + inline constexpr char brandUnsplash[] = "\xee\xb7\x98"; + inline constexpr char brandUpwork[] = "\xef\x8e\x9e"; + inline constexpr char brandValorant[] = "\xef\x8e\x9f"; + inline constexpr char brandVechain[] = "\xf0\x90\x89\x82"; + inline constexpr char brandVercel[] = "\xee\xbc\xa4"; + inline constexpr char brandVimeo[] = "\xee\xb4\x86"; + inline constexpr char brandVinted[] = "\xef\x88\x8f"; + inline constexpr char brandVisa[] = "\xef\x8e\x80"; + inline constexpr char brandVisualStudio[] = "\xee\xbd\xb6"; + inline constexpr char brandVite[] = "\xef\x97\xb2"; + inline constexpr char brandVivaldi[] = "\xef\x88\x90"; + inline constexpr char brandVk[] = "\xee\xb5\xb2"; + inline constexpr char brandVlc[] = "\xef\xa9\xb8"; + inline constexpr char brandVolkswagen[] = "\xef\x94\x8e"; + inline constexpr char brandVsco[] = "\xef\x8c\xb4"; + inline constexpr char brandVscode[] = "\xef\x8e\xa0"; + inline constexpr char brandVue[] = "\xef\x83\xa0"; + inline constexpr char brandWalmart[] = "\xef\x88\x91"; + inline constexpr char brandWaze[] = "\xef\x97\x98"; + inline constexpr char brandWebflow[] = "\xef\x8b\x92"; + inline constexpr char brandWechat[] = "\xef\x97\xb3"; + inline constexpr char brandWeibo[] = "\xef\x98\x89"; + inline constexpr char brandWhatsapp[] = "\xee\xb1\xb4"; + inline constexpr char brandWikipedia[] = "\xef\xa9\xb9"; + inline constexpr char brandWindows[] = "\xee\xb3\x98"; + inline constexpr char brandWindy[] = "\xef\x93\x9d"; + inline constexpr char brandWish[] = "\xef\x88\x92"; + inline constexpr char brandWix[] = "\xef\x8e\xa1"; + inline constexpr char brandWordpress[] = "\xef\x8b\x93"; + inline constexpr char brandX[] = "\xef\xb0\x8f"; + inline constexpr char brandXamarin[] = "\xef\xa9\xba"; + inline constexpr char brandXbox[] = "\xef\x8a\x98"; + inline constexpr char brandXdeep[] = "\xef\xb0\x90"; + inline constexpr char brandXing[] = "\xef\x88\x9a"; + inline constexpr char brandYahoo[] = "\xee\xb5\xb3"; + inline constexpr char brandYandex[] = "\xef\xab\xa1"; + inline constexpr char brandYarn[] = "\xef\xb5\xb9"; + inline constexpr char brandYatse[] = "\xef\x88\x93"; + inline constexpr char brandYcombinator[] = "\xee\xb7\x99"; + inline constexpr char brandYoutube[] = "\xee\xb2\x90"; + inline constexpr char brandYoutubeKids[] = "\xef\x88\x94"; + inline constexpr char brandZalando[] = "\xef\x92\x9e"; + inline constexpr char brandZapier[] = "\xef\x92\x9f"; + inline constexpr char brandZeit[] = "\xef\x8c\xb5"; + inline constexpr char brandZhihu[] = "\xef\x98\x8a"; + inline constexpr char brandZoom[] = "\xef\x88\x95"; + inline constexpr char brandZulip[] = "\xef\x93\x9e"; + inline constexpr char brandZwift[] = "\xef\x88\x96"; + inline constexpr char bread[] = "\xee\xbe\xa3"; + inline constexpr char breadOff[] = "\xef\x8f\x8b"; + inline constexpr char briefcase[] = "\xee\xa9\x86"; + inline constexpr char briefcase2[] = "\xef\xac\x83"; + inline constexpr char briefcaseOff[] = "\xef\x8f\x8c"; + inline constexpr char brightness[] = "\xee\xad\xbf"; + inline constexpr char brightness2[] = "\xee\xb8\x99"; + inline constexpr char brightnessAuto[] = "\xef\xb6\x99"; + inline constexpr char brightnessDown[] = "\xee\xad\xbd"; + inline constexpr char brightnessHalf[] = "\xee\xb8\x9a"; + inline constexpr char brightnessOff[] = "\xef\x8f\x8d"; + inline constexpr char brightnessUp[] = "\xee\xad\xbe"; + inline constexpr char broadcast[] = "\xef\x87\xa9"; + inline constexpr char broadcastOff[] = "\xef\x87\xa8"; + inline constexpr char browser[] = "\xee\xae\xb7"; + inline constexpr char browserCheck[] = "\xee\xbf\x96"; + inline constexpr char browserMaximize[] = "\xf0\x90\x82\xb0"; + inline constexpr char browserMinus[] = "\xf0\x90\x82\xaf"; + inline constexpr char browserOff[] = "\xef\x83\x81"; + inline constexpr char browserPlus[] = "\xee\xbf\x97"; + inline constexpr char browserShare[] = "\xf0\x90\x82\xae"; + inline constexpr char browserX[] = "\xee\xbf\x98"; + inline constexpr char brush[] = "\xee\xae\xb8"; + inline constexpr char brushOff[] = "\xef\x83\x82"; + inline constexpr char bubble[] = "\xef\xba\xba"; + inline constexpr char bubbleMinus[] = "\xef\xba\xbe"; + inline constexpr char bubblePlus[] = "\xef\xba\xbd"; + inline constexpr char bubbleTea[] = "\xef\xbd\x91"; + inline constexpr char bubbleTea2[] = "\xef\xbd\x92"; + inline constexpr char bubbleText[] = "\xef\xba\xbc"; + inline constexpr char bubbleX[] = "\xef\xba\xbb"; + inline constexpr char bucket[] = "\xee\xa9\x87"; + inline constexpr char bucketDroplet[] = "\xef\x95\xaa"; + inline constexpr char bucketOff[] = "\xef\x84\x83"; + inline constexpr char bug[] = "\xee\xa9\x88"; + inline constexpr char bugOff[] = "\xef\x83\x83"; + inline constexpr char building[] = "\xee\xa9\x8f"; + inline constexpr char buildingAirport[] = "\xef\xbe\xa9"; + inline constexpr char buildingArch[] = "\xee\xa9\x89"; + inline constexpr char buildingBank[] = "\xee\xaf\xa2"; + inline constexpr char buildingBridge[] = "\xee\xa9\x8b"; + inline constexpr char buildingBridge2[] = "\xee\xa9\x8a"; + inline constexpr char buildingBroadcastTower[] = "\xef\x92\xbe"; + inline constexpr char buildingBurjAlArab[] = "\xef\xbd\x90"; + inline constexpr char buildingCarousel[] = "\xee\xb6\x87"; + inline constexpr char buildingCastle[] = "\xee\xb6\x88"; + inline constexpr char buildingChurch[] = "\xee\xa9\x8c"; + inline constexpr char buildingCircus[] = "\xef\x92\xbf"; + inline constexpr char buildingCog[] = "\xf0\x90\x81\xa2"; + inline constexpr char buildingCommunity[] = "\xee\xaf\xb6"; + inline constexpr char buildingCottage[] = "\xee\xb8\x9b"; + inline constexpr char buildingEiffelTower[] = "\xf0\x90\x89\x91"; + inline constexpr char buildingEstate[] = "\xef\x96\xa5"; + inline constexpr char buildingFactory[] = "\xee\xb8\x9c"; + inline constexpr char buildingFactory2[] = "\xef\x82\x82"; + inline constexpr char buildingFortress[] = "\xee\xb6\x89"; + inline constexpr char buildingHospital[] = "\xee\xa9\x8d"; + inline constexpr char buildingLighthouse[] = "\xee\xb6\x8a"; + inline constexpr char buildingMinus[] = "\xf0\x90\x81\xa1"; + inline constexpr char buildingMonument[] = "\xee\xb4\xa6"; + inline constexpr char buildingMosque[] = "\xef\xa9\x97"; + inline constexpr char buildingOff[] = "\xef\xbb\xbd"; + inline constexpr char buildingPavilion[] = "\xee\xaf\xb7"; + inline constexpr char buildingPlus[] = "\xf0\x90\x81\xa0"; + inline constexpr char buildingSkyscraper[] = "\xee\xb0\xb9"; + inline constexpr char buildingStadium[] = "\xef\x99\x81"; + inline constexpr char buildingStore[] = "\xee\xa9\x8e"; + inline constexpr char buildingTunnel[] = "\xef\x96\xa6"; + inline constexpr char buildingWarehouse[] = "\xee\xaf\xa3"; + inline constexpr char buildingWindTurbine[] = "\xef\x93\x80"; + inline constexpr char buildings[] = "\xef\xbd\x80"; + inline constexpr char bulb[] = "\xee\xa9\x91"; + inline constexpr char bulbOff[] = "\xee\xa9\x90"; + inline constexpr char bulldozer[] = "\xee\xb8\x9d"; + inline constexpr char burger[] = "\xef\xb2\xb4"; + inline constexpr char bus[] = "\xee\xaf\xa4"; + inline constexpr char busOff[] = "\xef\x8f\x8e"; + inline constexpr char busStop[] = "\xef\x8b\x94"; + inline constexpr char businessplan[] = "\xee\xb8\x9e"; + inline constexpr char butterfly[] = "\xee\xbf\x99"; + inline constexpr char cactus[] = "\xef\x88\x9b"; + inline constexpr char cactusOff[] = "\xef\x8f\x8f"; + inline constexpr char cake[] = "\xef\x80\x8f"; + inline constexpr char cakeOff[] = "\xef\x84\x84"; + inline constexpr char cakeRoll[] = "\xf0\x90\x82\xbd"; + inline constexpr char calculator[] = "\xee\xae\x80"; + inline constexpr char calculatorOff[] = "\xef\x83\x84"; + inline constexpr char calendar[] = "\xee\xa9\x93"; + inline constexpr char calendarBolt[] = "\xef\xa0\xa2"; + inline constexpr char calendarCancel[] = "\xef\xa0\xa3"; + inline constexpr char calendarCheck[] = "\xef\xa0\xa4"; + inline constexpr char calendarClock[] = "\xef\xb4\xae"; + inline constexpr char calendarCode[] = "\xef\xa0\xa5"; + inline constexpr char calendarCog[] = "\xef\xa0\xa6"; + inline constexpr char calendarDollar[] = "\xef\xa0\xa7"; + inline constexpr char calendarDot[] = "\xef\xb4\xbe"; + inline constexpr char calendarDown[] = "\xef\xa0\xa8"; + inline constexpr char calendarDue[] = "\xef\x98\xa1"; + inline constexpr char calendarEvent[] = "\xee\xa9\x92"; + inline constexpr char calendarExclamation[] = "\xef\xa0\xa9"; + inline constexpr char calendarHeart[] = "\xef\xa0\xaa"; + inline constexpr char calendarMinus[] = "\xee\xae\xb9"; + inline constexpr char calendarMonth[] = "\xef\xb4\xaf"; + inline constexpr char calendarOff[] = "\xee\xb8\x9f"; + inline constexpr char calendarPause[] = "\xef\xa0\xab"; + inline constexpr char calendarPin[] = "\xef\xa0\xac"; + inline constexpr char calendarPlus[] = "\xee\xae\xba"; + inline constexpr char calendarQuestion[] = "\xef\xa0\xad"; + inline constexpr char calendarRepeat[] = "\xef\xab\x92"; + inline constexpr char calendarSad[] = "\xef\xb4\x9d"; + inline constexpr char calendarSearch[] = "\xef\xa0\xae"; + inline constexpr char calendarShare[] = "\xef\xa0\xaf"; + inline constexpr char calendarSmile[] = "\xef\xb4\x9e"; + inline constexpr char calendarStar[] = "\xef\xa0\xb0"; + inline constexpr char calendarStats[] = "\xee\xb8\xa0"; + inline constexpr char calendarTime[] = "\xee\xb8\xa1"; + inline constexpr char calendarUp[] = "\xef\xa0\xb1"; + inline constexpr char calendarUser[] = "\xef\xb4\x9f"; + inline constexpr char calendarWeek[] = "\xef\xb4\xb0"; + inline constexpr char calendarX[] = "\xef\xa0\xb2"; + inline constexpr char camera[] = "\xee\xa9\x94"; + inline constexpr char cameraAi[] = "\xef\xbe\xa8"; + inline constexpr char cameraBitcoin[] = "\xef\xbe\xa7"; + inline constexpr char cameraBolt[] = "\xef\xa0\xb3"; + inline constexpr char cameraCancel[] = "\xef\xa0\xb4"; + inline constexpr char cameraCheck[] = "\xef\xa0\xb5"; + inline constexpr char cameraCode[] = "\xef\xa0\xb6"; + inline constexpr char cameraCog[] = "\xef\xa0\xb7"; + inline constexpr char cameraDollar[] = "\xef\xa0\xb8"; + inline constexpr char cameraDown[] = "\xef\xa0\xb9"; + inline constexpr char cameraExclamation[] = "\xef\xa0\xba"; + inline constexpr char cameraHeart[] = "\xef\xa0\xbb"; + inline constexpr char cameraMinus[] = "\xee\xb0\xba"; + inline constexpr char cameraMoon[] = "\xef\xbe\xa6"; + inline constexpr char cameraOff[] = "\xee\xb3\xae"; + inline constexpr char cameraPause[] = "\xef\xa0\xbc"; + inline constexpr char cameraPin[] = "\xef\xa0\xbd"; + inline constexpr char cameraPlus[] = "\xee\xb0\xbb"; + inline constexpr char cameraQuestion[] = "\xef\xa0\xbe"; + inline constexpr char cameraRotate[] = "\xee\xb8\xa2"; + inline constexpr char cameraSearch[] = "\xef\xa0\xbf"; + inline constexpr char cameraSelfie[] = "\xee\xb8\xa3"; + inline constexpr char cameraShare[] = "\xef\xa1\x80"; + inline constexpr char cameraSpark[] = "\xef\xbe\xbc"; + inline constexpr char cameraStar[] = "\xef\xa1\x81"; + inline constexpr char cameraUp[] = "\xef\xa1\x82"; + inline constexpr char cameraX[] = "\xef\xa1\x83"; + inline constexpr char camper[] = "\xef\xa8\xa5"; + inline constexpr char campfire[] = "\xef\x96\xa7"; + inline constexpr char canary[] = "\xf0\x90\x87\xb5"; + inline constexpr char cancel[] = "\xef\xbc\x91"; + inline constexpr char candle[] = "\xee\xbf\x86"; + inline constexpr char candy[] = "\xee\xbc\x8d"; + inline constexpr char candyOff[] = "\xef\x83\x85"; + inline constexpr char cane[] = "\xef\x94\x8f"; + inline constexpr char cannabis[] = "\xef\x93\x81"; + inline constexpr char capProjecting[] = "\xef\xbc\xa2"; + inline constexpr char capRounded[] = "\xef\xbc\xa1"; + inline constexpr char capStraight[] = "\xef\xbc\xa0"; + inline constexpr char capsule[] = "\xef\xab\xa3"; + inline constexpr char capsuleHorizontal[] = "\xef\xab\xa2"; + inline constexpr char capture[] = "\xee\xb0\xbc"; + inline constexpr char captureOff[] = "\xef\x83\x86"; + inline constexpr char car[] = "\xee\xae\xbb"; + inline constexpr char car4wd[] = "\xef\xb6\xb8"; + inline constexpr char carCrane[] = "\xee\xbc\xa5"; + inline constexpr char carCrash[] = "\xee\xbe\xa4"; + inline constexpr char carDoor[] = "\xf0\x90\x89\x90"; + inline constexpr char carFan[] = "\xef\xb6\xb3"; + inline constexpr char carFan1[] = "\xef\xb6\xb7"; + inline constexpr char carFan2[] = "\xef\xb6\xb6"; + inline constexpr char carFan3[] = "\xef\xb6\xb5"; + inline constexpr char carFanAuto[] = "\xef\xb6\xb4"; + inline constexpr char carGarage[] = "\xef\xb1\xb7"; + inline constexpr char carLifter[] = "\xf0\x90\x89\x8f"; + inline constexpr char carOff[] = "\xef\x83\x87"; + inline constexpr char carOffRoad[] = "\xf0\x90\x88\xb0"; + inline constexpr char carSuspension[] = "\xf0\x90\x88\xaf"; + inline constexpr char carSuv[] = "\xef\xb2\x8b"; + inline constexpr char carTurbine[] = "\xef\x93\xbd"; + inline constexpr char carambola[] = "\xef\xba\xb9"; + inline constexpr char caravan[] = "\xee\xb1\xbc"; + inline constexpr char cardboards[] = "\xee\xb5\xb4"; + inline constexpr char cardboardsOff[] = "\xef\x83\x88"; + inline constexpr char cards[] = "\xef\x94\x90"; + inline constexpr char caretDown[] = "\xee\xad\x9d"; + inline constexpr char caretLeft[] = "\xee\xad\x9e"; + inline constexpr char caretLeftRight[] = "\xef\xb1\x83"; + inline constexpr char caretRight[] = "\xee\xad\x9f"; + inline constexpr char caretUp[] = "\xee\xad\xa0"; + inline constexpr char caretUpDown[] = "\xef\xb1\x84"; + inline constexpr char carouselHorizontal[] = "\xef\x99\x99"; + inline constexpr char carouselVertical[] = "\xef\x99\x9a"; + inline constexpr char carrot[] = "\xef\x88\x9c"; + inline constexpr char carrotOff[] = "\xef\x8f\x90"; + inline constexpr char cash[] = "\xee\xa9\x95"; + inline constexpr char cashBanknote[] = "\xee\xb8\xa5"; + inline constexpr char cashBanknoteEdit[] = "\xf0\x90\x85\x89"; + inline constexpr char cashBanknoteHeart[] = "\xf0\x90\x85\x88"; + inline constexpr char cashBanknoteMinus[] = "\xf0\x90\x85\x87"; + inline constexpr char cashBanknoteMove[] = "\xf0\x90\x85\x85"; + inline constexpr char cashBanknoteMoveBack[] = "\xf0\x90\x85\x86"; + inline constexpr char cashBanknoteOff[] = "\xee\xb8\xa4"; + inline constexpr char cashBanknotePlus[] = "\xf0\x90\x85\x84"; + inline constexpr char cashEdit[] = "\xf0\x90\x85\x83"; + inline constexpr char cashHeart[] = "\xf0\x90\x85\x82"; + inline constexpr char cashMinus[] = "\xf0\x90\x85\x81"; + inline constexpr char cashMove[] = "\xf0\x90\x84\xbf"; + inline constexpr char cashMoveBack[] = "\xf0\x90\x85\x80"; + inline constexpr char cashOff[] = "\xef\x84\x85"; + inline constexpr char cashPlus[] = "\xf0\x90\x84\xbe"; + inline constexpr char cashRegister[] = "\xef\xbb\xa6"; + inline constexpr char cast[] = "\xee\xa9\x96"; + inline constexpr char castOff[] = "\xef\x83\x89"; + inline constexpr char cat[] = "\xef\x99\x9b"; + inline constexpr char category[] = "\xef\x87\xb6"; + inline constexpr char category2[] = "\xef\x87\xb5"; + inline constexpr char categoryMinus[] = "\xef\xb4\xa0"; + inline constexpr char categoryPlus[] = "\xef\xb4\xa1"; + inline constexpr char ce[] = "\xee\xb5\xb5"; + inline constexpr char ceOff[] = "\xef\x83\x8a"; + inline constexpr char cell[] = "\xef\x81\x9f"; + inline constexpr char cellSignal1[] = "\xef\x82\x83"; + inline constexpr char cellSignal2[] = "\xef\x82\x84"; + inline constexpr char cellSignal3[] = "\xef\x82\x85"; + inline constexpr char cellSignal4[] = "\xef\x82\x86"; + inline constexpr char cellSignal5[] = "\xef\x82\x87"; + inline constexpr char cellSignalOff[] = "\xef\x82\x88"; + inline constexpr char certificate[] = "\xee\xb5\xb6"; + inline constexpr char certificate2[] = "\xef\x81\xb3"; + inline constexpr char certificate2Off[] = "\xef\x83\x8b"; + inline constexpr char certificateOff[] = "\xef\x83\x8c"; + inline constexpr char chairDirector[] = "\xef\x8b\x95"; + inline constexpr char chalkboard[] = "\xef\x8d\x8d"; + inline constexpr char chalkboardOff[] = "\xef\x8f\x91"; + inline constexpr char chalkboardTeacher[] = "\xf0\x90\x85\xa0"; + inline constexpr char chargingPile[] = "\xee\xb8\xa6"; + inline constexpr char chartArcs[] = "\xee\xb8\xa8"; + inline constexpr char chartArcs3[] = "\xee\xb8\xa7"; + inline constexpr char chartArea[] = "\xee\xa9\x98"; + inline constexpr char chartAreaLine[] = "\xee\xa9\x97"; + inline constexpr char chartArrows[] = "\xee\xb8\xaa"; + inline constexpr char chartArrowsVertical[] = "\xee\xb8\xa9"; + inline constexpr char chartBar[] = "\xee\xa9\x99"; + inline constexpr char chartBarOff[] = "\xef\x8f\x92"; + inline constexpr char chartBarPopular[] = "\xef\xbb\xb7"; + inline constexpr char chartBubble[] = "\xee\xb1\xb5"; + inline constexpr char chartCandle[] = "\xee\xa9\x9a"; + inline constexpr char chartCircles[] = "\xee\xb8\xab"; + inline constexpr char chartCohort[] = "\xef\xbb\xb6"; + inline constexpr char chartColumn[] = "\xef\xbe\xa5"; + inline constexpr char chartCovariate[] = "\xef\xbe\xa4"; + inline constexpr char chartDonut[] = "\xee\xa9\x9b"; + inline constexpr char chartDonut2[] = "\xee\xb8\xac"; + inline constexpr char chartDonut3[] = "\xee\xb8\xad"; + inline constexpr char chartDonut4[] = "\xee\xb8\xae"; + inline constexpr char chartDots[] = "\xee\xb8\xaf"; + inline constexpr char chartDots2[] = "\xef\x82\x97"; + inline constexpr char chartDots3[] = "\xef\x82\x98"; + inline constexpr char chartFunnel[] = "\xef\xbb\xb5"; + inline constexpr char chartGridDots[] = "\xef\x93\x82"; + inline constexpr char chartHistogram[] = "\xef\x99\x9c"; + inline constexpr char chartInfographic[] = "\xee\xb8\xb0"; + inline constexpr char chartLine[] = "\xee\xa9\x9c"; + inline constexpr char chartPie[] = "\xee\xa9\x9d"; + inline constexpr char chartPie2[] = "\xee\xb8\xb1"; + inline constexpr char chartPie3[] = "\xee\xb8\xb2"; + inline constexpr char chartPie4[] = "\xee\xb8\xb3"; + inline constexpr char chartPieOff[] = "\xef\x8f\x93"; + inline constexpr char chartPpf[] = "\xef\x98\x98"; + inline constexpr char chartRadar[] = "\xee\xb5\xb7"; + inline constexpr char chartSankey[] = "\xef\x98\x99"; + inline constexpr char chartScatter[] = "\xef\xb6\x93"; + inline constexpr char chartScatter3d[] = "\xef\xb6\x92"; + inline constexpr char chartTreemap[] = "\xef\x8e\x81"; + inline constexpr char check[] = "\xee\xa9\x9e"; + inline constexpr char checkbox[] = "\xee\xae\xa6"; + inline constexpr char checklist[] = "\xef\x81\xb4"; + inline constexpr char checks[] = "\xee\xae\xaa"; + inline constexpr char checkupList[] = "\xee\xbd\x9a"; + inline constexpr char cheese[] = "\xee\xbc\xa6"; + inline constexpr char chefHat[] = "\xef\x88\x9d"; + inline constexpr char chefHatOff[] = "\xef\x8f\x94"; + inline constexpr char cherry[] = "\xef\x94\x91"; + inline constexpr char chess[] = "\xef\x8e\x82"; + inline constexpr char chessBishop[] = "\xef\x95\xab"; + inline constexpr char chessKing[] = "\xef\x95\xac"; + inline constexpr char chessKnight[] = "\xef\x95\xad"; + inline constexpr char chessQueen[] = "\xef\x95\xae"; + inline constexpr char chessRook[] = "\xef\x95\xaf"; + inline constexpr char chevronCompactDown[] = "\xef\xab\xb0"; + inline constexpr char chevronCompactLeft[] = "\xef\xab\xb1"; + inline constexpr char chevronCompactRight[] = "\xef\xab\xb2"; + inline constexpr char chevronCompactUp[] = "\xef\xab\xb3"; + inline constexpr char chevronDown[] = "\xee\xa9\x9f"; + inline constexpr char chevronDownLeft[] = "\xee\xb4\x89"; + inline constexpr char chevronDownRight[] = "\xee\xb4\x8a"; + inline constexpr char chevronLeft[] = "\xee\xa9\xa0"; + inline constexpr char chevronLeftPipe[] = "\xef\xab\xa4"; + inline constexpr char chevronRight[] = "\xee\xa9\xa1"; + inline constexpr char chevronRightPipe[] = "\xef\xab\xa5"; + inline constexpr char chevronUp[] = "\xee\xa9\xa2"; + inline constexpr char chevronUpLeft[] = "\xee\xb4\x8b"; + inline constexpr char chevronUpRight[] = "\xee\xb4\x8c"; + inline constexpr char chevronsDown[] = "\xee\xa9\xa3"; + inline constexpr char chevronsDownLeft[] = "\xee\xb4\x8d"; + inline constexpr char chevronsDownRight[] = "\xee\xb4\x8e"; + inline constexpr char chevronsLeft[] = "\xee\xa9\xa4"; + inline constexpr char chevronsRight[] = "\xee\xa9\xa5"; + inline constexpr char chevronsUp[] = "\xee\xa9\xa6"; + inline constexpr char chevronsUpLeft[] = "\xee\xb4\x8f"; + inline constexpr char chevronsUpRight[] = "\xee\xb4\x90"; + inline constexpr char chisel[] = "\xef\x8e\x83"; + inline constexpr char chocolate[] = "\xf0\x90\x89\x8e"; + inline constexpr char christmasBall[] = "\xef\xb4\xb1"; + inline constexpr char christmasTree[] = "\xee\xb5\xb8"; + inline constexpr char christmasTreeOff[] = "\xef\x8f\x95"; + inline constexpr char circle[] = "\xee\xa9\xab"; + inline constexpr char circleArrowDown[] = "\xef\x9b\xb9"; + inline constexpr char circleArrowDownLeft[] = "\xef\x9b\xb6"; + inline constexpr char circleArrowDownRight[] = "\xef\x9b\xb8"; + inline constexpr char circleArrowLeft[] = "\xef\x9b\xbb"; + inline constexpr char circleArrowRight[] = "\xef\x9b\xbd"; + inline constexpr char circleArrowUp[] = "\xef\x9c\x83"; + inline constexpr char circleArrowUpLeft[] = "\xef\x9c\x80"; + inline constexpr char circleArrowUpRight[] = "\xef\x9c\x82"; + inline constexpr char circleAsterisk[] = "\xf0\x90\x86\xad"; + inline constexpr char circleCaretDown[] = "\xef\x92\xa9"; + inline constexpr char circleCaretLeft[] = "\xef\x92\xaa"; + inline constexpr char circleCaretRight[] = "\xef\x92\xab"; + inline constexpr char circleCaretUp[] = "\xef\x92\xac"; + inline constexpr char circleCheck[] = "\xee\xa9\xa7"; + inline constexpr char circleChevronDown[] = "\xef\x98\xa2"; + inline constexpr char circleChevronLeft[] = "\xef\x98\xa3"; + inline constexpr char circleChevronRight[] = "\xef\x98\xa4"; + inline constexpr char circleChevronUp[] = "\xef\x98\xa5"; + inline constexpr char circleChevronsDown[] = "\xef\x99\x82"; + inline constexpr char circleChevronsLeft[] = "\xef\x99\x83"; + inline constexpr char circleChevronsRight[] = "\xef\x99\x84"; + inline constexpr char circleChevronsUp[] = "\xef\x99\x85"; + inline constexpr char circleDashed[] = "\xee\xb4\xa7"; + inline constexpr char circleDashedCheck[] = "\xef\xba\xb8"; + inline constexpr char circleDashedLetterA[] = "\xef\xbe\x9a"; + inline constexpr char circleDashedLetterB[] = "\xef\xbe\x99"; + inline constexpr char circleDashedLetterC[] = "\xef\xbe\x98"; + inline constexpr char circleDashedLetterD[] = "\xef\xbe\x97"; + inline constexpr char circleDashedLetterE[] = "\xef\xbe\x96"; + inline constexpr char circleDashedLetterF[] = "\xef\xbe\x95"; + inline constexpr char circleDashedLetterG[] = "\xef\xbe\x94"; + inline constexpr char circleDashedLetterH[] = "\xef\xbe\x93"; + inline constexpr char circleDashedLetterI[] = "\xef\xbe\x92"; + inline constexpr char circleDashedLetterJ[] = "\xef\xbe\x91"; + inline constexpr char circleDashedLetterK[] = "\xef\xbe\x90"; + inline constexpr char circleDashedLetterL[] = "\xef\xbe\x8f"; + inline constexpr char circleDashedLetterM[] = "\xef\xbe\x8d"; + inline constexpr char circleDashedLetterN[] = "\xef\xbe\x8c"; + inline constexpr char circleDashedLetterO[] = "\xef\xbe\x8b"; + inline constexpr char circleDashedLetterP[] = "\xef\xbe\x8a"; + inline constexpr char circleDashedLetterQ[] = "\xef\xbe\x89"; + inline constexpr char circleDashedLetterR[] = "\xef\xbe\x88"; + inline constexpr char circleDashedLetterS[] = "\xef\xbe\x87"; + inline constexpr char circleDashedLetterT[] = "\xef\xbe\x86"; + inline constexpr char circleDashedLetterU[] = "\xef\xbe\x85"; + inline constexpr char circleDashedLetterV[] = "\xef\xbe\x84"; + inline constexpr char circleDashedLetterW[] = "\xef\xbe\x83"; + inline constexpr char circleDashedLetterX[] = "\xef\xbe\x82"; + inline constexpr char circleDashedLetterY[] = "\xef\xbe\x81"; + inline constexpr char circleDashedLetterZ[] = "\xef\xbe\x80"; + inline constexpr char circleDashedMinus[] = "\xef\xba\xb7"; + inline constexpr char circleDashedNumber0[] = "\xef\xb1\xab"; + inline constexpr char circleDashedNumber1[] = "\xef\xb1\xac"; + inline constexpr char circleDashedNumber2[] = "\xef\xb1\xad"; + inline constexpr char circleDashedNumber3[] = "\xef\xb1\xae"; + inline constexpr char circleDashedNumber4[] = "\xef\xb1\xaf"; + inline constexpr char circleDashedNumber5[] = "\xef\xb1\xb0"; + inline constexpr char circleDashedNumber6[] = "\xef\xb1\xb1"; + inline constexpr char circleDashedNumber7[] = "\xef\xb1\xb2"; + inline constexpr char circleDashedNumber8[] = "\xef\xb1\xb3"; + inline constexpr char circleDashedNumber9[] = "\xef\xb1\xb4"; + inline constexpr char circleDashedPercentage[] = "\xef\xb5\xba"; + inline constexpr char circleDashedPlus[] = "\xef\xba\xb6"; + inline constexpr char circleDashedX[] = "\xef\xb1\xb5"; + inline constexpr char circleDot[] = "\xee\xbe\xb1"; + inline constexpr char circleDotted[] = "\xee\xb4\xa8"; + inline constexpr char circleDottedLetterA[] = "\xef\xbd\xbf"; + inline constexpr char circleDottedLetterB[] = "\xef\xbd\xbe"; + inline constexpr char circleDottedLetterC[] = "\xef\xbd\xbd"; + inline constexpr char circleDottedLetterD[] = "\xef\xbd\xbc"; + inline constexpr char circleDottedLetterE[] = "\xef\xbd\xbb"; + inline constexpr char circleDottedLetterF[] = "\xef\xbd\xba"; + inline constexpr char circleDottedLetterG[] = "\xef\xbd\xb9"; + inline constexpr char circleDottedLetterH[] = "\xef\xbd\xb8"; + inline constexpr char circleDottedLetterI[] = "\xef\xbd\xb7"; + inline constexpr char circleDottedLetterJ[] = "\xef\xbd\xb6"; + inline constexpr char circleDottedLetterK[] = "\xef\xbd\xb5"; + inline constexpr char circleDottedLetterL[] = "\xef\xbd\xb4"; + inline constexpr char circleDottedLetterM[] = "\xef\xbd\xb3"; + inline constexpr char circleDottedLetterN[] = "\xef\xbd\xb2"; + inline constexpr char circleDottedLetterO[] = "\xef\xbd\xb1"; + inline constexpr char circleDottedLetterP[] = "\xef\xbd\xb0"; + inline constexpr char circleDottedLetterQ[] = "\xef\xbd\xaf"; + inline constexpr char circleDottedLetterR[] = "\xef\xbd\xae"; + inline constexpr char circleDottedLetterS[] = "\xef\xbd\xad"; + inline constexpr char circleDottedLetterT[] = "\xef\xbd\xac"; + inline constexpr char circleDottedLetterU[] = "\xef\xbd\xab"; + inline constexpr char circleDottedLetterV[] = "\xef\xbd\xaa"; + inline constexpr char circleDottedLetterW[] = "\xef\xbd\xa9"; + inline constexpr char circleDottedLetterX[] = "\xef\xbd\xa8"; + inline constexpr char circleDottedLetterY[] = "\xef\xbd\xa7"; + inline constexpr char circleDottedLetterZ[] = "\xef\xbd\xa6"; + inline constexpr char circleHalf[] = "\xee\xb8\xbf"; + inline constexpr char circleHalf2[] = "\xee\xbf\xb3"; + inline constexpr char circleHalfVertical[] = "\xee\xb8\xbe"; + inline constexpr char circleKey[] = "\xef\x98\xb3"; + inline constexpr char circleLetterA[] = "\xef\x91\x81"; + inline constexpr char circleLetterB[] = "\xef\x91\x82"; + inline constexpr char circleLetterC[] = "\xef\x91\x83"; + inline constexpr char circleLetterD[] = "\xef\x91\x84"; + inline constexpr char circleLetterE[] = "\xef\x91\x85"; + inline constexpr char circleLetterF[] = "\xef\x91\x86"; + inline constexpr char circleLetterG[] = "\xef\x91\x87"; + inline constexpr char circleLetterH[] = "\xef\x91\x88"; + inline constexpr char circleLetterI[] = "\xef\x91\x89"; + inline constexpr char circleLetterJ[] = "\xef\x91\x8a"; + inline constexpr char circleLetterK[] = "\xef\x91\x8b"; + inline constexpr char circleLetterL[] = "\xef\x91\x8c"; + inline constexpr char circleLetterM[] = "\xef\x91\x8d"; + inline constexpr char circleLetterN[] = "\xef\x91\x8e"; + inline constexpr char circleLetterO[] = "\xef\x91\x8f"; + inline constexpr char circleLetterP[] = "\xef\x91\x90"; + inline constexpr char circleLetterQ[] = "\xef\x91\x91"; + inline constexpr char circleLetterR[] = "\xef\x91\x92"; + inline constexpr char circleLetterS[] = "\xef\x91\x93"; + inline constexpr char circleLetterT[] = "\xef\x91\x94"; + inline constexpr char circleLetterU[] = "\xef\x91\x95"; + inline constexpr char circleLetterV[] = "\xef\x92\xad"; + inline constexpr char circleLetterW[] = "\xef\x91\x96"; + inline constexpr char circleLetterX[] = "\xef\x92\xae"; + inline constexpr char circleLetterY[] = "\xef\x91\x97"; + inline constexpr char circleLetterZ[] = "\xef\x91\x98"; + inline constexpr char circleMinus[] = "\xee\xa9\xa8"; + inline constexpr char circleMinus2[] = "\xef\xb2\x8c"; + inline constexpr char circleNumber0[] = "\xee\xb8\xb4"; + inline constexpr char circleNumber1[] = "\xee\xb8\xb5"; + inline constexpr char circleNumber2[] = "\xee\xb8\xb6"; + inline constexpr char circleNumber3[] = "\xee\xb8\xb7"; + inline constexpr char circleNumber4[] = "\xee\xb8\xb8"; + inline constexpr char circleNumber5[] = "\xee\xb8\xb9"; + inline constexpr char circleNumber6[] = "\xee\xb8\xba"; + inline constexpr char circleNumber7[] = "\xee\xb8\xbb"; + inline constexpr char circleNumber8[] = "\xee\xb8\xbc"; + inline constexpr char circleNumber9[] = "\xee\xb8\xbd"; + inline constexpr char circleOff[] = "\xee\xb9\x80"; + inline constexpr char circleOpenArrowDown[] = "\xf0\x90\x88\x89"; + inline constexpr char circleOpenArrowLeft[] = "\xf0\x90\x88\x88"; + inline constexpr char circleOpenArrowRight[] = "\xf0\x90\x88\x87"; + inline constexpr char circleOpenArrowUp[] = "\xf0\x90\x88\x86"; + inline constexpr char circlePercentage[] = "\xef\xb5\xbb"; + inline constexpr char circlePlus[] = "\xee\xa9\xa9"; + inline constexpr char circlePlus2[] = "\xef\xb2\x8d"; + inline constexpr char circlePlusMinus[] = "\xf0\x90\x88\x85"; + inline constexpr char circleRectangle[] = "\xef\x80\x90"; + inline constexpr char circleRectangleOff[] = "\xef\x83\x8d"; + inline constexpr char circleSquare[] = "\xee\xb3\xa4"; + inline constexpr char circleTriangle[] = "\xef\x80\x91"; + inline constexpr char circleX[] = "\xee\xa9\xaa"; + inline constexpr char circles[] = "\xee\xb3\xa5"; + inline constexpr char circlesRelation[] = "\xef\x93\x83"; + inline constexpr char circuitAmmeter[] = "\xef\x89\xb1"; + inline constexpr char circuitBattery[] = "\xef\x89\xb2"; + inline constexpr char circuitBulb[] = "\xef\x89\xb3"; + inline constexpr char circuitCapacitor[] = "\xef\x89\xb5"; + inline constexpr char circuitCapacitorPolarized[] = "\xef\x89\xb4"; + inline constexpr char circuitCell[] = "\xef\x89\xb7"; + inline constexpr char circuitCellPlus[] = "\xef\x89\xb6"; + inline constexpr char circuitChangeover[] = "\xef\x89\xb8"; + inline constexpr char circuitDiode[] = "\xef\x89\xba"; + inline constexpr char circuitDiodeZener[] = "\xef\x89\xb9"; + inline constexpr char circuitGround[] = "\xef\x89\xbc"; + inline constexpr char circuitGroundDigital[] = "\xef\x89\xbb"; + inline constexpr char circuitInductor[] = "\xef\x89\xbd"; + inline constexpr char circuitMotor[] = "\xef\x89\xbe"; + inline constexpr char circuitPushbutton[] = "\xef\x89\xbf"; + inline constexpr char circuitResistor[] = "\xef\x8a\x80"; + inline constexpr char circuitSwitchClosed[] = "\xef\x8a\x81"; + inline constexpr char circuitSwitchOpen[] = "\xef\x8a\x82"; + inline constexpr char circuitVoltmeter[] = "\xef\x8a\x83"; + inline constexpr char clearAll[] = "\xee\xb9\x81"; + inline constexpr char clearFormatting[] = "\xee\xaf\xa5"; + inline constexpr char clef[] = "\xf0\x90\x89\x80"; + inline constexpr char clefStaff[] = "\xf0\x90\x89\x81"; + inline constexpr char click[] = "\xee\xae\xbc"; + inline constexpr char cliffJumping[] = "\xef\xbb\xbc"; + inline constexpr char clipboard[] = "\xee\xa9\xaf"; + inline constexpr char clipboardCheck[] = "\xee\xa9\xac"; + inline constexpr char clipboardCopy[] = "\xef\x8a\x99"; + inline constexpr char clipboardData[] = "\xef\x95\xa3"; + inline constexpr char clipboardHeart[] = "\xef\x8d\x8e"; + inline constexpr char clipboardList[] = "\xee\xa9\xad"; + inline constexpr char clipboardOff[] = "\xef\x83\x8e"; + inline constexpr char clipboardPlus[] = "\xee\xbe\xb2"; + inline constexpr char clipboardSearch[] = "\xf0\x90\x82\x98"; + inline constexpr char clipboardSmile[] = "\xef\xb6\x9a"; + inline constexpr char clipboardText[] = "\xef\x82\x89"; + inline constexpr char clipboardTypography[] = "\xef\x8d\x8f"; + inline constexpr char clipboardX[] = "\xee\xa9\xae"; + inline constexpr char clock[] = "\xee\xa9\xb0"; + inline constexpr char clock12[] = "\xef\xb1\x96"; + inline constexpr char clock2[] = "\xef\x82\x99"; + inline constexpr char clock24[] = "\xef\xb1\x97"; + inline constexpr char clockBitcoin[] = "\xef\xbc\xbf"; + inline constexpr char clockBolt[] = "\xef\xa1\x84"; + inline constexpr char clockCancel[] = "\xef\x95\x86"; + inline constexpr char clockCheck[] = "\xef\x9f\x81"; + inline constexpr char clockCode[] = "\xef\xa1\x85"; + inline constexpr char clockCog[] = "\xef\x9f\x82"; + inline constexpr char clockDollar[] = "\xef\xa1\x86"; + inline constexpr char clockDown[] = "\xef\x9f\x83"; + inline constexpr char clockEdit[] = "\xef\x95\x87"; + inline constexpr char clockExclamation[] = "\xef\xa1\x87"; + inline constexpr char clockHeart[] = "\xef\x9f\x84"; + inline constexpr char clockHour1[] = "\xef\x8c\x93"; + inline constexpr char clockHour10[] = "\xef\x8c\x94"; + inline constexpr char clockHour11[] = "\xef\x8c\x95"; + inline constexpr char clockHour12[] = "\xef\x8c\x96"; + inline constexpr char clockHour2[] = "\xef\x8c\x97"; + inline constexpr char clockHour3[] = "\xef\x8c\x98"; + inline constexpr char clockHour4[] = "\xef\x8c\x99"; + inline constexpr char clockHour5[] = "\xef\x8c\x9a"; + inline constexpr char clockHour6[] = "\xef\x8c\x9b"; + inline constexpr char clockHour7[] = "\xef\x8c\x9c"; + inline constexpr char clockHour8[] = "\xef\x8c\x9d"; + inline constexpr char clockHour9[] = "\xef\x8c\x9e"; + inline constexpr char clockMinus[] = "\xef\xa1\x88"; + inline constexpr char clockOff[] = "\xef\x83\x8f"; + inline constexpr char clockPause[] = "\xef\x95\x88"; + inline constexpr char clockPin[] = "\xef\xa1\x89"; + inline constexpr char clockPlay[] = "\xef\x95\x89"; + inline constexpr char clockPlus[] = "\xef\x9f\x85"; + inline constexpr char clockQuestion[] = "\xef\x9f\x86"; + inline constexpr char clockRecord[] = "\xef\x95\x8a"; + inline constexpr char clockSearch[] = "\xef\x9f\x87"; + inline constexpr char clockShare[] = "\xef\xa1\x8a"; + inline constexpr char clockShield[] = "\xef\x9f\x88"; + inline constexpr char clockStar[] = "\xef\x9f\x89"; + inline constexpr char clockStop[] = "\xef\x95\x8b"; + inline constexpr char clockUp[] = "\xef\x9f\x8a"; + inline constexpr char clockX[] = "\xef\x9f\x8b"; + inline constexpr char clothesRack[] = "\xef\x8a\x85"; + inline constexpr char clothesRackOff[] = "\xef\x8f\x96"; + inline constexpr char cloud[] = "\xee\xa9\xb6"; + inline constexpr char cloudBitcoin[] = "\xef\xbc\xbe"; + inline constexpr char cloudBolt[] = "\xef\xa1\x8b"; + inline constexpr char cloudCancel[] = "\xef\xa1\x8c"; + inline constexpr char cloudCheck[] = "\xef\xa1\x8d"; + inline constexpr char cloudCode[] = "\xef\xa1\x8e"; + inline constexpr char cloudCog[] = "\xef\xa1\x8f"; + inline constexpr char cloudComputing[] = "\xef\x87\x90"; + inline constexpr char cloudDataConnection[] = "\xef\x87\x91"; + inline constexpr char cloudDollar[] = "\xef\xa1\x90"; + inline constexpr char cloudDown[] = "\xef\xa1\x91"; + inline constexpr char cloudDownload[] = "\xee\xa9\xb1"; + inline constexpr char cloudExclamation[] = "\xef\xa1\x92"; + inline constexpr char cloudFog[] = "\xee\xb3\x99"; + inline constexpr char cloudHeart[] = "\xef\xa1\x93"; + inline constexpr char cloudLock[] = "\xee\xbf\x9b"; + inline constexpr char cloudLockOpen[] = "\xee\xbf\x9a"; + inline constexpr char cloudMinus[] = "\xef\xa1\x94"; + inline constexpr char cloudNetwork[] = "\xef\xb1\xb8"; + inline constexpr char cloudOff[] = "\xee\xb4\xbe"; + inline constexpr char cloudPause[] = "\xef\xa1\x95"; + inline constexpr char cloudPin[] = "\xef\xa1\x96"; + inline constexpr char cloudPlus[] = "\xef\xa1\x97"; + inline constexpr char cloudQuestion[] = "\xef\xa1\x98"; + inline constexpr char cloudRain[] = "\xee\xa9\xb2"; + inline constexpr char cloudSearch[] = "\xef\xa1\x99"; + inline constexpr char cloudShare[] = "\xef\xa1\x9a"; + inline constexpr char cloudSnow[] = "\xee\xa9\xb3"; + inline constexpr char cloudStar[] = "\xef\xa1\x9b"; + inline constexpr char cloudStorm[] = "\xee\xa9\xb4"; + inline constexpr char cloudUp[] = "\xef\xa1\x9c"; + inline constexpr char cloudUpload[] = "\xee\xa9\xb5"; + inline constexpr char cloudX[] = "\xef\xa1\x9d"; + inline constexpr char clover[] = "\xef\x87\xaa"; + inline constexpr char clover2[] = "\xef\x88\x9e"; + inline constexpr char clubs[] = "\xee\xbf\xb4"; + inline constexpr char code[] = "\xee\xa9\xb7"; + inline constexpr char codeAi[] = "\xf0\x90\x89\xa7"; + inline constexpr char codeAsterisk[] = "\xef\x8c\x92"; + inline constexpr char codeCircle[] = "\xef\x93\xbf"; + inline constexpr char codeCircle2[] = "\xef\x93\xbe"; + inline constexpr char codeDots[] = "\xef\x98\x9a"; + inline constexpr char codeMinus[] = "\xee\xb9\x82"; + inline constexpr char codeOff[] = "\xef\x83\x90"; + inline constexpr char codePlus[] = "\xee\xb9\x83"; + inline constexpr char codeVariable[] = "\xf0\x90\x82\xab"; + inline constexpr char codeVariableMinus[] = "\xf0\x90\x82\xad"; + inline constexpr char codeVariablePlus[] = "\xf0\x90\x82\xac"; + inline constexpr char codeblock[] = "\xf0\x90\x87\xb4"; + inline constexpr char coffee[] = "\xee\xbc\x8e"; + inline constexpr char coffeeOff[] = "\xef\x84\x86"; + inline constexpr char coffin[] = "\xef\x95\xb9"; + inline constexpr char coin[] = "\xee\xae\x82"; + inline constexpr char coinBitcoin[] = "\xef\x8a\xbe"; + inline constexpr char coinEuro[] = "\xef\x8a\xbf"; + inline constexpr char coinMonero[] = "\xef\x92\xa0"; + inline constexpr char coinOff[] = "\xef\x83\x91"; + inline constexpr char coinPound[] = "\xef\x8b\x80"; + inline constexpr char coinRupee[] = "\xef\x8b\x81"; + inline constexpr char coinTaka[] = "\xef\xb4\x8d"; + inline constexpr char coinYen[] = "\xef\x8b\x82"; + inline constexpr char coinYuan[] = "\xef\x8b\x83"; + inline constexpr char coins[] = "\xef\x99\x9d"; + inline constexpr char colorFilter[] = "\xef\x96\xa8"; + inline constexpr char colorPicker[] = "\xee\xaf\xa6"; + inline constexpr char colorPickerOff[] = "\xef\x83\x92"; + inline constexpr char colorSwatch[] = "\xee\xad\xa1"; + inline constexpr char colorSwatchOff[] = "\xef\x83\x93"; + inline constexpr char columnInsertLeft[] = "\xee\xb9\x84"; + inline constexpr char columnInsertRight[] = "\xee\xb9\x85"; + inline constexpr char columnRemove[] = "\xef\xab\xb4"; + inline constexpr char columns[] = "\xee\xae\x83"; + inline constexpr char columns1[] = "\xef\x9b\x94"; + inline constexpr char columns2[] = "\xef\x9b\x95"; + inline constexpr char columns3[] = "\xef\x9b\x96"; + inline constexpr char columnsOff[] = "\xef\x83\x94"; + inline constexpr char comet[] = "\xee\xb1\xb6"; + inline constexpr char command[] = "\xee\xa9\xb8"; + inline constexpr char commandOff[] = "\xef\x8f\x97"; + inline constexpr char compass[] = "\xee\xa9\xb9"; + inline constexpr char compassOff[] = "\xef\x83\x95"; + inline constexpr char components[] = "\xee\xbe\xa5"; + inline constexpr char componentsOff[] = "\xef\x83\x96"; + inline constexpr char cone[] = "\xee\xbf\x9d"; + inline constexpr char cone2[] = "\xee\xbf\x9c"; + inline constexpr char coneOff[] = "\xef\x8f\x98"; + inline constexpr char conePlus[] = "\xef\xaa\x94"; + inline constexpr char confetti[] = "\xee\xb9\x86"; + inline constexpr char confettiOff[] = "\xef\x8f\x99"; + inline constexpr char confucius[] = "\xef\x96\x8a"; + inline constexpr char congruentTo[] = "\xef\xbe\xa3"; + inline constexpr char connection[] = "\xf0\x90\x87\xb3"; + inline constexpr char container[] = "\xee\xb9\x87"; + inline constexpr char containerOff[] = "\xef\x84\x87"; + inline constexpr char contract[] = "\xef\xbb\xbb"; + inline constexpr char contrast[] = "\xee\xb1\x8e"; + inline constexpr char contrast2[] = "\xee\xbf\x87"; + inline constexpr char contrast2Off[] = "\xef\x8f\x9a"; + inline constexpr char contrastOff[] = "\xef\x8f\x9b"; + inline constexpr char cooker[] = "\xef\x95\xba"; + inline constexpr char cookie[] = "\xef\xb6\xb1"; + inline constexpr char cookieMan[] = "\xef\xb6\xb2"; + inline constexpr char cookieOff[] = "\xef\x83\x97"; + inline constexpr char copy[] = "\xee\xa9\xba"; + inline constexpr char copyCheck[] = "\xef\xb6\xb0"; + inline constexpr char copyMinus[] = "\xef\xb6\xaf"; + inline constexpr char copyOff[] = "\xef\x83\x98"; + inline constexpr char copyPlus[] = "\xef\xb6\xae"; + inline constexpr char copyX[] = "\xef\xb6\xad"; + inline constexpr char copyleft[] = "\xee\xb0\xbd"; + inline constexpr char copyleftOff[] = "\xef\x83\x99"; + inline constexpr char copyright[] = "\xee\xa9\xbb"; + inline constexpr char copyrightOff[] = "\xef\x83\x9a"; + inline constexpr char cornerDownLeft[] = "\xee\xa9\xbc"; + inline constexpr char cornerDownLeftDouble[] = "\xee\xb9\x88"; + inline constexpr char cornerDownRight[] = "\xee\xa9\xbd"; + inline constexpr char cornerDownRightDouble[] = "\xee\xb9\x89"; + inline constexpr char cornerLeftDown[] = "\xee\xa9\xbe"; + inline constexpr char cornerLeftDownDouble[] = "\xee\xb9\x8a"; + inline constexpr char cornerLeftUp[] = "\xee\xa9\xbf"; + inline constexpr char cornerLeftUpDouble[] = "\xee\xb9\x8b"; + inline constexpr char cornerRightDown[] = "\xee\xaa\x80"; + inline constexpr char cornerRightDownDouble[] = "\xee\xb9\x8c"; + inline constexpr char cornerRightUp[] = "\xee\xaa\x81"; + inline constexpr char cornerRightUpDouble[] = "\xee\xb9\x8d"; + inline constexpr char cornerUpLeft[] = "\xee\xaa\x82"; + inline constexpr char cornerUpLeftDouble[] = "\xee\xb9\x8e"; + inline constexpr char cornerUpRight[] = "\xee\xaa\x83"; + inline constexpr char cornerUpRightDouble[] = "\xee\xb9\x8f"; + inline constexpr char cpu[] = "\xee\xbe\x8e"; + inline constexpr char cpu2[] = "\xef\x81\xb5"; + inline constexpr char cpuOff[] = "\xef\x84\x88"; + inline constexpr char crane[] = "\xee\xbc\xa7"; + inline constexpr char craneOff[] = "\xef\x84\x89"; + inline constexpr char creativeCommons[] = "\xee\xbe\xb3"; + inline constexpr char creativeCommonsBy[] = "\xef\x88\x9f"; + inline constexpr char creativeCommonsNc[] = "\xef\x88\xa0"; + inline constexpr char creativeCommonsNd[] = "\xef\x88\xa1"; + inline constexpr char creativeCommonsOff[] = "\xef\x84\x8a"; + inline constexpr char creativeCommonsSa[] = "\xef\x88\xa2"; + inline constexpr char creativeCommonsZero[] = "\xef\x88\xa3"; + inline constexpr char creditCard[] = "\xee\xaa\x84"; + inline constexpr char creditCardHand[] = "\xf0\x90\x88\xae"; + inline constexpr char creditCardOff[] = "\xee\xb4\x91"; + inline constexpr char creditCardPay[] = "\xef\xb4\xb2"; + inline constexpr char creditCardRefund[] = "\xef\xb4\xb3"; + inline constexpr char credits[] = "\xf0\x90\x87\xb2"; + inline constexpr char cricket[] = "\xef\x82\x9a"; + inline constexpr char crop[] = "\xee\xaa\x85"; + inline constexpr char crop11[] = "\xef\xb5\x90"; + inline constexpr char crop169[] = "\xef\xb5\x91"; + inline constexpr char crop32[] = "\xef\xb5\x92"; + inline constexpr char crop54[] = "\xef\xb5\x93"; + inline constexpr char crop75[] = "\xef\xb5\x94"; + inline constexpr char cropLandscape[] = "\xef\xb5\x95"; + inline constexpr char cropPortrait[] = "\xef\xb5\x96"; + inline constexpr char cross[] = "\xee\xbe\x8f"; + inline constexpr char crossOff[] = "\xef\x84\x8b"; + inline constexpr char crosshair[] = "\xee\xb0\xbe"; + inline constexpr char crown[] = "\xee\xb4\x92"; + inline constexpr char crownOff[] = "\xee\xb9\x90"; + inline constexpr char crutches[] = "\xee\xbd\x9b"; + inline constexpr char crutchesOff[] = "\xef\x84\x8c"; + inline constexpr char crystalBall[] = "\xef\x95\xbb"; + inline constexpr char csv[] = "\xef\x9e\x91"; + inline constexpr char cube[] = "\xef\xaa\x97"; + inline constexpr char cube3dSphere[] = "\xee\xb3\x97"; + inline constexpr char cube3dSphereOff[] = "\xef\x8e\xb5"; + inline constexpr char cubeOff[] = "\xef\xaa\x95"; + inline constexpr char cubePlus[] = "\xef\xaa\x96"; + inline constexpr char cubeSend[] = "\xef\x98\x9b"; + inline constexpr char cubeSpark[] = "\xef\xbe\xbb"; + inline constexpr char cubeUnfolded[] = "\xef\x98\x9c"; + inline constexpr char cup[] = "\xee\xbc\xa8"; + inline constexpr char cupOff[] = "\xef\x84\x8d"; + inline constexpr char curling[] = "\xee\xbf\x88"; + inline constexpr char curlyLoop[] = "\xee\xb3\x9a"; + inline constexpr char currency[] = "\xee\xbe\xa6"; + inline constexpr char currencyAfghani[] = "\xef\x99\x9e"; + inline constexpr char currencyBahraini[] = "\xee\xb9\x91"; + inline constexpr char currencyBaht[] = "\xef\x82\x8a"; + inline constexpr char currencyBitcoin[] = "\xee\xae\xab"; + inline constexpr char currencyCent[] = "\xee\xb9\x93"; + inline constexpr char currencyDinar[] = "\xee\xb9\x94"; + inline constexpr char currencyDirham[] = "\xee\xb9\x95"; + inline constexpr char currencyDogecoin[] = "\xee\xbd\x8b"; + inline constexpr char currencyDollar[] = "\xee\xae\x84"; + inline constexpr char currencyDollarAustralian[] = "\xee\xb9\x96"; + inline constexpr char currencyDollarBrunei[] = "\xef\x8d\xac"; + inline constexpr char currencyDollarCanadian[] = "\xee\xb9\x97"; + inline constexpr char currencyDollarGuyanese[] = "\xef\x8d\xad"; + inline constexpr char currencyDollarOff[] = "\xef\x8f\x9c"; + inline constexpr char currencyDollarSingapore[] = "\xee\xb9\x98"; + inline constexpr char currencyDollarZimbabwean[] = "\xef\x8d\xae"; + inline constexpr char currencyDong[] = "\xef\x8d\xaf"; + inline constexpr char currencyDram[] = "\xef\x8d\xb0"; + inline constexpr char currencyEthereum[] = "\xee\xb9\x99"; + inline constexpr char currencyEuro[] = "\xee\xae\x85"; + inline constexpr char currencyEuroOff[] = "\xef\x8f\x9d"; + inline constexpr char currencyFlorin[] = "\xef\xab\xb5"; + inline constexpr char currencyForint[] = "\xee\xb9\x9a"; + inline constexpr char currencyFrank[] = "\xee\xb9\x9b"; + inline constexpr char currencyGuarani[] = "\xef\x8d\xb1"; + inline constexpr char currencyHryvnia[] = "\xef\x8d\xb2"; + inline constexpr char currencyHusd[] = "\xf0\x90\x88\xbf"; + inline constexpr char currencyIranianRial[] = "\xef\xa9\x98"; + inline constexpr char currencyKip[] = "\xef\x8d\xb3"; + inline constexpr char currencyKroneCzech[] = "\xee\xb9\x9c"; + inline constexpr char currencyKroneDanish[] = "\xee\xb9\x9d"; + inline constexpr char currencyKroneSwedish[] = "\xee\xb9\x9e"; + inline constexpr char currencyLari[] = "\xef\x8d\xb4"; + inline constexpr char currencyLeu[] = "\xee\xb9\x9f"; + inline constexpr char currencyLira[] = "\xee\xb9\xa0"; + inline constexpr char currencyLitecoin[] = "\xee\xb9\xa1"; + inline constexpr char currencyLyd[] = "\xef\x8d\xb5"; + inline constexpr char currencyManat[] = "\xef\x8d\xb6"; + inline constexpr char currencyMonero[] = "\xef\x8d\xb7"; + inline constexpr char currencyNaira[] = "\xee\xb9\xa2"; + inline constexpr char currencyNano[] = "\xef\x9e\xa6"; + inline constexpr char currencyOff[] = "\xef\x8f\x9e"; + inline constexpr char currencyPaanga[] = "\xef\x8d\xb8"; + inline constexpr char currencyPeso[] = "\xef\x99\x9f"; + inline constexpr char currencyPound[] = "\xee\xae\xac"; + inline constexpr char currencyPoundOff[] = "\xef\x8f\x9f"; + inline constexpr char currencyQuetzal[] = "\xef\x8d\xb9"; + inline constexpr char currencyReal[] = "\xee\xb9\xa3"; + inline constexpr char currencyRenminbi[] = "\xee\xb9\xa4"; + inline constexpr char currencyRipple[] = "\xee\xb9\xa5"; + inline constexpr char currencyRiyal[] = "\xee\xb9\xa6"; + inline constexpr char currencyRuble[] = "\xee\xb9\xa7"; + inline constexpr char currencyRufiyaa[] = "\xef\x8d\xba"; + inline constexpr char currencyRupee[] = "\xee\xae\xad"; + inline constexpr char currencyRupeeNepalese[] = "\xef\x8d\xbb"; + inline constexpr char currencyShekel[] = "\xee\xb9\xa8"; + inline constexpr char currencySolana[] = "\xef\x92\xa1"; + inline constexpr char currencySom[] = "\xef\x8d\xbc"; + inline constexpr char currencyTaka[] = "\xee\xb9\xa9"; + inline constexpr char currencyTenge[] = "\xef\x8d\xbd"; + inline constexpr char currencyTether[] = "\xf0\x90\x88\xbe"; + inline constexpr char currencyTugrik[] = "\xee\xb9\xaa"; + inline constexpr char currencyWon[] = "\xee\xb9\xab"; + inline constexpr char currencyXrp[] = "\xef\xb4\xb4"; + inline constexpr char currencyYen[] = "\xee\xae\xae"; + inline constexpr char currencyYenOff[] = "\xef\x8f\xa0"; + inline constexpr char currencyYuan[] = "\xef\x8a\x9a"; + inline constexpr char currencyZcash[] = "\xf0\x90\x88\xbd"; + inline constexpr char currencyZloty[] = "\xee\xb9\xac"; + inline constexpr char currentLocation[] = "\xee\xb3\xaf"; + inline constexpr char currentLocationOff[] = "\xef\x84\x8e"; + inline constexpr char cursorOff[] = "\xef\x84\x8f"; + inline constexpr char cursorText[] = "\xee\xb9\xad"; + inline constexpr char cut[] = "\xee\xaa\x86"; + inline constexpr char cylinder[] = "\xef\x95\x8c"; + inline constexpr char cylinderOff[] = "\xef\xaa\x98"; + inline constexpr char cylinderPlus[] = "\xef\xaa\x99"; + inline constexpr char dashboard[] = "\xee\xaa\x87"; + inline constexpr char dashboardOff[] = "\xef\x8f\xa1"; + inline constexpr char database[] = "\xee\xaa\x88"; + inline constexpr char databaseCog[] = "\xef\xa8\x90"; + inline constexpr char databaseDollar[] = "\xef\xa8\x91"; + inline constexpr char databaseEdit[] = "\xef\xa8\x92"; + inline constexpr char databaseExclamation[] = "\xef\xa8\x93"; + inline constexpr char databaseExport[] = "\xee\xb9\xae"; + inline constexpr char databaseHeart[] = "\xef\xa8\x94"; + inline constexpr char databaseImport[] = "\xee\xb9\xaf"; + inline constexpr char databaseLeak[] = "\xef\xa8\x95"; + inline constexpr char databaseMinus[] = "\xef\xa8\x96"; + inline constexpr char databaseOff[] = "\xee\xb9\xb0"; + inline constexpr char databasePlus[] = "\xef\xa8\x97"; + inline constexpr char databaseSearch[] = "\xef\xa8\x98"; + inline constexpr char databaseShare[] = "\xef\xa8\x99"; + inline constexpr char databaseSmile[] = "\xef\xb6\x9b"; + inline constexpr char databaseStar[] = "\xef\xa8\x9a"; + inline constexpr char databaseX[] = "\xef\xa8\x9b"; + inline constexpr char deaf[] = "\xf0\x90\x86\xac"; + inline constexpr char decimal[] = "\xef\xa8\xa6"; + inline constexpr char deer[] = "\xef\x93\x85"; + inline constexpr char delta[] = "\xef\x94\xbc"; + inline constexpr char dental[] = "\xef\x80\xa5"; + inline constexpr char dentalBroken[] = "\xef\x8a\x86"; + inline constexpr char dentalOff[] = "\xef\x84\x90"; + inline constexpr char deselect[] = "\xef\xa7\xb3"; + inline constexpr char desk[] = "\xef\xb4\xb5"; + inline constexpr char details[] = "\xee\xb9\xb1"; + inline constexpr char detailsOff[] = "\xef\x8f\xa2"; + inline constexpr char device3dCamera[] = "\xf0\x90\x88\xad"; + inline constexpr char device3dLens[] = "\xf0\x90\x88\xac"; + inline constexpr char deviceAirpods[] = "\xef\x96\xa9"; + inline constexpr char deviceAirpodsCase[] = "\xef\x99\x86"; + inline constexpr char deviceAirtag[] = "\xef\xab\xa6"; + inline constexpr char deviceAnalytics[] = "\xee\xb9\xb2"; + inline constexpr char deviceAudioTape[] = "\xee\xb9\xb3"; + inline constexpr char deviceCameraPhone[] = "\xef\x88\xb3"; + inline constexpr char deviceCctv[] = "\xee\xb9\xb4"; + inline constexpr char deviceCctvOff[] = "\xef\x8f\xa3"; + inline constexpr char deviceComputerCamera[] = "\xee\xb9\xb6"; + inline constexpr char deviceComputerCamera2[] = "\xf0\x90\x88\xbc"; + inline constexpr char deviceComputerCameraOff[] = "\xee\xb9\xb5"; + inline constexpr char deviceDesktop[] = "\xee\xaa\x89"; + inline constexpr char deviceDesktopAnalytics[] = "\xee\xb9\xb7"; + inline constexpr char deviceDesktopBolt[] = "\xef\xa1\x9e"; + inline constexpr char deviceDesktopCancel[] = "\xef\xa1\x9f"; + inline constexpr char deviceDesktopCheck[] = "\xef\xa1\xa0"; + inline constexpr char deviceDesktopCode[] = "\xef\xa1\xa1"; + inline constexpr char deviceDesktopCog[] = "\xef\xa1\xa2"; + inline constexpr char deviceDesktopDollar[] = "\xef\xa1\xa3"; + inline constexpr char deviceDesktopDown[] = "\xef\xa1\xa4"; + inline constexpr char deviceDesktopExclamation[] = "\xef\xa1\xa5"; + inline constexpr char deviceDesktopHeart[] = "\xef\xa1\xa6"; + inline constexpr char deviceDesktopMinus[] = "\xef\xa1\xa7"; + inline constexpr char deviceDesktopOff[] = "\xee\xb9\xb8"; + inline constexpr char deviceDesktopPause[] = "\xef\xa1\xa8"; + inline constexpr char deviceDesktopPin[] = "\xef\xa1\xa9"; + inline constexpr char deviceDesktopPlus[] = "\xef\xa1\xaa"; + inline constexpr char deviceDesktopQuestion[] = "\xef\xa1\xab"; + inline constexpr char deviceDesktopSearch[] = "\xef\xa1\xac"; + inline constexpr char deviceDesktopShare[] = "\xef\xa1\xad"; + inline constexpr char deviceDesktopStar[] = "\xef\xa1\xae"; + inline constexpr char deviceDesktopUp[] = "\xef\xa1\xaf"; + inline constexpr char deviceDesktopX[] = "\xef\xa1\xb0"; + inline constexpr char deviceFloppy[] = "\xee\xad\xa2"; + inline constexpr char deviceGamepad[] = "\xee\xad\xa3"; + inline constexpr char deviceGamepad2[] = "\xef\x87\x92"; + inline constexpr char deviceGamepad3[] = "\xef\xb1\x98"; + inline constexpr char deviceHeartMonitor[] = "\xef\x81\xa0"; + inline constexpr char deviceImac[] = "\xef\x9e\xa7"; + inline constexpr char deviceImacBolt[] = "\xef\xa1\xb1"; + inline constexpr char deviceImacCancel[] = "\xef\xa1\xb2"; + inline constexpr char deviceImacCheck[] = "\xef\xa1\xb3"; + inline constexpr char deviceImacCode[] = "\xef\xa1\xb4"; + inline constexpr char deviceImacCog[] = "\xef\xa1\xb5"; + inline constexpr char deviceImacDollar[] = "\xef\xa1\xb6"; + inline constexpr char deviceImacDown[] = "\xef\xa1\xb7"; + inline constexpr char deviceImacExclamation[] = "\xef\xa1\xb8"; + inline constexpr char deviceImacHeart[] = "\xef\xa1\xb9"; + inline constexpr char deviceImacMinus[] = "\xef\xa1\xba"; + inline constexpr char deviceImacOff[] = "\xef\xa1\xbb"; + inline constexpr char deviceImacPause[] = "\xef\xa1\xbc"; + inline constexpr char deviceImacPin[] = "\xef\xa1\xbd"; + inline constexpr char deviceImacPlus[] = "\xef\xa1\xbe"; + inline constexpr char deviceImacQuestion[] = "\xef\xa1\xbf"; + inline constexpr char deviceImacSearch[] = "\xef\xa2\x80"; + inline constexpr char deviceImacShare[] = "\xef\xa2\x81"; + inline constexpr char deviceImacStar[] = "\xef\xa2\x82"; + inline constexpr char deviceImacUp[] = "\xef\xa2\x83"; + inline constexpr char deviceImacX[] = "\xef\xa2\x84"; + inline constexpr char deviceIpad[] = "\xef\x99\x88"; + inline constexpr char deviceIpadBolt[] = "\xef\xa2\x85"; + inline constexpr char deviceIpadCancel[] = "\xef\xa2\x86"; + inline constexpr char deviceIpadCheck[] = "\xef\xa2\x87"; + inline constexpr char deviceIpadCode[] = "\xef\xa2\x88"; + inline constexpr char deviceIpadCog[] = "\xef\xa2\x89"; + inline constexpr char deviceIpadDollar[] = "\xef\xa2\x8a"; + inline constexpr char deviceIpadDown[] = "\xef\xa2\x8b"; + inline constexpr char deviceIpadExclamation[] = "\xef\xa2\x8c"; + inline constexpr char deviceIpadHeart[] = "\xef\xa2\x8d"; + inline constexpr char deviceIpadHorizontal[] = "\xef\x99\x87"; + inline constexpr char deviceIpadHorizontalBolt[] = "\xef\xa2\x8e"; + inline constexpr char deviceIpadHorizontalCancel[] = "\xef\xa2\x8f"; + inline constexpr char deviceIpadHorizontalCheck[] = "\xef\xa2\x90"; + inline constexpr char deviceIpadHorizontalCode[] = "\xef\xa2\x91"; + inline constexpr char deviceIpadHorizontalCog[] = "\xef\xa2\x92"; + inline constexpr char deviceIpadHorizontalDollar[] = "\xef\xa2\x93"; + inline constexpr char deviceIpadHorizontalDown[] = "\xef\xa2\x94"; + inline constexpr char deviceIpadHorizontalExclamation[] = "\xef\xa2\x95"; + inline constexpr char deviceIpadHorizontalHeart[] = "\xef\xa2\x96"; + inline constexpr char deviceIpadHorizontalMinus[] = "\xef\xa2\x97"; + inline constexpr char deviceIpadHorizontalOff[] = "\xef\xa2\x98"; + inline constexpr char deviceIpadHorizontalPause[] = "\xef\xa2\x99"; + inline constexpr char deviceIpadHorizontalPin[] = "\xef\xa2\x9a"; + inline constexpr char deviceIpadHorizontalPlus[] = "\xef\xa2\x9b"; + inline constexpr char deviceIpadHorizontalQuestion[] = "\xef\xa2\x9c"; + inline constexpr char deviceIpadHorizontalSearch[] = "\xef\xa2\x9d"; + inline constexpr char deviceIpadHorizontalShare[] = "\xef\xa2\x9e"; + inline constexpr char deviceIpadHorizontalStar[] = "\xef\xa2\x9f"; + inline constexpr char deviceIpadHorizontalUp[] = "\xef\xa2\xa0"; + inline constexpr char deviceIpadHorizontalX[] = "\xef\xa2\xa1"; + inline constexpr char deviceIpadMinus[] = "\xef\xa2\xa2"; + inline constexpr char deviceIpadOff[] = "\xef\xa2\xa3"; + inline constexpr char deviceIpadPause[] = "\xef\xa2\xa4"; + inline constexpr char deviceIpadPin[] = "\xef\xa2\xa5"; + inline constexpr char deviceIpadPlus[] = "\xef\xa2\xa6"; + inline constexpr char deviceIpadQuestion[] = "\xef\xa2\xa7"; + inline constexpr char deviceIpadSearch[] = "\xef\xa2\xa8"; + inline constexpr char deviceIpadShare[] = "\xef\xa2\xa9"; + inline constexpr char deviceIpadStar[] = "\xef\xa2\xaa"; + inline constexpr char deviceIpadUp[] = "\xef\xa2\xab"; + inline constexpr char deviceIpadX[] = "\xef\xa2\xac"; + inline constexpr char deviceLandlinePhone[] = "\xef\x99\x89"; + inline constexpr char deviceLaptop[] = "\xee\xad\xa4"; + inline constexpr char deviceLaptopOff[] = "\xef\x81\xa1"; + inline constexpr char deviceMobile[] = "\xee\xaa\x8a"; + inline constexpr char deviceMobileBolt[] = "\xef\xa2\xad"; + inline constexpr char deviceMobileCancel[] = "\xef\xa2\xae"; + inline constexpr char deviceMobileCharging[] = "\xef\x88\xa4"; + inline constexpr char deviceMobileCheck[] = "\xef\xa2\xaf"; + inline constexpr char deviceMobileCode[] = "\xef\xa2\xb0"; + inline constexpr char deviceMobileCog[] = "\xef\xa2\xb1"; + inline constexpr char deviceMobileDollar[] = "\xef\xa2\xb2"; + inline constexpr char deviceMobileDown[] = "\xef\xa2\xb3"; + inline constexpr char deviceMobileExclamation[] = "\xef\xa2\xb4"; + inline constexpr char deviceMobileHeart[] = "\xef\xa2\xb5"; + inline constexpr char deviceMobileMessage[] = "\xee\xb9\xb9"; + inline constexpr char deviceMobileMinus[] = "\xef\xa2\xb6"; + inline constexpr char deviceMobileOff[] = "\xef\x81\xa2"; + inline constexpr char deviceMobilePause[] = "\xef\xa2\xb7"; + inline constexpr char deviceMobilePin[] = "\xef\xa2\xb8"; + inline constexpr char deviceMobilePlus[] = "\xef\xa2\xb9"; + inline constexpr char deviceMobileQuestion[] = "\xef\xa2\xba"; + inline constexpr char deviceMobileRotated[] = "\xee\xb3\x9b"; + inline constexpr char deviceMobileSearch[] = "\xef\xa2\xbb"; + inline constexpr char deviceMobileShare[] = "\xef\xa2\xbc"; + inline constexpr char deviceMobileStar[] = "\xef\xa2\xbd"; + inline constexpr char deviceMobileUp[] = "\xef\xa2\xbe"; + inline constexpr char deviceMobileVibration[] = "\xee\xae\x86"; + inline constexpr char deviceMobileX[] = "\xef\xa2\xbf"; + inline constexpr char deviceNintendo[] = "\xef\x80\xa6"; + inline constexpr char deviceNintendoOff[] = "\xef\x84\x91"; + inline constexpr char deviceProjector[] = "\xef\xb0\x91"; + inline constexpr char deviceRemote[] = "\xef\x9e\x92"; + inline constexpr char deviceScreen[] = "\xf0\x90\x88\xab"; + inline constexpr char deviceSdCard[] = "\xef\x8e\x84"; + inline constexpr char deviceSim[] = "\xef\x92\xb2"; + inline constexpr char deviceSim1[] = "\xef\x92\xaf"; + inline constexpr char deviceSim2[] = "\xef\x92\xb0"; + inline constexpr char deviceSim3[] = "\xef\x92\xb1"; + inline constexpr char deviceSpeaker[] = "\xee\xaa\x8b"; + inline constexpr char deviceSpeakerOff[] = "\xef\x84\x92"; + inline constexpr char deviceTablet[] = "\xee\xaa\x8c"; + inline constexpr char deviceTabletBolt[] = "\xef\xa3\x80"; + inline constexpr char deviceTabletCancel[] = "\xef\xa3\x81"; + inline constexpr char deviceTabletCheck[] = "\xef\xa3\x82"; + inline constexpr char deviceTabletCode[] = "\xef\xa3\x83"; + inline constexpr char deviceTabletCog[] = "\xef\xa3\x84"; + inline constexpr char deviceTabletDollar[] = "\xef\xa3\x85"; + inline constexpr char deviceTabletDown[] = "\xef\xa3\x86"; + inline constexpr char deviceTabletExclamation[] = "\xef\xa3\x87"; + inline constexpr char deviceTabletHeart[] = "\xef\xa3\x88"; + inline constexpr char deviceTabletMinus[] = "\xef\xa3\x89"; + inline constexpr char deviceTabletOff[] = "\xef\x81\xa3"; + inline constexpr char deviceTabletPause[] = "\xef\xa3\x8a"; + inline constexpr char deviceTabletPin[] = "\xef\xa3\x8b"; + inline constexpr char deviceTabletPlus[] = "\xef\xa3\x8c"; + inline constexpr char deviceTabletQuestion[] = "\xef\xa3\x8d"; + inline constexpr char deviceTabletSearch[] = "\xef\xa3\x8e"; + inline constexpr char deviceTabletShare[] = "\xef\xa3\x8f"; + inline constexpr char deviceTabletStar[] = "\xef\xa3\x90"; + inline constexpr char deviceTabletUp[] = "\xef\xa3\x91"; + inline constexpr char deviceTabletX[] = "\xef\xa3\x92"; + inline constexpr char deviceTv[] = "\xee\xaa\x8d"; + inline constexpr char deviceTvOff[] = "\xef\x81\xa4"; + inline constexpr char deviceTvOld[] = "\xef\x87\x93"; + inline constexpr char deviceUnknown[] = "\xef\xbb\xb4"; + inline constexpr char deviceUsb[] = "\xef\xb1\x99"; + inline constexpr char deviceVisionPro[] = "\xef\xab\xa7"; + inline constexpr char deviceVisionProWifi[] = "\xf0\x90\x89\xb4"; + inline constexpr char deviceWatch[] = "\xee\xaf\xb9"; + inline constexpr char deviceWatchBolt[] = "\xef\xa3\x93"; + inline constexpr char deviceWatchCancel[] = "\xef\xa3\x94"; + inline constexpr char deviceWatchCheck[] = "\xef\xa3\x95"; + inline constexpr char deviceWatchCode[] = "\xef\xa3\x96"; + inline constexpr char deviceWatchCog[] = "\xef\xa3\x97"; + inline constexpr char deviceWatchDollar[] = "\xef\xa3\x98"; + inline constexpr char deviceWatchDown[] = "\xef\xa3\x99"; + inline constexpr char deviceWatchExclamation[] = "\xef\xa3\x9a"; + inline constexpr char deviceWatchHeart[] = "\xef\xa3\x9b"; + inline constexpr char deviceWatchMinus[] = "\xef\xa3\x9c"; + inline constexpr char deviceWatchOff[] = "\xef\x81\xa5"; + inline constexpr char deviceWatchPause[] = "\xef\xa3\x9d"; + inline constexpr char deviceWatchPin[] = "\xef\xa3\x9e"; + inline constexpr char deviceWatchPlus[] = "\xef\xa3\x9f"; + inline constexpr char deviceWatchQuestion[] = "\xef\xa3\xa0"; + inline constexpr char deviceWatchSearch[] = "\xef\xa3\xa1"; + inline constexpr char deviceWatchShare[] = "\xef\xa3\xa2"; + inline constexpr char deviceWatchStar[] = "\xef\xa3\xa3"; + inline constexpr char deviceWatchStats[] = "\xee\xbd\xbd"; + inline constexpr char deviceWatchStats2[] = "\xee\xbd\xbc"; + inline constexpr char deviceWatchUp[] = "\xef\xa3\xa4"; + inline constexpr char deviceWatchX[] = "\xef\xa3\xa5"; + inline constexpr char deviceWorkstation[] = "\xf0\x90\x89\xb3"; + inline constexpr char devices[] = "\xee\xae\x87"; + inline constexpr char devices2[] = "\xee\xb4\xa9"; + inline constexpr char devicesBolt[] = "\xef\xa3\xa6"; + inline constexpr char devicesCancel[] = "\xef\xa3\xa7"; + inline constexpr char devicesCheck[] = "\xef\xa3\xa8"; + inline constexpr char devicesCode[] = "\xef\xa3\xa9"; + inline constexpr char devicesCog[] = "\xef\xa3\xaa"; + inline constexpr char devicesDollar[] = "\xef\xa3\xab"; + inline constexpr char devicesDown[] = "\xef\xa3\xac"; + inline constexpr char devicesExclamation[] = "\xef\xa3\xad"; + inline constexpr char devicesHeart[] = "\xef\xa3\xae"; + inline constexpr char devicesMinus[] = "\xef\xa3\xaf"; + inline constexpr char devicesOff[] = "\xef\x8f\xa4"; + inline constexpr char devicesPause[] = "\xef\xa3\xb0"; + inline constexpr char devicesPc[] = "\xee\xb9\xba"; + inline constexpr char devicesPcOff[] = "\xef\x84\x93"; + inline constexpr char devicesPin[] = "\xef\xa3\xb1"; + inline constexpr char devicesPlus[] = "\xef\xa3\xb2"; + inline constexpr char devicesQuestion[] = "\xef\xa3\xb3"; + inline constexpr char devicesSearch[] = "\xef\xa3\xb4"; + inline constexpr char devicesShare[] = "\xef\xa3\xb5"; + inline constexpr char devicesStar[] = "\xef\xa3\xb6"; + inline constexpr char devicesUp[] = "\xef\xa3\xb7"; + inline constexpr char devicesX[] = "\xef\xa3\xb8"; + inline constexpr char diabolo[] = "\xef\xaa\x9c"; + inline constexpr char diaboloOff[] = "\xef\xaa\x9a"; + inline constexpr char diaboloPlus[] = "\xef\xaa\x9b"; + inline constexpr char dialpad[] = "\xef\x81\xa7"; + inline constexpr char dialpadOff[] = "\xef\x84\x94"; + inline constexpr char diamond[] = "\xee\xad\xa5"; + inline constexpr char diamondOff[] = "\xef\x84\x95"; + inline constexpr char diamonds[] = "\xee\xbf\xb5"; + inline constexpr char diaper[] = "\xef\xbe\xa2"; + inline constexpr char dice[] = "\xee\xad\xa6"; + inline constexpr char dice1[] = "\xef\x82\x8b"; + inline constexpr char dice2[] = "\xef\x82\x8c"; + inline constexpr char dice3[] = "\xef\x82\x8d"; + inline constexpr char dice4[] = "\xef\x82\x8e"; + inline constexpr char dice5[] = "\xef\x82\x8f"; + inline constexpr char dice6[] = "\xef\x82\x90"; + inline constexpr char dimensions[] = "\xee\xb9\xbb"; + inline constexpr char direction[] = "\xee\xaf\xbb"; + inline constexpr char directionArrows[] = "\xef\xb4\xb6"; + inline constexpr char directionHorizontal[] = "\xee\xaf\xba"; + inline constexpr char directionSign[] = "\xef\x87\xb7"; + inline constexpr char directionSignOff[] = "\xef\x8f\xa5"; + inline constexpr char directions[] = "\xee\xaa\x8e"; + inline constexpr char directionsOff[] = "\xef\x84\x96"; + inline constexpr char disabled[] = "\xee\xaa\x8f"; + inline constexpr char disabled2[] = "\xee\xae\xaf"; + inline constexpr char disabledOff[] = "\xef\x84\x97"; + inline constexpr char disc[] = "\xee\xaa\x90"; + inline constexpr char discGolf[] = "\xef\x8e\x85"; + inline constexpr char discOff[] = "\xef\x84\x98"; + inline constexpr char discount[] = "\xee\xae\xbd"; + inline constexpr char discountOff[] = "\xef\x8f\xa7"; + inline constexpr char divide[] = "\xee\xb5\x9c"; + inline constexpr char dna[] = "\xee\xb9\xbd"; + inline constexpr char dna2[] = "\xee\xbd\x9c"; + inline constexpr char dna2Off[] = "\xef\x84\x99"; + inline constexpr char dnaOff[] = "\xef\x84\x9a"; + inline constexpr char dog[] = "\xef\x99\xa0"; + inline constexpr char dogBowl[] = "\xee\xbc\xa9"; + inline constexpr char door[] = "\xee\xbd\x8e"; + inline constexpr char doorEnter[] = "\xee\xbd\x8c"; + inline constexpr char doorExit[] = "\xee\xbd\x8d"; + inline constexpr char doorHanger[] = "\xf0\x90\x88\xbb"; + inline constexpr char doorOff[] = "\xef\x84\x9b"; + inline constexpr char dots[] = "\xee\xaa\x95"; + inline constexpr char dotsCircleHorizontal[] = "\xee\xaa\x91"; + inline constexpr char dotsDiagonal[] = "\xee\xaa\x93"; + inline constexpr char dotsDiagonal2[] = "\xee\xaa\x92"; + inline constexpr char dotsVertical[] = "\xee\xaa\x94"; + inline constexpr char download[] = "\xee\xaa\x96"; + inline constexpr char downloadOff[] = "\xef\x84\x9c"; + inline constexpr char dragDrop[] = "\xee\xae\x89"; + inline constexpr char dragDrop2[] = "\xee\xae\x88"; + inline constexpr char dragon[] = "\xf0\x90\x89\xb2"; + inline constexpr char drone[] = "\xee\xb5\xb9"; + inline constexpr char droneOff[] = "\xee\xb9\xbe"; + inline constexpr char dropCircle[] = "\xee\xbf\x9e"; + inline constexpr char droplet[] = "\xee\xaa\x97"; + inline constexpr char dropletBolt[] = "\xef\xa3\xb9"; + inline constexpr char dropletCancel[] = "\xef\xa3\xba"; + inline constexpr char dropletCheck[] = "\xef\xa3\xbb"; + inline constexpr char dropletCode[] = "\xef\xa3\xbc"; + inline constexpr char dropletCog[] = "\xef\xa3\xbd"; + inline constexpr char dropletDollar[] = "\xef\xa3\xbe"; + inline constexpr char dropletDown[] = "\xef\xa3\xbf"; + inline constexpr char dropletExclamation[] = "\xef\xa4\x80"; + inline constexpr char dropletHalf[] = "\xee\xba\x82"; + inline constexpr char dropletHalf2[] = "\xee\xba\x81"; + inline constexpr char dropletHeart[] = "\xef\xa4\x81"; + inline constexpr char dropletMinus[] = "\xef\xa4\x82"; + inline constexpr char dropletOff[] = "\xee\xba\x83"; + inline constexpr char dropletPause[] = "\xef\xa4\x83"; + inline constexpr char dropletPin[] = "\xef\xa4\x84"; + inline constexpr char dropletPlus[] = "\xef\xa4\x85"; + inline constexpr char dropletQuestion[] = "\xef\xa4\x86"; + inline constexpr char dropletSearch[] = "\xef\xa4\x87"; + inline constexpr char dropletShare[] = "\xef\xa4\x88"; + inline constexpr char dropletStar[] = "\xef\xa4\x89"; + inline constexpr char dropletUp[] = "\xef\xa4\x8a"; + inline constexpr char dropletX[] = "\xef\xa4\x8b"; + inline constexpr char droplets[] = "\xef\xb0\x92"; + inline constexpr char dualScreen[] = "\xef\xa9\x99"; + inline constexpr char dumbbell[] = "\xf0\x90\x89\x8d"; + inline constexpr char dumpling[] = "\xef\xba\xb5"; + inline constexpr char ePassport[] = "\xef\x93\x9f"; + inline constexpr char ear[] = "\xee\xaf\x8e"; + inline constexpr char earOff[] = "\xee\xba\x84"; + inline constexpr char earScan[] = "\xef\xb5\x97"; + inline constexpr char earphoneBluetooth[] = "\xf0\x90\x88\xba"; + inline constexpr char easeIn[] = "\xef\x95\xb3"; + inline constexpr char easeInControlPoint[] = "\xef\x95\xb0"; + inline constexpr char easeInOut[] = "\xef\x95\xb2"; + inline constexpr char easeInOutControlPoints[] = "\xef\x95\xb1"; + inline constexpr char easeOut[] = "\xef\x95\xb5"; + inline constexpr char easeOutControlPoint[] = "\xef\x95\xb4"; + inline constexpr char edit[] = "\xee\xaa\x98"; + inline constexpr char editCircle[] = "\xee\xba\x85"; + inline constexpr char editCircleOff[] = "\xef\x84\x9d"; + inline constexpr char editOff[] = "\xef\x84\x9e"; + inline constexpr char egg[] = "\xee\xae\x8a"; + inline constexpr char eggCracked[] = "\xef\x8b\x96"; + inline constexpr char eggFried[] = "\xef\x8e\x86"; + inline constexpr char eggOff[] = "\xef\x84\x9f"; + inline constexpr char eggs[] = "\xef\x94\x80"; + inline constexpr char elevator[] = "\xee\xbf\x9f"; + inline constexpr char elevatorOff[] = "\xef\x8f\xa8"; + inline constexpr char emailStamp[] = "\xf0\x90\x89\xa6"; + inline constexpr char emergencyBed[] = "\xee\xbd\x9d"; + inline constexpr char empathize[] = "\xef\x8a\x9b"; + inline constexpr char empathizeOff[] = "\xef\x8f\xa9"; + inline constexpr char emphasis[] = "\xee\xaf\x8f"; + inline constexpr char engine[] = "\xee\xbd\xbe"; + inline constexpr char engineOff[] = "\xef\x84\xa0"; + inline constexpr char equal[] = "\xee\xba\x87"; + inline constexpr char equalDouble[] = "\xef\x93\xa1"; + inline constexpr char equalNot[] = "\xee\xba\x86"; + inline constexpr char eraser[] = "\xee\xae\x8b"; + inline constexpr char eraserOff[] = "\xef\x84\xa1"; + inline constexpr char error404[] = "\xef\x80\xa7"; + inline constexpr char error404Off[] = "\xef\x84\xa2"; + inline constexpr char escalator[] = "\xef\xac\x86"; + inline constexpr char escalatorDown[] = "\xef\xac\x84"; + inline constexpr char escalatorUp[] = "\xef\xac\x85"; + inline constexpr char exchange[] = "\xee\xaf\xa7"; + inline constexpr char exchangeOff[] = "\xef\x84\xa3"; + inline constexpr char exclamationCircle[] = "\xef\x98\xb4"; + inline constexpr char exclamationMark[] = "\xee\xbe\xb4"; + inline constexpr char exclamationMarkOff[] = "\xef\x84\xa4"; + inline constexpr char exerciseBall[] = "\xf0\x90\x89\x8c"; + inline constexpr char explicitIcon[] = "\xef\x89\x96"; + inline constexpr char explicitOff[] = "\xef\x8f\xaa"; + inline constexpr char exposure[] = "\xee\xae\x8c"; + inline constexpr char exposure0[] = "\xef\x8a\x9c"; + inline constexpr char exposureMinus1[] = "\xef\x8a\x9d"; + inline constexpr char exposureMinus2[] = "\xef\x8a\x9e"; + inline constexpr char exposureOff[] = "\xef\x8f\xab"; + inline constexpr char exposurePlus1[] = "\xef\x8a\x9f"; + inline constexpr char exposurePlus2[] = "\xef\x8a\xa0"; + inline constexpr char externalLink[] = "\xee\xaa\x99"; + inline constexpr char externalLinkOff[] = "\xef\x84\xa5"; + inline constexpr char eye[] = "\xee\xaa\x9a"; + inline constexpr char eyeBitcoin[] = "\xef\xbc\xbd"; + inline constexpr char eyeBolt[] = "\xef\xad\xad"; + inline constexpr char eyeCancel[] = "\xef\xad\xae"; + inline constexpr char eyeCheck[] = "\xee\xba\x88"; + inline constexpr char eyeClosed[] = "\xef\x9f\xac"; + inline constexpr char eyeCode[] = "\xef\xad\xaf"; + inline constexpr char eyeCog[] = "\xef\x9f\xad"; + inline constexpr char eyeDiscount[] = "\xef\xad\xb0"; + inline constexpr char eyeDollar[] = "\xef\xad\xb1"; + inline constexpr char eyeDotted[] = "\xef\xba\xad"; + inline constexpr char eyeDown[] = "\xef\xad\xb2"; + inline constexpr char eyeEdit[] = "\xef\x9f\xae"; + inline constexpr char eyeExclamation[] = "\xef\x9f\xaf"; + inline constexpr char eyeHeart[] = "\xef\x9f\xb0"; + inline constexpr char eyeMinus[] = "\xef\xad\xb3"; + inline constexpr char eyeOff[] = "\xee\xb3\xb0"; + inline constexpr char eyePause[] = "\xef\xad\xb4"; + inline constexpr char eyePin[] = "\xef\xad\xb5"; + inline constexpr char eyePlus[] = "\xef\xad\xb6"; + inline constexpr char eyeQuestion[] = "\xef\xad\xb7"; + inline constexpr char eyeSearch[] = "\xef\xad\xb8"; + inline constexpr char eyeShare[] = "\xef\xad\xb9"; + inline constexpr char eyeSpark[] = "\xef\xbe\xba"; + inline constexpr char eyeStar[] = "\xef\xad\xba"; + inline constexpr char eyeTable[] = "\xee\xbd\x9e"; + inline constexpr char eyeUp[] = "\xef\xad\xbb"; + inline constexpr char eyeX[] = "\xef\x9f\xb1"; + inline constexpr char eyeglass[] = "\xee\xba\x8a"; + inline constexpr char eyeglass2[] = "\xee\xba\x89"; + inline constexpr char eyeglassOff[] = "\xef\x84\xa6"; + inline constexpr char faceId[] = "\xee\xaa\x9b"; + inline constexpr char faceIdError[] = "\xee\xbe\xa7"; + inline constexpr char faceMask[] = "\xee\xbe\xb5"; + inline constexpr char faceMaskOff[] = "\xef\x84\xa7"; + inline constexpr char fall[] = "\xee\xb2\xb9"; + inline constexpr char favicon[] = "\xef\xb5\xa5"; + inline constexpr char feather[] = "\xee\xba\x8b"; + inline constexpr char featherOff[] = "\xef\x84\xa8"; + inline constexpr char fence[] = "\xee\xbc\xaa"; + inline constexpr char fenceOff[] = "\xef\x84\xa9"; + inline constexpr char ferry[] = "\xf0\x90\x81\xb4"; + inline constexpr char fidgetSpinner[] = "\xef\x81\xa8"; + inline constexpr char file[] = "\xee\xaa\xa4"; + inline constexpr char file3d[] = "\xef\x80\xb2"; + inline constexpr char fileAi[] = "\xef\xbe\xa1"; + inline constexpr char fileAlert[] = "\xee\xb7\xa6"; + inline constexpr char fileAnalytics[] = "\xee\xb7\xa7"; + inline constexpr char fileArrowLeft[] = "\xef\x80\xb3"; + inline constexpr char fileArrowRight[] = "\xef\x80\xb4"; + inline constexpr char fileBarcode[] = "\xef\x80\xb5"; + inline constexpr char fileBitcoin[] = "\xef\xbe\xa0"; + inline constexpr char fileBroken[] = "\xef\x94\x81"; + inline constexpr char fileCertificate[] = "\xee\xb5\x8d"; + inline constexpr char fileChart[] = "\xef\x80\xb6"; + inline constexpr char fileCheck[] = "\xee\xaa\x9c"; + inline constexpr char fileCode[] = "\xee\xaf\x90"; + inline constexpr char fileCode2[] = "\xee\xb7\xa8"; + inline constexpr char fileCv[] = "\xef\xa9\x9a"; + inline constexpr char fileDatabase[] = "\xef\x80\xb7"; + inline constexpr char fileDelta[] = "\xef\x94\xbd"; + inline constexpr char fileDescription[] = "\xef\x80\xa8"; + inline constexpr char fileDiff[] = "\xee\xb3\xb1"; + inline constexpr char fileDigit[] = "\xee\xbe\xa8"; + inline constexpr char fileDislike[] = "\xee\xb4\xaa"; + inline constexpr char fileDollar[] = "\xee\xbf\xa0"; + inline constexpr char fileDots[] = "\xef\x80\xb8"; + inline constexpr char fileDownload[] = "\xee\xaa\x9d"; + inline constexpr char fileEuro[] = "\xee\xbf\xa1"; + inline constexpr char fileExcel[] = "\xef\xbb\xb3"; + inline constexpr char fileExport[] = "\xee\xb7\xa9"; + inline constexpr char fileFunction[] = "\xef\x94\xbe"; + inline constexpr char fileHorizontal[] = "\xee\xae\xb0"; + inline constexpr char fileImport[] = "\xee\xb7\xaa"; + inline constexpr char fileInfinity[] = "\xef\x94\x82"; + inline constexpr char fileInfo[] = "\xee\xb7\xac"; + inline constexpr char fileInvoice[] = "\xee\xad\xa7"; + inline constexpr char fileIsr[] = "\xef\xba\xac"; + inline constexpr char fileLambda[] = "\xef\x94\xbf"; + inline constexpr char fileLike[] = "\xee\xb4\xab"; + inline constexpr char fileMinus[] = "\xee\xaa\x9e"; + inline constexpr char fileMusic[] = "\xee\xaa\x9f"; + inline constexpr char fileNeutral[] = "\xef\xb4\xa2"; + inline constexpr char fileOff[] = "\xee\xb3\xb2"; + inline constexpr char fileOrientation[] = "\xef\x8a\xa1"; + inline constexpr char filePencil[] = "\xef\x80\xb9"; + inline constexpr char filePercent[] = "\xef\x95\x80"; + inline constexpr char filePhone[] = "\xee\xb3\x9c"; + inline constexpr char filePlus[] = "\xee\xaa\xa0"; + inline constexpr char filePower[] = "\xef\x80\xba"; + inline constexpr char fileReport[] = "\xee\xb7\xad"; + inline constexpr char fileRss[] = "\xef\x80\xbb"; + inline constexpr char fileSad[] = "\xef\xb4\xa3"; + inline constexpr char fileScissors[] = "\xef\x80\xbc"; + inline constexpr char fileSearch[] = "\xee\xb5\x9d"; + inline constexpr char fileSettings[] = "\xef\x80\xa9"; + inline constexpr char fileShredder[] = "\xee\xaa\xa1"; + inline constexpr char fileSignal[] = "\xef\x80\xbd"; + inline constexpr char fileSmile[] = "\xef\xb4\xa4"; + inline constexpr char fileSpark[] = "\xef\xbe\xb9"; + inline constexpr char fileSpreadsheet[] = "\xef\x80\xbe"; + inline constexpr char fileStack[] = "\xef\x94\x83"; + inline constexpr char fileStar[] = "\xef\x80\xbf"; + inline constexpr char fileSymlink[] = "\xee\xb5\x93"; + inline constexpr char fileText[] = "\xee\xaa\xa2"; + inline constexpr char fileTextAi[] = "\xef\xa8\xa7"; + inline constexpr char fileTextShield[] = "\xf0\x90\x83\xb2"; + inline constexpr char fileTextSpark[] = "\xef\xbe\xb8"; + inline constexpr char fileTime[] = "\xef\x81\x80"; + inline constexpr char fileTypeBmp[] = "\xef\xac\x87"; + inline constexpr char fileTypeCss[] = "\xef\xac\x88"; + inline constexpr char fileTypeCsv[] = "\xef\xac\x89"; + inline constexpr char fileTypeDoc[] = "\xef\xac\x8a"; + inline constexpr char fileTypeDocx[] = "\xef\xac\x8b"; + inline constexpr char fileTypeHtml[] = "\xef\xac\x8c"; + inline constexpr char fileTypeJpg[] = "\xef\xac\x8d"; + inline constexpr char fileTypeJs[] = "\xef\xac\x8e"; + inline constexpr char fileTypeJsx[] = "\xef\xac\x8f"; + inline constexpr char fileTypePdf[] = "\xef\xac\x90"; + inline constexpr char fileTypePhp[] = "\xef\xac\x91"; + inline constexpr char fileTypePng[] = "\xef\xac\x92"; + inline constexpr char fileTypePpt[] = "\xef\xac\x93"; + inline constexpr char fileTypeRs[] = "\xef\xac\x94"; + inline constexpr char fileTypeSql[] = "\xef\xac\x95"; + inline constexpr char fileTypeSvg[] = "\xef\xac\x96"; + inline constexpr char fileTypeTs[] = "\xef\xac\x97"; + inline constexpr char fileTypeTsx[] = "\xef\xac\x98"; + inline constexpr char fileTypeTxt[] = "\xef\xac\x99"; + inline constexpr char fileTypeVue[] = "\xef\xac\x9a"; + inline constexpr char fileTypeXls[] = "\xef\xac\x9b"; + inline constexpr char fileTypeXml[] = "\xef\xac\x9c"; + inline constexpr char fileTypeZip[] = "\xef\xac\x9d"; + inline constexpr char fileTypography[] = "\xef\x81\x81"; + inline constexpr char fileUnknown[] = "\xef\x81\x82"; + inline constexpr char fileUpload[] = "\xee\xb2\x91"; + inline constexpr char fileVector[] = "\xef\x81\x83"; + inline constexpr char fileWord[] = "\xef\xbb\xb2"; + inline constexpr char fileX[] = "\xee\xaa\xa3"; + inline constexpr char fileZip[] = "\xee\xb5\x8e"; + inline constexpr char files[] = "\xee\xb7\xaf"; + inline constexpr char filesOff[] = "\xee\xb7\xae"; + inline constexpr char filter[] = "\xee\xaa\xa5"; + inline constexpr char filter2[] = "\xf0\x90\x85\x8b"; + inline constexpr char filter2Bolt[] = "\xf0\x90\x85\x9f"; + inline constexpr char filter2Cancel[] = "\xf0\x90\x85\x9e"; + inline constexpr char filter2Check[] = "\xf0\x90\x85\x9d"; + inline constexpr char filter2Code[] = "\xf0\x90\x85\x9c"; + inline constexpr char filter2Cog[] = "\xf0\x90\x85\x9b"; + inline constexpr char filter2Discount[] = "\xf0\x90\x85\x9a"; + inline constexpr char filter2Dollar[] = "\xf0\x90\x85\x99"; + inline constexpr char filter2Down[] = "\xf0\x90\x85\x98"; + inline constexpr char filter2Edit[] = "\xf0\x90\x85\x97"; + inline constexpr char filter2Exclamation[] = "\xf0\x90\x85\x96"; + inline constexpr char filter2Minus[] = "\xf0\x90\x85\x95"; + inline constexpr char filter2Pause[] = "\xf0\x90\x85\x94"; + inline constexpr char filter2Pin[] = "\xf0\x90\x85\x93"; + inline constexpr char filter2Plus[] = "\xf0\x90\x85\x92"; + inline constexpr char filter2Question[] = "\xf0\x90\x85\x91"; + inline constexpr char filter2Search[] = "\xf0\x90\x85\x90"; + inline constexpr char filter2Share[] = "\xf0\x90\x85\x8f"; + inline constexpr char filter2Spark[] = "\xf0\x90\x85\x8e"; + inline constexpr char filter2Up[] = "\xf0\x90\x85\x8d"; + inline constexpr char filter2X[] = "\xf0\x90\x85\x8c"; + inline constexpr char filterBolt[] = "\xef\xad\xbc"; + inline constexpr char filterCancel[] = "\xef\xad\xbd"; + inline constexpr char filterCheck[] = "\xef\xad\xbe"; + inline constexpr char filterCode[] = "\xef\xad\xbf"; + inline constexpr char filterCog[] = "\xef\xa7\xbe"; + inline constexpr char filterDiscount[] = "\xef\xae\x80"; + inline constexpr char filterDollar[] = "\xef\xa7\xbf"; + inline constexpr char filterDown[] = "\xef\xae\x81"; + inline constexpr char filterEdit[] = "\xef\xa8\x80"; + inline constexpr char filterExclamation[] = "\xef\xae\x82"; + inline constexpr char filterHeart[] = "\xef\xae\x83"; + inline constexpr char filterMinus[] = "\xef\xa8\x81"; + inline constexpr char filterOff[] = "\xee\xb4\xac"; + inline constexpr char filterPause[] = "\xef\xae\x84"; + inline constexpr char filterPin[] = "\xef\xae\x85"; + inline constexpr char filterPlus[] = "\xef\xa8\x82"; + inline constexpr char filterQuestion[] = "\xef\xae\x86"; + inline constexpr char filterSearch[] = "\xef\xae\x87"; + inline constexpr char filterShare[] = "\xef\xae\x88"; + inline constexpr char filterSpark[] = "\xf0\x90\x85\x8a"; + inline constexpr char filterStar[] = "\xef\xa8\x83"; + inline constexpr char filterUp[] = "\xef\xae\x89"; + inline constexpr char filterX[] = "\xef\xa8\x84"; + inline constexpr char filters[] = "\xef\x9e\x93"; + inline constexpr char fingerprint[] = "\xee\xaf\x91"; + inline constexpr char fingerprintOff[] = "\xef\x84\xaa"; + inline constexpr char fingerprintScan[] = "\xef\xb2\xb5"; + inline constexpr char fireExtinguisher[] = "\xef\xab\xb6"; + inline constexpr char fireHydrant[] = "\xef\x8e\xa9"; + inline constexpr char fireHydrantOff[] = "\xef\x8f\xac"; + inline constexpr char firetruck[] = "\xee\xaf\xa8"; + inline constexpr char firewallCheck[] = "\xf0\x90\x87\xb1"; + inline constexpr char firewallFlame[] = "\xf0\x90\x87\xb0"; + inline constexpr char firstAidKit[] = "\xee\xbd\x9f"; + inline constexpr char firstAidKitOff[] = "\xef\x8f\xad"; + inline constexpr char fish[] = "\xee\xbc\xab"; + inline constexpr char fishBone[] = "\xef\x8a\x87"; + inline constexpr char fishChristianity[] = "\xef\x96\x8b"; + inline constexpr char fishHook[] = "\xef\x87\xb9"; + inline constexpr char fishHookOff[] = "\xef\x8f\xae"; + inline constexpr char fishOff[] = "\xef\x84\xab"; + inline constexpr char flag[] = "\xee\xaa\xa6"; + inline constexpr char flag2[] = "\xee\xba\x8c"; + inline constexpr char flag2Off[] = "\xef\x84\xac"; + inline constexpr char flag3[] = "\xee\xba\x8d"; + inline constexpr char flagBitcoin[] = "\xef\xbc\xbc"; + inline constexpr char flagBolt[] = "\xef\xae\x8a"; + inline constexpr char flagCancel[] = "\xef\xae\x8b"; + inline constexpr char flagCheck[] = "\xef\xae\x8c"; + inline constexpr char flagCode[] = "\xef\xae\x8d"; + inline constexpr char flagCog[] = "\xef\xae\x8e"; + inline constexpr char flagDiscount[] = "\xef\xae\x8f"; + inline constexpr char flagDollar[] = "\xef\xae\x90"; + inline constexpr char flagDown[] = "\xef\xae\x91"; + inline constexpr char flagExclamation[] = "\xef\xae\x92"; + inline constexpr char flagHeart[] = "\xef\xae\x93"; + inline constexpr char flagMinus[] = "\xef\xae\x94"; + inline constexpr char flagOff[] = "\xef\x84\xad"; + inline constexpr char flagPause[] = "\xef\xae\x95"; + inline constexpr char flagPin[] = "\xef\xae\x96"; + inline constexpr char flagPlus[] = "\xef\xae\x97"; + inline constexpr char flagQuestion[] = "\xef\xae\x98"; + inline constexpr char flagSearch[] = "\xef\xae\x99"; + inline constexpr char flagShare[] = "\xef\xae\x9a"; + inline constexpr char flagSpark[] = "\xef\xbe\xb7"; + inline constexpr char flagStar[] = "\xef\xae\x9b"; + inline constexpr char flagUp[] = "\xef\xae\x9c"; + inline constexpr char flagX[] = "\xef\xae\x9d"; + inline constexpr char flame[] = "\xee\xb0\xac"; + inline constexpr char flameOff[] = "\xef\x84\xae"; + inline constexpr char flare[] = "\xee\xba\x8e"; + inline constexpr char flask[] = "\xee\xaf\x92"; + inline constexpr char flask2[] = "\xee\xbd\xa0"; + inline constexpr char flask2Off[] = "\xef\x84\xaf"; + inline constexpr char flaskOff[] = "\xef\x84\xb0"; + inline constexpr char flipFlops[] = "\xef\x95\xa4"; + inline constexpr char flipHorizontal[] = "\xee\xaa\xa7"; + inline constexpr char flipVertical[] = "\xee\xaa\xa8"; + inline constexpr char floatCenter[] = "\xee\xae\xb1"; + inline constexpr char floatLeft[] = "\xee\xae\xb2"; + inline constexpr char floatNone[] = "\xee\xb4\x93"; + inline constexpr char floatRight[] = "\xee\xae\xb3"; + inline constexpr char flood[] = "\xf0\x90\x89\x8b"; + inline constexpr char flower[] = "\xee\xbf\xb6"; + inline constexpr char flowerOff[] = "\xef\x84\xb1"; + inline constexpr char focus[] = "\xee\xae\x8d"; + inline constexpr char focus2[] = "\xee\xaf\x93"; + inline constexpr char focusAuto[] = "\xef\xa9\xa2"; + inline constexpr char focusCentered[] = "\xef\x80\xaa"; + inline constexpr char fold[] = "\xee\xb5\x96"; + inline constexpr char foldDown[] = "\xee\xb5\x94"; + inline constexpr char foldUp[] = "\xee\xb5\x95"; + inline constexpr char folder[] = "\xee\xaa\xad"; + inline constexpr char folderBolt[] = "\xef\xa4\x8c"; + inline constexpr char folderCancel[] = "\xef\xa4\x8d"; + inline constexpr char folderCheck[] = "\xef\xa4\x8e"; + inline constexpr char folderCode[] = "\xef\xa4\x8f"; + inline constexpr char folderCog[] = "\xef\xa4\x90"; + inline constexpr char folderDollar[] = "\xef\xa4\x91"; + inline constexpr char folderDown[] = "\xef\xa4\x92"; + inline constexpr char folderExclamation[] = "\xef\xa4\x93"; + inline constexpr char folderHeart[] = "\xef\xa4\x94"; + inline constexpr char folderMinus[] = "\xee\xaa\xaa"; + inline constexpr char folderOff[] = "\xee\xb4\x94"; + inline constexpr char folderOpen[] = "\xef\xab\xb7"; + inline constexpr char folderPause[] = "\xef\xa4\x95"; + inline constexpr char folderPin[] = "\xef\xa4\x96"; + inline constexpr char folderPlus[] = "\xee\xaa\xab"; + inline constexpr char folderQuestion[] = "\xef\xa4\x97"; + inline constexpr char folderRoot[] = "\xef\xb5\x83"; + inline constexpr char folderSearch[] = "\xef\xa4\x98"; + inline constexpr char folderShare[] = "\xef\xa4\x99"; + inline constexpr char folderStar[] = "\xef\xa4\x9a"; + inline constexpr char folderSymlink[] = "\xef\xa4\x9b"; + inline constexpr char folderUp[] = "\xef\xa4\x9c"; + inline constexpr char folderX[] = "\xee\xaa\xac"; + inline constexpr char folders[] = "\xee\xaa\xae"; + inline constexpr char foldersOff[] = "\xef\x84\xb3"; + inline constexpr char footsteps[] = "\xf0\x90\x89\xa5"; + inline constexpr char forbid[] = "\xee\xaf\x95"; + inline constexpr char forbid2[] = "\xee\xaf\x94"; + inline constexpr char forklift[] = "\xee\xaf\xa9"; + inline constexpr char forms[] = "\xee\xba\x8f"; + inline constexpr char fountain[] = "\xef\x82\x9b"; + inline constexpr char fountainOff[] = "\xef\x84\xb4"; + inline constexpr char frame[] = "\xee\xaa\xaf"; + inline constexpr char frameOff[] = "\xef\x84\xb5"; + inline constexpr char freeRights[] = "\xee\xbe\xb6"; + inline constexpr char freezeColumn[] = "\xef\xa9\xa3"; + inline constexpr char freezeRow[] = "\xef\xa9\xa5"; + inline constexpr char freezeRowColumn[] = "\xef\xa9\xa4"; + inline constexpr char fridge[] = "\xef\x87\xba"; + inline constexpr char fridgeOff[] = "\xef\x8f\xaf"; + inline constexpr char friends[] = "\xee\xaa\xb0"; + inline constexpr char friendsOff[] = "\xef\x84\xb6"; + inline constexpr char frustum[] = "\xef\xaa\x9f"; + inline constexpr char frustumOff[] = "\xef\xaa\x9d"; + inline constexpr char frustumPlus[] = "\xef\xaa\x9e"; + inline constexpr char function[] = "\xef\x88\xa5"; + inline constexpr char functionOff[] = "\xef\x8f\xb0"; + inline constexpr char galaxy[] = "\xef\xb2\xb6"; + inline constexpr char gardenCart[] = "\xef\x88\xbe"; + inline constexpr char gardenCartOff[] = "\xef\x8f\xb1"; + inline constexpr char gasStation[] = "\xee\xb1\xbd"; + inline constexpr char gasStationOff[] = "\xef\x84\xb7"; + inline constexpr char gauge[] = "\xee\xaa\xb1"; + inline constexpr char gaugeOff[] = "\xef\x84\xb8"; + inline constexpr char gavel[] = "\xee\xbe\x90"; + inline constexpr char genderAgender[] = "\xef\x83\xa1"; + inline constexpr char genderAndrogyne[] = "\xef\x83\xa2"; + inline constexpr char genderBigender[] = "\xef\x83\xa3"; + inline constexpr char genderDemiboy[] = "\xef\x83\xa4"; + inline constexpr char genderDemigirl[] = "\xef\x83\xa5"; + inline constexpr char genderEpicene[] = "\xef\x83\xa6"; + inline constexpr char genderFemale[] = "\xef\x83\xa7"; + inline constexpr char genderFemme[] = "\xef\x83\xa8"; + inline constexpr char genderGenderfluid[] = "\xef\x83\xa9"; + inline constexpr char genderGenderless[] = "\xef\x83\xaa"; + inline constexpr char genderGenderqueer[] = "\xef\x83\xab"; + inline constexpr char genderHermaphrodite[] = "\xef\x83\xac"; + inline constexpr char genderIntergender[] = "\xef\x83\xad"; + inline constexpr char genderMale[] = "\xef\x83\xae"; + inline constexpr char genderNeutrois[] = "\xef\x83\xaf"; + inline constexpr char genderThird[] = "\xef\x83\xb0"; + inline constexpr char genderTransgender[] = "\xef\x83\xb1"; + inline constexpr char genderTravesti[] = "\xef\x83\xb2"; + inline constexpr char geometry[] = "\xee\xba\x90"; + inline constexpr char ghost[] = "\xee\xae\x8e"; + inline constexpr char ghost2[] = "\xef\x95\xbc"; + inline constexpr char ghost3[] = "\xef\xb0\x93"; + inline constexpr char ghostOff[] = "\xef\x8f\xb2"; + inline constexpr char gif[] = "\xef\x89\x97"; + inline constexpr char gift[] = "\xee\xad\xa8"; + inline constexpr char giftCard[] = "\xef\x8e\xaa"; + inline constexpr char giftOff[] = "\xef\x8f\xb3"; + inline constexpr char gitBranch[] = "\xee\xaa\xb2"; + inline constexpr char gitBranchDeleted[] = "\xef\x95\xbd"; + inline constexpr char gitCherryPick[] = "\xef\x95\xbe"; + inline constexpr char gitCommit[] = "\xee\xaa\xb3"; + inline constexpr char gitCompare[] = "\xee\xaa\xb4"; + inline constexpr char gitFork[] = "\xee\xae\x8f"; + inline constexpr char gitMerge[] = "\xee\xaa\xb5"; + inline constexpr char gitPullRequest[] = "\xee\xaa\xb6"; + inline constexpr char gitPullRequestClosed[] = "\xee\xbd\xbf"; + inline constexpr char gitPullRequestConflict[] = "\xf0\x90\x89\xa4"; + inline constexpr char gitPullRequestDraft[] = "\xee\xbe\xb7"; + inline constexpr char gizmo[] = "\xef\x80\xab"; + inline constexpr char glass[] = "\xee\xaa\xb8"; + inline constexpr char glassChampagne[] = "\xef\xb6\x9c"; + inline constexpr char glassCocktail[] = "\xef\xb6\x9d"; + inline constexpr char glassFull[] = "\xee\xaa\xb7"; + inline constexpr char glassGin[] = "\xef\xb6\x9e"; + inline constexpr char glassOff[] = "\xee\xba\x91"; + inline constexpr char globe[] = "\xee\xaa\xb9"; + inline constexpr char globeOff[] = "\xef\x84\xb9"; + inline constexpr char goGame[] = "\xef\x94\x92"; + inline constexpr char golf[] = "\xee\xb6\x8c"; + inline constexpr char golfOff[] = "\xef\x84\xba"; + inline constexpr char gps[] = "\xee\xb5\xba"; + inline constexpr char gradienter[] = "\xef\x8e\xab"; + inline constexpr char grain[] = "\xee\xba\x92"; + inline constexpr char grape[] = "\xf0\x90\x88\xb9"; + inline constexpr char graph[] = "\xef\x8a\x88"; + inline constexpr char graphOff[] = "\xef\x8f\xb4"; + inline constexpr char grave[] = "\xef\x96\x80"; + inline constexpr char grave2[] = "\xef\x95\xbf"; + inline constexpr char grid3x3[] = "\xef\xb2\xa4"; + inline constexpr char grid4x4[] = "\xef\xb2\xa5"; + inline constexpr char gridDots[] = "\xee\xaa\xba"; + inline constexpr char gridGoldenratio[] = "\xef\xb2\xa6"; + inline constexpr char gridPattern[] = "\xee\xbf\x89"; + inline constexpr char gridScan[] = "\xef\xb2\xa7"; + inline constexpr char grill[] = "\xee\xbe\xa9"; + inline constexpr char grillFork[] = "\xef\x8d\x9b"; + inline constexpr char grillOff[] = "\xef\x8f\xb5"; + inline constexpr char grillSpatula[] = "\xef\x8d\x9c"; + inline constexpr char gripHorizontal[] = "\xee\xb0\x80"; + inline constexpr char gripVertical[] = "\xee\xb0\x81"; + inline constexpr char growth[] = "\xee\xba\x93"; + inline constexpr char guitarPick[] = "\xef\x93\x86"; + inline constexpr char gymnastics[] = "\xef\xb5\x84"; + inline constexpr char h1[] = "\xee\xb2\x94"; + inline constexpr char h2[] = "\xee\xb2\x95"; + inline constexpr char h3[] = "\xee\xb2\x96"; + inline constexpr char h4[] = "\xee\xb2\x97"; + inline constexpr char h5[] = "\xee\xb2\x98"; + inline constexpr char h6[] = "\xee\xb2\x99"; + inline constexpr char hammer[] = "\xee\xbe\x91"; + inline constexpr char hammerDrill[] = "\xf0\x90\x88\xb8"; + inline constexpr char hammerOff[] = "\xef\x84\xbc"; + inline constexpr char handClick[] = "\xee\xbd\x8f"; + inline constexpr char handClickOff[] = "\xf0\x90\x83\xb1"; + inline constexpr char handFinger[] = "\xee\xba\x94"; + inline constexpr char handFingerDown[] = "\xef\xbd\x8f"; + inline constexpr char handFingerLeft[] = "\xef\xbd\x8e"; + inline constexpr char handFingerOff[] = "\xef\x84\xbd"; + inline constexpr char handFingerRight[] = "\xef\xbd\x8d"; + inline constexpr char handGrab[] = "\xef\x82\x91"; + inline constexpr char handLittleFinger[] = "\xee\xba\x95"; + inline constexpr char handLoveYou[] = "\xee\xba\x97"; + inline constexpr char handMiddleFinger[] = "\xee\xb0\xad"; + inline constexpr char handMove[] = "\xee\xbd\x90"; + inline constexpr char handOff[] = "\xee\xb4\x95"; + inline constexpr char handRingFinger[] = "\xee\xba\x96"; + inline constexpr char handSanitizer[] = "\xef\x97\xb4"; + inline constexpr char handStop[] = "\xee\xb0\xae"; + inline constexpr char handThreeFingers[] = "\xee\xba\x98"; + inline constexpr char handTwoFingers[] = "\xee\xba\x99"; + inline constexpr char hanger[] = "\xee\xba\x9a"; + inline constexpr char hanger2[] = "\xef\x82\x9c"; + inline constexpr char hangerOff[] = "\xef\x84\xbe"; + inline constexpr char hash[] = "\xee\xaa\xbc"; + inline constexpr char haze[] = "\xee\xbe\xaa"; + inline constexpr char hazeMoon[] = "\xef\xab\xb8"; + inline constexpr char hdr[] = "\xef\xa9\xbb"; + inline constexpr char heading[] = "\xee\xba\x9b"; + inline constexpr char headingOff[] = "\xef\x84\xbf"; + inline constexpr char headphones[] = "\xee\xaa\xbd"; + inline constexpr char headphonesOff[] = "\xee\xb4\x9d"; + inline constexpr char headset[] = "\xee\xae\x90"; + inline constexpr char headsetOff[] = "\xef\x8f\xb6"; + inline constexpr char healthRecognition[] = "\xef\x87\xbb"; + inline constexpr char heart[] = "\xee\xaa\xbe"; + inline constexpr char heartBitcoin[] = "\xef\xbc\xbb"; + inline constexpr char heartBolt[] = "\xef\xae\x9e"; + inline constexpr char heartBroken[] = "\xee\xb2\xba"; + inline constexpr char heartCancel[] = "\xef\xae\x9f"; + inline constexpr char heartCheck[] = "\xef\xae\xa0"; + inline constexpr char heartCode[] = "\xef\xae\xa1"; + inline constexpr char heartCog[] = "\xef\xae\xa2"; + inline constexpr char heartDiscount[] = "\xef\xae\xa3"; + inline constexpr char heartDollar[] = "\xef\xae\xa4"; + inline constexpr char heartDown[] = "\xef\xae\xa5"; + inline constexpr char heartExclamation[] = "\xef\xae\xa6"; + inline constexpr char heartHandshake[] = "\xef\x83\xb3"; + inline constexpr char heartMinus[] = "\xef\x85\x80"; + inline constexpr char heartOff[] = "\xef\x85\x81"; + inline constexpr char heartPause[] = "\xef\xae\xa7"; + inline constexpr char heartPin[] = "\xef\xae\xa8"; + inline constexpr char heartPlus[] = "\xef\x85\x82"; + inline constexpr char heartQuestion[] = "\xef\xae\xa9"; + inline constexpr char heartRateMonitor[] = "\xee\xbd\xa1"; + inline constexpr char heartSearch[] = "\xef\xae\xaa"; + inline constexpr char heartShare[] = "\xef\xae\xab"; + inline constexpr char heartSpark[] = "\xef\xbe\xb6"; + inline constexpr char heartStar[] = "\xef\xae\xac"; + inline constexpr char heartUp[] = "\xef\xae\xad"; + inline constexpr char heartX[] = "\xef\xae\xae"; + inline constexpr char heartbeat[] = "\xee\xbe\x92"; + inline constexpr char hearts[] = "\xef\x8e\x87"; + inline constexpr char heartsOff[] = "\xef\x8f\xb7"; + inline constexpr char helicopter[] = "\xee\xb6\x8e"; + inline constexpr char helicopterLanding[] = "\xee\xb6\x8d"; + inline constexpr char helmet[] = "\xee\xbf\x8a"; + inline constexpr char helmetOff[] = "\xef\x85\x83"; + inline constexpr char help[] = "\xee\xaa\xbf"; + inline constexpr char helpCircle[] = "\xef\xa4\x9d"; + inline constexpr char helpHexagon[] = "\xef\x9e\xa8"; + inline constexpr char helpOctagon[] = "\xef\x9e\xa9"; + inline constexpr char helpOff[] = "\xef\x8f\xb8"; + inline constexpr char helpSmall[] = "\xef\xa4\x9e"; + inline constexpr char helpSquare[] = "\xef\xa4\xa0"; + inline constexpr char helpSquareRounded[] = "\xef\xa4\x9f"; + inline constexpr char helpTriangle[] = "\xef\xa4\xa1"; + inline constexpr char hemisphere[] = "\xef\xaa\xa2"; + inline constexpr char hemisphereOff[] = "\xef\xaa\xa0"; + inline constexpr char hemispherePlus[] = "\xef\xaa\xa1"; + inline constexpr char hexagon[] = "\xee\xb0\x82"; + inline constexpr char hexagon3d[] = "\xef\x93\x87"; + inline constexpr char hexagonAsterisk[] = "\xf0\x90\x86\xab"; + inline constexpr char hexagonLetterA[] = "\xef\x91\xa3"; + inline constexpr char hexagonLetterB[] = "\xef\x91\xa4"; + inline constexpr char hexagonLetterC[] = "\xef\x91\xa5"; + inline constexpr char hexagonLetterD[] = "\xef\x91\xa6"; + inline constexpr char hexagonLetterE[] = "\xef\x91\xa7"; + inline constexpr char hexagonLetterF[] = "\xef\x91\xa8"; + inline constexpr char hexagonLetterG[] = "\xef\x91\xa9"; + inline constexpr char hexagonLetterH[] = "\xef\x91\xaa"; + inline constexpr char hexagonLetterI[] = "\xef\x91\xab"; + inline constexpr char hexagonLetterJ[] = "\xef\x91\xac"; + inline constexpr char hexagonLetterK[] = "\xef\x91\xad"; + inline constexpr char hexagonLetterL[] = "\xef\x91\xae"; + inline constexpr char hexagonLetterM[] = "\xef\x91\xaf"; + inline constexpr char hexagonLetterN[] = "\xef\x91\xb0"; + inline constexpr char hexagonLetterO[] = "\xef\x91\xb1"; + inline constexpr char hexagonLetterP[] = "\xef\x91\xb2"; + inline constexpr char hexagonLetterQ[] = "\xef\x91\xb3"; + inline constexpr char hexagonLetterR[] = "\xef\x91\xb4"; + inline constexpr char hexagonLetterS[] = "\xef\x91\xb5"; + inline constexpr char hexagonLetterT[] = "\xef\x91\xb6"; + inline constexpr char hexagonLetterU[] = "\xef\x91\xb7"; + inline constexpr char hexagonLetterV[] = "\xef\x92\xb3"; + inline constexpr char hexagonLetterW[] = "\xef\x91\xb8"; + inline constexpr char hexagonLetterX[] = "\xef\x91\xb9"; + inline constexpr char hexagonLetterY[] = "\xef\x91\xba"; + inline constexpr char hexagonLetterZ[] = "\xef\x91\xbb"; + inline constexpr char hexagonMinus[] = "\xef\xb2\x8f"; + inline constexpr char hexagonMinus2[] = "\xef\xb2\x8e"; + inline constexpr char hexagonNumber0[] = "\xef\x91\x99"; + inline constexpr char hexagonNumber1[] = "\xef\x91\x9a"; + inline constexpr char hexagonNumber2[] = "\xef\x91\x9b"; + inline constexpr char hexagonNumber3[] = "\xef\x91\x9c"; + inline constexpr char hexagonNumber4[] = "\xef\x91\x9d"; + inline constexpr char hexagonNumber5[] = "\xef\x91\x9e"; + inline constexpr char hexagonNumber6[] = "\xef\x91\x9f"; + inline constexpr char hexagonNumber7[] = "\xef\x91\xa0"; + inline constexpr char hexagonNumber8[] = "\xef\x91\xa1"; + inline constexpr char hexagonNumber9[] = "\xef\x91\xa2"; + inline constexpr char hexagonOff[] = "\xee\xba\x9c"; + inline constexpr char hexagonPlus[] = "\xef\xb1\x85"; + inline constexpr char hexagonPlus2[] = "\xef\xb2\x90"; + inline constexpr char hexagonalPrism[] = "\xef\xaa\xa5"; + inline constexpr char hexagonalPrismOff[] = "\xef\xaa\xa3"; + inline constexpr char hexagonalPrismPlus[] = "\xef\xaa\xa4"; + inline constexpr char hexagonalPyramid[] = "\xef\xaa\xa8"; + inline constexpr char hexagonalPyramidOff[] = "\xef\xaa\xa6"; + inline constexpr char hexagonalPyramidPlus[] = "\xef\xaa\xa7"; + inline constexpr char hexagons[] = "\xef\x82\x9d"; + inline constexpr char hexagonsOff[] = "\xef\x8f\xb9"; + inline constexpr char hierarchy[] = "\xee\xba\x9e"; + inline constexpr char hierarchy2[] = "\xee\xba\x9d"; + inline constexpr char hierarchy3[] = "\xef\x8a\x89"; + inline constexpr char hierarchyOff[] = "\xef\x8f\xba"; + inline constexpr char highlight[] = "\xee\xbc\xbf"; + inline constexpr char highlightOff[] = "\xef\x85\x84"; + inline constexpr char history[] = "\xee\xaf\xaa"; + inline constexpr char historyOff[] = "\xef\x8f\xbb"; + inline constexpr char historyToggle[] = "\xef\x87\xbc"; + inline constexpr char home[] = "\xee\xab\x81"; + inline constexpr char home2[] = "\xee\xab\x80"; + inline constexpr char homeBitcoin[] = "\xef\xbc\xba"; + inline constexpr char homeBolt[] = "\xef\x8c\xb6"; + inline constexpr char homeCancel[] = "\xef\x8d\x90"; + inline constexpr char homeCheck[] = "\xef\x8c\xb7"; + inline constexpr char homeCog[] = "\xef\x8c\xb8"; + inline constexpr char homeDollar[] = "\xef\x8c\xb9"; + inline constexpr char homeDot[] = "\xef\x8c\xba"; + inline constexpr char homeDown[] = "\xef\x8c\xbb"; + inline constexpr char homeEco[] = "\xef\x8d\x91"; + inline constexpr char homeEdit[] = "\xef\x8d\x92"; + inline constexpr char homeExclamation[] = "\xef\x8c\xbc"; + inline constexpr char homeHand[] = "\xef\x94\x84"; + inline constexpr char homeHeart[] = "\xef\x8d\x93"; + inline constexpr char homeInfinity[] = "\xef\x94\x85"; + inline constexpr char homeLink[] = "\xef\x8d\x94"; + inline constexpr char homeLock[] = "\xf0\x90\x88\x84"; + inline constexpr char homeMinus[] = "\xef\x8c\xbd"; + inline constexpr char homeMove[] = "\xef\x8c\xbe"; + inline constexpr char homeOff[] = "\xef\x85\x85"; + inline constexpr char homePlus[] = "\xef\x8c\xbf"; + inline constexpr char homeQuestion[] = "\xef\x8d\x80"; + inline constexpr char homeRibbon[] = "\xef\x8d\x95"; + inline constexpr char homeSearch[] = "\xef\x8d\x81"; + inline constexpr char homeShare[] = "\xef\x8d\x82"; + inline constexpr char homeShield[] = "\xef\x8d\x83"; + inline constexpr char homeSignal[] = "\xef\x8d\x96"; + inline constexpr char homeSpark[] = "\xef\xbe\xb5"; + inline constexpr char homeStar[] = "\xef\x8d\x84"; + inline constexpr char homeStats[] = "\xef\x8d\x85"; + inline constexpr char homeUp[] = "\xef\x8d\x86"; + inline constexpr char homeX[] = "\xef\x8d\x87"; + inline constexpr char horse[] = "\xef\xb1\x86"; + inline constexpr char horseToy[] = "\xef\x8a\x8a"; + inline constexpr char horseshoe[] = "\xef\xb2\xb7"; + inline constexpr char hospital[] = "\xef\xb5\x99"; + inline constexpr char hospitalCircle[] = "\xef\xb5\x98"; + inline constexpr char hotelService[] = "\xee\xbe\x80"; + inline constexpr char hourglass[] = "\xee\xbe\x93"; + inline constexpr char hourglassEmpty[] = "\xef\x85\x86"; + inline constexpr char hourglassHigh[] = "\xef\x82\x92"; + inline constexpr char hourglassLow[] = "\xef\x82\x93"; + inline constexpr char hourglassOff[] = "\xef\x85\x87"; + inline constexpr char hours12[] = "\xef\xb1\x93"; + inline constexpr char hours24[] = "\xef\x97\xa7"; + inline constexpr char html[] = "\xef\x9e\xb1"; + inline constexpr char httpConnect[] = "\xef\xa8\xa8"; + inline constexpr char httpConnectOff[] = "\xf0\x90\x83\xa7"; + inline constexpr char httpDelete[] = "\xef\xa8\xa9"; + inline constexpr char httpDeleteOff[] = "\xf0\x90\x83\xa6"; + inline constexpr char httpGet[] = "\xef\xa8\xaa"; + inline constexpr char httpGetOff[] = "\xf0\x90\x83\xa5"; + inline constexpr char httpHead[] = "\xef\xa8\xab"; + inline constexpr char httpHeadOff[] = "\xf0\x90\x83\xa4"; + inline constexpr char httpOptions[] = "\xef\xa8\xac"; + inline constexpr char httpOptionsOff[] = "\xf0\x90\x83\xa3"; + inline constexpr char httpPatch[] = "\xef\xa8\xad"; + inline constexpr char httpPatchOff[] = "\xf0\x90\x83\xa2"; + inline constexpr char httpPost[] = "\xef\xa8\xae"; + inline constexpr char httpPostOff[] = "\xf0\x90\x83\xa1"; + inline constexpr char httpPut[] = "\xef\xa8\xaf"; + inline constexpr char httpPutOff[] = "\xf0\x90\x83\xa0"; + inline constexpr char httpQue[] = "\xef\xa9\x9b"; + inline constexpr char httpQueOff[] = "\xf0\x90\x83\x9f"; + inline constexpr char httpTrace[] = "\xef\xa8\xb0"; + inline constexpr char httpTraceOff[] = "\xf0\x90\x83\x9e"; + inline constexpr char hulaHoop[] = "\xf0\x90\x89\x8a"; + inline constexpr char iceCream[] = "\xee\xab\x82"; + inline constexpr char iceCream2[] = "\xee\xba\x9f"; + inline constexpr char iceCreamOff[] = "\xef\x85\x88"; + inline constexpr char iceSkating[] = "\xee\xbf\x8b"; + inline constexpr char iceberg[] = "\xf0\x90\x88\xaa"; + inline constexpr char icons[] = "\xef\x87\x94"; + inline constexpr char iconsOff[] = "\xef\x8f\xbc"; + inline constexpr char icosahedron[] = "\xef\xbb\x86"; + inline constexpr char id[] = "\xee\xab\x83"; + inline constexpr char idBadge[] = "\xee\xbf\xb7"; + inline constexpr char idBadge2[] = "\xef\x81\xb6"; + inline constexpr char idBadgeOff[] = "\xef\x8f\xbd"; + inline constexpr char idOff[] = "\xef\x85\x89"; + inline constexpr char imageGeneration[] = "\xf0\x90\x87\xaf"; + inline constexpr char imageInPicture[] = "\xef\xb6\x9f"; + inline constexpr char inbox[] = "\xee\xab\x84"; + inline constexpr char inboxOff[] = "\xef\x85\x8a"; + inline constexpr char indentDecrease[] = "\xee\xae\x91"; + inline constexpr char indentIncrease[] = "\xee\xae\x92"; + inline constexpr char infinity[] = "\xee\xad\xa9"; + inline constexpr char infinity2[] = "\xf0\x90\x88\xb7"; + inline constexpr char infinityOff[] = "\xef\x8f\xbe"; + inline constexpr char infoCircle[] = "\xee\xab\x85"; + inline constexpr char infoHexagon[] = "\xef\x9e\xaa"; + inline constexpr char infoOctagon[] = "\xef\x9e\xab"; + inline constexpr char infoSmall[] = "\xef\xa4\xa2"; + inline constexpr char infoSquare[] = "\xee\xab\x86"; + inline constexpr char infoSquareRounded[] = "\xef\x98\xb5"; + inline constexpr char infoTriangle[] = "\xef\xa4\xa3"; + inline constexpr char innerShadowBottom[] = "\xef\x94\xa0"; + inline constexpr char innerShadowBottomLeft[] = "\xef\x94\x9e"; + inline constexpr char innerShadowBottomRight[] = "\xef\x94\x9f"; + inline constexpr char innerShadowLeft[] = "\xef\x94\xa1"; + inline constexpr char innerShadowRight[] = "\xef\x94\xa2"; + inline constexpr char innerShadowTop[] = "\xef\x94\xa5"; + inline constexpr char innerShadowTopLeft[] = "\xef\x94\xa3"; + inline constexpr char innerShadowTopRight[] = "\xef\x94\xa4"; + inline constexpr char inputAi[] = "\xef\xb1\x9a"; + inline constexpr char inputCheck[] = "\xef\xb1\x9b"; + inline constexpr char inputSearch[] = "\xef\x8a\xa2"; + inline constexpr char inputSpark[] = "\xef\xbe\xb4"; + inline constexpr char inputX[] = "\xef\xb1\x9c"; + inline constexpr char invoice[] = "\xef\xba\xab"; + inline constexpr char ironing[] = "\xef\xa9\xbc"; + inline constexpr char ironing1[] = "\xef\x8b\xb4"; + inline constexpr char ironing2[] = "\xef\x8b\xb5"; + inline constexpr char ironing3[] = "\xef\x8b\xb6"; + inline constexpr char ironingOff[] = "\xef\x8b\xb7"; + inline constexpr char ironingSteam[] = "\xef\x8b\xb9"; + inline constexpr char ironingSteamOff[] = "\xef\x8b\xb8"; + inline constexpr char irregularPolyhedron[] = "\xef\xaa\xab"; + inline constexpr char irregularPolyhedronOff[] = "\xef\xaa\xa9"; + inline constexpr char irregularPolyhedronPlus[] = "\xef\xaa\xaa"; + inline constexpr char italic[] = "\xee\xae\x93"; + inline constexpr char italicOff[] = "\xf0\x90\x89\xb1"; + inline constexpr char jacket[] = "\xef\x99\xa1"; + inline constexpr char jetpack[] = "\xef\x96\x81"; + inline constexpr char jetski[] = "\xf0\x90\x88\xa9"; + inline constexpr char jewishStar[] = "\xef\x8f\xbf"; + inline constexpr char joinBevel[] = "\xef\xbd\x8c"; + inline constexpr char joinRound[] = "\xef\xbd\x8b"; + inline constexpr char joinStraight[] = "\xef\xbd\x8a"; + inline constexpr char joker[] = "\xf0\x90\x81\x9f"; + inline constexpr char jpg[] = "\xef\x8e\xac"; + inline constexpr char json[] = "\xef\x9e\xb2"; + inline constexpr char jumpRope[] = "\xee\xb6\x8f"; + inline constexpr char karate[] = "\xee\xb4\xb2"; + inline constexpr char kayak[] = "\xef\x87\x96"; + inline constexpr char kerning[] = "\xee\xbe\xb8"; + inline constexpr char key[] = "\xee\xab\x87"; + inline constexpr char keyOff[] = "\xef\x85\x8b"; + inline constexpr char keyboard[] = "\xee\xaf\x96"; + inline constexpr char keyboardHide[] = "\xee\xb1\xbe"; + inline constexpr char keyboardOff[] = "\xee\xba\xa0"; + inline constexpr char keyboardShow[] = "\xee\xb1\xbf"; + inline constexpr char keyframe[] = "\xef\x95\xb6"; + inline constexpr char keyframeAlignCenter[] = "\xef\x96\x82"; + inline constexpr char keyframeAlignHorizontal[] = "\xef\x96\x83"; + inline constexpr char keyframeAlignVertical[] = "\xef\x96\x84"; + inline constexpr char keyframes[] = "\xef\x96\x85"; + inline constexpr char label[] = "\xef\xbc\xb8"; + inline constexpr char labelImportant[] = "\xef\xbd\x89"; + inline constexpr char labelOff[] = "\xef\xbc\xb9"; + inline constexpr char ladder[] = "\xee\xbf\xa2"; + inline constexpr char ladderOff[] = "\xef\x85\x8c"; + inline constexpr char ladle[] = "\xef\xb0\x94"; + inline constexpr char lambda[] = "\xef\x95\x81"; + inline constexpr char lamp[] = "\xee\xbe\xab"; + inline constexpr char lamp2[] = "\xef\x82\x9e"; + inline constexpr char lampOff[] = "\xef\x85\x8d"; + inline constexpr char lane[] = "\xef\xab\xb9"; + inline constexpr char language[] = "\xee\xae\xbe"; + inline constexpr char languageHiragana[] = "\xee\xbd\xb7"; + inline constexpr char languageKatakana[] = "\xee\xbd\xb8"; + inline constexpr char languageOff[] = "\xef\x85\x8e"; + inline constexpr char lasso[] = "\xee\xbe\xac"; + inline constexpr char lassoOff[] = "\xef\x85\x8f"; + inline constexpr char lassoPolygon[] = "\xef\x8e\x88"; + inline constexpr char laurelWreath[] = "\xef\xbd\x85"; + inline constexpr char laurelWreath1[] = "\xef\xbd\x88"; + inline constexpr char laurelWreath2[] = "\xef\xbd\x87"; + inline constexpr char laurelWreath3[] = "\xef\xbd\x86"; + inline constexpr char lawnMower[] = "\xf0\x90\x88\xb6"; + inline constexpr char layersDifference[] = "\xee\xab\x88"; + inline constexpr char layersIntersect[] = "\xee\xab\x89"; + inline constexpr char layersIntersect2[] = "\xee\xbf\xb8"; + inline constexpr char layersLinked[] = "\xee\xba\xa1"; + inline constexpr char layersOff[] = "\xef\x85\x90"; + inline constexpr char layersSelected[] = "\xef\xba\xa9"; + inline constexpr char layersSelectedBottom[] = "\xef\xba\xaa"; + inline constexpr char layersSubtract[] = "\xee\xab\x8a"; + inline constexpr char layersUnion[] = "\xee\xab\x8b"; + inline constexpr char layout[] = "\xee\xab\x9b"; + inline constexpr char layout2[] = "\xee\xab\x8c"; + inline constexpr char layoutAlignBottom[] = "\xee\xab\x8d"; + inline constexpr char layoutAlignCenter[] = "\xee\xab\x8e"; + inline constexpr char layoutAlignLeft[] = "\xee\xab\x8f"; + inline constexpr char layoutAlignMiddle[] = "\xee\xab\x90"; + inline constexpr char layoutAlignRight[] = "\xee\xab\x91"; + inline constexpr char layoutAlignTop[] = "\xee\xab\x92"; + inline constexpr char layoutBoard[] = "\xee\xbe\x95"; + inline constexpr char layoutBoardSplit[] = "\xee\xbe\x94"; + inline constexpr char layoutBottombar[] = "\xee\xab\x93"; + inline constexpr char layoutBottombarCollapse[] = "\xef\x8a\x8b"; + inline constexpr char layoutBottombarExpand[] = "\xef\x8a\x8c"; + inline constexpr char layoutBottombarInactive[] = "\xef\xb5\x85"; + inline constexpr char layoutCards[] = "\xee\xb0\x93"; + inline constexpr char layoutCollage[] = "\xef\x8e\x89"; + inline constexpr char layoutColumns[] = "\xee\xab\x94"; + inline constexpr char layoutDashboard[] = "\xef\x80\xac"; + inline constexpr char layoutDistributeHorizontal[] = "\xee\xab\x95"; + inline constexpr char layoutDistributeVertical[] = "\xee\xab\x96"; + inline constexpr char layoutGrid[] = "\xee\xb6\xba"; + inline constexpr char layoutGridAdd[] = "\xee\xb6\xb9"; + inline constexpr char layoutGridRemove[] = "\xef\xa9\xbd"; + inline constexpr char layoutKanban[] = "\xee\xb0\xbf"; + inline constexpr char layoutList[] = "\xee\xb0\x94"; + inline constexpr char layoutNavbar[] = "\xee\xab\x97"; + inline constexpr char layoutNavbarCollapse[] = "\xef\x8a\x8d"; + inline constexpr char layoutNavbarExpand[] = "\xef\x8a\x8e"; + inline constexpr char layoutNavbarInactive[] = "\xef\xb5\x86"; + inline constexpr char layoutOff[] = "\xef\x85\x91"; + inline constexpr char layoutRows[] = "\xee\xab\x98"; + inline constexpr char layoutSidebar[] = "\xee\xab\x9a"; + inline constexpr char layoutSidebarInactive[] = "\xef\xb5\x87"; + inline constexpr char layoutSidebarLeftCollapse[] = "\xef\x80\x84"; + inline constexpr char layoutSidebarLeftExpand[] = "\xef\x80\x85"; + inline constexpr char layoutSidebarRight[] = "\xee\xab\x99"; + inline constexpr char layoutSidebarRightCollapse[] = "\xef\x80\x86"; + inline constexpr char layoutSidebarRightExpand[] = "\xef\x80\x87"; + inline constexpr char layoutSidebarRightInactive[] = "\xef\xb5\x88"; + inline constexpr char leaf[] = "\xee\xb5\x8f"; + inline constexpr char leaf2[] = "\xef\xbd\x84"; + inline constexpr char leafMaple[] = "\xf0\x90\x89\x89"; + inline constexpr char leafOff[] = "\xef\x90\x80"; + inline constexpr char lego[] = "\xee\xab\x9c"; + inline constexpr char legoOff[] = "\xef\x90\x81"; + inline constexpr char lemon[] = "\xee\xbc\x90"; + inline constexpr char lemon2[] = "\xee\xbe\x81"; + inline constexpr char letterA[] = "\xee\xb1\x90"; + inline constexpr char letterASmall[] = "\xef\xb3\x87"; + inline constexpr char letterB[] = "\xee\xb1\x91"; + inline constexpr char letterBSmall[] = "\xef\xb3\x88"; + inline constexpr char letterC[] = "\xee\xb1\x92"; + inline constexpr char letterCSmall[] = "\xef\xb3\x89"; + inline constexpr char letterCase[] = "\xee\xba\xa5"; + inline constexpr char letterCaseLower[] = "\xee\xba\xa2"; + inline constexpr char letterCaseToggle[] = "\xee\xba\xa3"; + inline constexpr char letterCaseUpper[] = "\xee\xba\xa4"; + inline constexpr char letterD[] = "\xee\xb1\x93"; + inline constexpr char letterDSmall[] = "\xef\xb3\x8a"; + inline constexpr char letterE[] = "\xee\xb1\x94"; + inline constexpr char letterESmall[] = "\xef\xb3\x8b"; + inline constexpr char letterF[] = "\xee\xb1\x95"; + inline constexpr char letterFSmall[] = "\xef\xb3\x8c"; + inline constexpr char letterG[] = "\xee\xb1\x96"; + inline constexpr char letterGSmall[] = "\xef\xb3\x8d"; + inline constexpr char letterH[] = "\xee\xb1\x97"; + inline constexpr char letterHSmall[] = "\xef\xb3\x8e"; + inline constexpr char letterI[] = "\xee\xb1\x98"; + inline constexpr char letterISmall[] = "\xef\xb3\x8f"; + inline constexpr char letterJ[] = "\xee\xb1\x99"; + inline constexpr char letterJSmall[] = "\xef\xb3\x90"; + inline constexpr char letterK[] = "\xee\xb1\x9a"; + inline constexpr char letterKSmall[] = "\xef\xb3\x91"; + inline constexpr char letterL[] = "\xee\xb1\x9b"; + inline constexpr char letterLSmall[] = "\xef\xb3\x92"; + inline constexpr char letterM[] = "\xee\xb1\x9c"; + inline constexpr char letterMSmall[] = "\xef\xb3\x93"; + inline constexpr char letterN[] = "\xee\xb1\x9d"; + inline constexpr char letterNSmall[] = "\xef\xb3\x94"; + inline constexpr char letterO[] = "\xee\xb1\x9e"; + inline constexpr char letterOSmall[] = "\xef\xb3\x95"; + inline constexpr char letterP[] = "\xee\xb1\x9f"; + inline constexpr char letterPSmall[] = "\xef\xb3\x96"; + inline constexpr char letterQ[] = "\xee\xb1\xa0"; + inline constexpr char letterQSmall[] = "\xef\xb3\x97"; + inline constexpr char letterR[] = "\xee\xb1\xa1"; + inline constexpr char letterRSmall[] = "\xef\xb3\x98"; + inline constexpr char letterS[] = "\xee\xb1\xa2"; + inline constexpr char letterSSmall[] = "\xef\xb3\x99"; + inline constexpr char letterSpacing[] = "\xee\xba\xa6"; + inline constexpr char letterT[] = "\xee\xb1\xa3"; + inline constexpr char letterTSmall[] = "\xef\xb3\x9a"; + inline constexpr char letterU[] = "\xee\xb1\xa4"; + inline constexpr char letterUSmall[] = "\xef\xb3\x9b"; + inline constexpr char letterV[] = "\xee\xb1\xa5"; + inline constexpr char letterVSmall[] = "\xef\xb3\x9c"; + inline constexpr char letterW[] = "\xee\xb1\xa6"; + inline constexpr char letterWSmall[] = "\xef\xb3\x9d"; + inline constexpr char letterX[] = "\xee\xb1\xa7"; + inline constexpr char letterXSmall[] = "\xef\xb3\x9e"; + inline constexpr char letterY[] = "\xee\xb1\xa8"; + inline constexpr char letterYSmall[] = "\xef\xb3\x9f"; + inline constexpr char letterZ[] = "\xee\xb1\xa9"; + inline constexpr char letterZSmall[] = "\xef\xb3\xa0"; + inline constexpr char library[] = "\xef\xb5\x8c"; + inline constexpr char libraryMinus[] = "\xef\xb5\x89"; + inline constexpr char libraryPhoto[] = "\xef\xb5\x8a"; + inline constexpr char libraryPlus[] = "\xef\xb5\x8b"; + inline constexpr char license[] = "\xee\xaf\x80"; + inline constexpr char licenseOff[] = "\xef\x85\x93"; + inline constexpr char lifebuoy[] = "\xee\xab\x9d"; + inline constexpr char lifebuoyOff[] = "\xef\x85\x94"; + inline constexpr char lighter[] = "\xef\x9e\x94"; + inline constexpr char line[] = "\xee\xb1\x80"; + inline constexpr char lineDashed[] = "\xee\xba\xa7"; + inline constexpr char lineDotted[] = "\xee\xba\xa8"; + inline constexpr char lineHeight[] = "\xee\xae\x94"; + inline constexpr char lineScan[] = "\xef\xb2\xb8"; + inline constexpr char link[] = "\xee\xab\x9e"; + inline constexpr char linkMinus[] = "\xef\xb4\x96"; + inline constexpr char linkOff[] = "\xef\x90\x82"; + inline constexpr char linkPlus[] = "\xef\xb4\x97"; + inline constexpr char list[] = "\xee\xad\xab"; + inline constexpr char listCheck[] = "\xee\xad\xaa"; + inline constexpr char listDetails[] = "\xee\xbd\x80"; + inline constexpr char listLetters[] = "\xef\xb1\x87"; + inline constexpr char listNumbers[] = "\xee\xbc\x91"; + inline constexpr char listSearch[] = "\xee\xba\xa9"; + inline constexpr char listTree[] = "\xef\xab\xba"; + inline constexpr char livePhoto[] = "\xee\xab\x9f"; + inline constexpr char livePhotoOff[] = "\xef\x90\x83"; + inline constexpr char liveView[] = "\xee\xb1\xab"; + inline constexpr char loadBalancer[] = "\xef\xa9\x9c"; + inline constexpr char loader[] = "\xee\xb2\xa3"; + inline constexpr char loader2[] = "\xef\x88\xa6"; + inline constexpr char loader3[] = "\xef\x94\x93"; + inline constexpr char loader4[] = "\xf0\x90\x88\xb5"; + inline constexpr char loaderQuarter[] = "\xee\xb2\xa2"; + inline constexpr char location[] = "\xee\xab\xa0"; + inline constexpr char locationBolt[] = "\xef\xae\xaf"; + inline constexpr char locationBroken[] = "\xef\x8b\x84"; + inline constexpr char locationCancel[] = "\xef\xae\xb0"; + inline constexpr char locationCheck[] = "\xef\xae\xb1"; + inline constexpr char locationCode[] = "\xef\xae\xb2"; + inline constexpr char locationCog[] = "\xef\xae\xb3"; + inline constexpr char locationDiscount[] = "\xef\xae\xb4"; + inline constexpr char locationDollar[] = "\xef\xae\xb5"; + inline constexpr char locationDown[] = "\xef\xae\xb6"; + inline constexpr char locationExclamation[] = "\xef\xae\xb7"; + inline constexpr char locationHeart[] = "\xef\xae\xb8"; + inline constexpr char locationMinus[] = "\xef\xae\xb9"; + inline constexpr char locationOff[] = "\xef\x85\x95"; + inline constexpr char locationPause[] = "\xef\xae\xba"; + inline constexpr char locationPin[] = "\xef\xae\xbb"; + inline constexpr char locationPlus[] = "\xef\xae\xbc"; + inline constexpr char locationQuestion[] = "\xef\xae\xbd"; + inline constexpr char locationSearch[] = "\xef\xae\xbe"; + inline constexpr char locationShare[] = "\xef\xae\xbf"; + inline constexpr char locationStar[] = "\xef\xaf\x80"; + inline constexpr char locationUp[] = "\xef\xaf\x81"; + inline constexpr char locationX[] = "\xef\xaf\x82"; + inline constexpr char lock[] = "\xee\xab\xa2"; + inline constexpr char lockAccess[] = "\xee\xba\xaa"; + inline constexpr char lockAccessOff[] = "\xef\x90\x84"; + inline constexpr char lockBitcoin[] = "\xef\xbc\xb7"; + inline constexpr char lockBolt[] = "\xef\xa4\xa4"; + inline constexpr char lockCancel[] = "\xef\xa4\xa5"; + inline constexpr char lockCheck[] = "\xef\xa4\xa6"; + inline constexpr char lockCode[] = "\xef\xa4\xa7"; + inline constexpr char lockCog[] = "\xef\xa4\xa8"; + inline constexpr char lockDollar[] = "\xef\xa4\xa9"; + inline constexpr char lockDown[] = "\xef\xa4\xaa"; + inline constexpr char lockExclamation[] = "\xef\xa4\xab"; + inline constexpr char lockHeart[] = "\xef\xa4\xac"; + inline constexpr char lockMinus[] = "\xef\xa4\xad"; + inline constexpr char lockOff[] = "\xee\xb4\x9e"; + inline constexpr char lockOpen[] = "\xee\xab\xa1"; + inline constexpr char lockOpen2[] = "\xef\xba\xa8"; + inline constexpr char lockOpenOff[] = "\xef\x85\x96"; + inline constexpr char lockPassword[] = "\xef\xbe\x9f"; + inline constexpr char lockPause[] = "\xef\xa4\xae"; + inline constexpr char lockPin[] = "\xef\xa4\xaf"; + inline constexpr char lockPlus[] = "\xef\xa4\xb0"; + inline constexpr char lockQuestion[] = "\xef\xa4\xb1"; + inline constexpr char lockSearch[] = "\xef\xa4\xb2"; + inline constexpr char lockShare[] = "\xef\xa4\xb3"; + inline constexpr char lockSquare[] = "\xee\xbd\x91"; + inline constexpr char lockSquareRounded[] = "\xef\x98\xb6"; + inline constexpr char lockStar[] = "\xef\xa4\xb4"; + inline constexpr char lockUp[] = "\xef\xa4\xb5"; + inline constexpr char lockX[] = "\xef\xa4\xb6"; + inline constexpr char logicAnd[] = "\xef\x89\x80"; + inline constexpr char logicBuffer[] = "\xef\x89\x81"; + inline constexpr char logicNand[] = "\xef\x89\x82"; + inline constexpr char logicNor[] = "\xef\x89\x83"; + inline constexpr char logicNot[] = "\xef\x89\x84"; + inline constexpr char logicOr[] = "\xef\x89\x85"; + inline constexpr char logicXnor[] = "\xef\x89\x86"; + inline constexpr char logicXor[] = "\xef\x89\x87"; + inline constexpr char login[] = "\xee\xae\xa7"; + inline constexpr char login2[] = "\xef\xb1\xb6"; + inline constexpr char logout[] = "\xee\xae\xa8"; + inline constexpr char logout2[] = "\xef\xa9\xbe"; + inline constexpr char logs[] = "\xef\xba\xa7"; + inline constexpr char lollipop[] = "\xee\xbf\x8c"; + inline constexpr char lollipopOff[] = "\xef\x85\x97"; + inline constexpr char luggage[] = "\xee\xbe\xad"; + inline constexpr char luggageOff[] = "\xef\x85\x98"; + inline constexpr char lungs[] = "\xee\xbd\xa2"; + inline constexpr char lungsOff[] = "\xef\x90\x85"; + inline constexpr char macro[] = "\xee\xba\xab"; + inline constexpr char macroOff[] = "\xef\x90\x86"; + inline constexpr char magnet[] = "\xee\xab\xa3"; + inline constexpr char magnetOff[] = "\xef\x85\x99"; + inline constexpr char magnetic[] = "\xef\xb2\xb9"; + inline constexpr char mail[] = "\xee\xab\xa5"; + inline constexpr char mailAi[] = "\xef\xa8\xb1"; + inline constexpr char mailBitcoin[] = "\xef\xbc\xb6"; + inline constexpr char mailBolt[] = "\xef\xa4\xb7"; + inline constexpr char mailCancel[] = "\xef\xa4\xb8"; + inline constexpr char mailCheck[] = "\xef\xa4\xb9"; + inline constexpr char mailCode[] = "\xef\xa4\xba"; + inline constexpr char mailCog[] = "\xef\xa4\xbb"; + inline constexpr char mailDollar[] = "\xef\xa4\xbc"; + inline constexpr char mailDown[] = "\xef\xa4\xbd"; + inline constexpr char mailExclamation[] = "\xef\xa4\xbe"; + inline constexpr char mailFast[] = "\xef\x81\xa9"; + inline constexpr char mailForward[] = "\xee\xba\xac"; + inline constexpr char mailHeart[] = "\xef\xa4\xbf"; + inline constexpr char mailMinus[] = "\xef\xa5\x80"; + inline constexpr char mailOff[] = "\xef\x85\x9a"; + inline constexpr char mailOpened[] = "\xee\xab\xa4"; + inline constexpr char mailPause[] = "\xef\xa5\x81"; + inline constexpr char mailPin[] = "\xef\xa5\x82"; + inline constexpr char mailPlus[] = "\xef\xa5\x83"; + inline constexpr char mailQuestion[] = "\xef\xa5\x84"; + inline constexpr char mailSearch[] = "\xef\xa5\x85"; + inline constexpr char mailShare[] = "\xef\xa5\x86"; + inline constexpr char mailSpark[] = "\xef\xbe\xb3"; + inline constexpr char mailStar[] = "\xef\xa5\x87"; + inline constexpr char mailUp[] = "\xef\xa5\x88"; + inline constexpr char mailX[] = "\xef\xa5\x89"; + inline constexpr char mailbox[] = "\xee\xba\xad"; + inline constexpr char mailboxOff[] = "\xef\x85\x9b"; + inline constexpr char man[] = "\xee\xab\xa6"; + inline constexpr char manualGearbox[] = "\xee\xb5\xbb"; + inline constexpr char map[] = "\xee\xab\xa9"; + inline constexpr char map2[] = "\xee\xab\xa7"; + inline constexpr char mapBolt[] = "\xef\xaf\x83"; + inline constexpr char mapCancel[] = "\xef\xaf\x84"; + inline constexpr char mapCheck[] = "\xef\xaf\x85"; + inline constexpr char mapCode[] = "\xef\xaf\x86"; + inline constexpr char mapCog[] = "\xef\xaf\x87"; + inline constexpr char mapDiscount[] = "\xef\xaf\x88"; + inline constexpr char mapDollar[] = "\xef\xaf\x89"; + inline constexpr char mapDown[] = "\xef\xaf\x8a"; + inline constexpr char mapEast[] = "\xef\xb1\x9d"; + inline constexpr char mapExclamation[] = "\xef\xaf\x8b"; + inline constexpr char mapHeart[] = "\xef\xaf\x8c"; + inline constexpr char mapLock[] = "\xf0\x90\x88\x83"; + inline constexpr char mapMinus[] = "\xef\xaf\x8d"; + inline constexpr char mapNorth[] = "\xef\xb1\x9e"; + inline constexpr char mapOff[] = "\xef\x85\x9c"; + inline constexpr char mapPause[] = "\xef\xaf\x8e"; + inline constexpr char mapPin[] = "\xee\xab\xa8"; + inline constexpr char mapPin2[] = "\xef\xb1\x88"; + inline constexpr char mapPinBolt[] = "\xef\xa5\x8a"; + inline constexpr char mapPinCancel[] = "\xef\xa5\x8b"; + inline constexpr char mapPinCheck[] = "\xef\xa5\x8c"; + inline constexpr char mapPinCode[] = "\xef\xa5\x8d"; + inline constexpr char mapPinCog[] = "\xef\xa5\x8e"; + inline constexpr char mapPinDollar[] = "\xef\xa5\x8f"; + inline constexpr char mapPinDown[] = "\xef\xa5\x90"; + inline constexpr char mapPinExclamation[] = "\xef\xa5\x91"; + inline constexpr char mapPinHeart[] = "\xef\xa5\x92"; + inline constexpr char mapPinMinus[] = "\xef\xa5\x93"; + inline constexpr char mapPinOff[] = "\xee\xb3\xb3"; + inline constexpr char mapPinPause[] = "\xef\xa5\x94"; + inline constexpr char mapPinPin[] = "\xef\xa5\x95"; + inline constexpr char mapPinPlus[] = "\xef\xa5\x96"; + inline constexpr char mapPinQuestion[] = "\xef\xa5\x97"; + inline constexpr char mapPinSearch[] = "\xef\xa5\x98"; + inline constexpr char mapPinShare[] = "\xef\x9e\x95"; + inline constexpr char mapPinStar[] = "\xef\xa5\x99"; + inline constexpr char mapPinUp[] = "\xef\xa5\x9a"; + inline constexpr char mapPinX[] = "\xef\xa5\x9b"; + inline constexpr char mapPins[] = "\xee\xb5\x9e"; + inline constexpr char mapPlus[] = "\xef\xaf\x8f"; + inline constexpr char mapQuestion[] = "\xef\xaf\x90"; + inline constexpr char mapRoute[] = "\xef\xb1\xb9"; + inline constexpr char mapSearch[] = "\xee\xbe\x82"; + inline constexpr char mapShare[] = "\xef\xaf\x91"; + inline constexpr char mapShield[] = "\xf0\x90\x88\x82"; + inline constexpr char mapSouth[] = "\xef\xb1\x9f"; + inline constexpr char mapStar[] = "\xef\xaf\x92"; + inline constexpr char mapUp[] = "\xef\xaf\x93"; + inline constexpr char mapWest[] = "\xef\xb1\xa0"; + inline constexpr char mapX[] = "\xef\xaf\x94"; + inline constexpr char markdown[] = "\xee\xb1\x81"; + inline constexpr char markdownOff[] = "\xef\x90\x87"; + inline constexpr char marquee[] = "\xee\xb1\xb7"; + inline constexpr char marquee2[] = "\xee\xba\xae"; + inline constexpr char marqueeOff[] = "\xef\x85\x9d"; + inline constexpr char mars[] = "\xee\xb2\x80"; + inline constexpr char mask[] = "\xee\xba\xb0"; + inline constexpr char maskOff[] = "\xee\xba\xaf"; + inline constexpr char masksTheater[] = "\xef\x89\xa3"; + inline constexpr char masksTheaterOff[] = "\xef\x90\x88"; + inline constexpr char massage[] = "\xee\xba\xb1"; + inline constexpr char matchstick[] = "\xef\x95\xb7"; + inline constexpr char math[] = "\xee\xaf\xab"; + inline constexpr char math1Divide2[] = "\xef\x93\xa2"; + inline constexpr char math1Divide3[] = "\xef\x93\xa3"; + inline constexpr char mathAvg[] = "\xef\x83\xb4"; + inline constexpr char mathCos[] = "\xef\xbc\x9f"; + inline constexpr char mathCtg[] = "\xef\xbc\xb5"; + inline constexpr char mathEqualGreater[] = "\xef\x93\xa4"; + inline constexpr char mathEqualLower[] = "\xef\x93\xa5"; + inline constexpr char mathFunction[] = "\xee\xba\xb2"; + inline constexpr char mathFunctionOff[] = "\xef\x85\x9e"; + inline constexpr char mathFunctionY[] = "\xef\x93\xa6"; + inline constexpr char mathGreater[] = "\xef\x93\xa7"; + inline constexpr char mathIntegral[] = "\xef\x93\xa9"; + inline constexpr char mathIntegralX[] = "\xef\x93\xa8"; + inline constexpr char mathIntegrals[] = "\xef\x93\xaa"; + inline constexpr char mathLower[] = "\xef\x93\xab"; + inline constexpr char mathMax[] = "\xef\x83\xb5"; + inline constexpr char mathMaxMin[] = "\xef\xb6\xa0"; + inline constexpr char mathMin[] = "\xef\x83\xb6"; + inline constexpr char mathNot[] = "\xef\x93\xac"; + inline constexpr char mathOff[] = "\xef\x90\x89"; + inline constexpr char mathPi[] = "\xef\x93\xae"; + inline constexpr char mathPiDivide2[] = "\xef\x93\xad"; + inline constexpr char mathSec[] = "\xef\xbc\xb4"; + inline constexpr char mathSin[] = "\xef\xbc\x9e"; + inline constexpr char mathSymbols[] = "\xee\xba\xb3"; + inline constexpr char mathTg[] = "\xef\xbc\xb3"; + inline constexpr char mathXDivide2[] = "\xef\x93\xaf"; + inline constexpr char mathXDivideY[] = "\xef\x93\xb1"; + inline constexpr char mathXDivideY2[] = "\xef\x93\xb0"; + inline constexpr char mathXFloorDivideY[] = "\xf0\x90\x81\xb3"; + inline constexpr char mathXMinusX[] = "\xef\x93\xb2"; + inline constexpr char mathXMinusY[] = "\xef\x93\xb3"; + inline constexpr char mathXPlusX[] = "\xef\x93\xb4"; + inline constexpr char mathXPlusY[] = "\xef\x93\xb5"; + inline constexpr char mathXy[] = "\xef\x93\xb6"; + inline constexpr char mathYMinusY[] = "\xef\x93\xb7"; + inline constexpr char mathYPlusY[] = "\xef\x93\xb8"; + inline constexpr char matrix[] = "\xf0\x90\x82\xbc"; + inline constexpr char maximize[] = "\xee\xab\xaa"; + inline constexpr char maximizeOff[] = "\xef\x85\x9f"; + inline constexpr char meat[] = "\xee\xbc\x92"; + inline constexpr char meatOff[] = "\xef\x90\x8a"; + inline constexpr char medal[] = "\xee\xb1\xb8"; + inline constexpr char medal2[] = "\xee\xbf\x8d"; + inline constexpr char medicalCross[] = "\xee\xb0\xaf"; + inline constexpr char medicalCrossCircle[] = "\xef\xab\xa8"; + inline constexpr char medicalCrossOff[] = "\xef\x85\xa0"; + inline constexpr char medicineSyrup[] = "\xee\xbd\xa3"; + inline constexpr char meeple[] = "\xef\x94\x94"; + inline constexpr char melon[] = "\xef\xb1\xba"; + inline constexpr char menorah[] = "\xef\x96\x8c"; + inline constexpr char menu[] = "\xee\xab\xab"; + inline constexpr char menu2[] = "\xee\xb1\x82"; + inline constexpr char menu3[] = "\xef\xbd\x83"; + inline constexpr char menu4[] = "\xef\xbd\x82"; + inline constexpr char menuDeep[] = "\xef\xab\xbb"; + inline constexpr char menuOrder[] = "\xef\x97\xb5"; + inline constexpr char mesh[] = "\xf0\x90\x88\x81"; + inline constexpr char message[] = "\xee\xab\xaf"; + inline constexpr char message2[] = "\xee\xab\xac"; + inline constexpr char message2Bolt[] = "\xef\xa5\x9c"; + inline constexpr char message2Cancel[] = "\xef\xa5\x9d"; + inline constexpr char message2Check[] = "\xef\xa5\x9e"; + inline constexpr char message2Code[] = "\xef\x80\x92"; + inline constexpr char message2Cog[] = "\xef\xa5\x9f"; + inline constexpr char message2Dollar[] = "\xef\xa5\xa0"; + inline constexpr char message2Down[] = "\xef\xa5\xa1"; + inline constexpr char message2Exclamation[] = "\xef\xa5\xa2"; + inline constexpr char message2Heart[] = "\xef\xa5\xa3"; + inline constexpr char message2Minus[] = "\xef\xa5\xa4"; + inline constexpr char message2Off[] = "\xef\x90\x8b"; + inline constexpr char message2Pause[] = "\xef\xa5\xa5"; + inline constexpr char message2Pin[] = "\xef\xa5\xa6"; + inline constexpr char message2Plus[] = "\xef\xa5\xa7"; + inline constexpr char message2Question[] = "\xef\xa5\xa8"; + inline constexpr char message2Search[] = "\xef\xa5\xa9"; + inline constexpr char message2Share[] = "\xef\x81\xb7"; + inline constexpr char message2Star[] = "\xef\xa5\xaa"; + inline constexpr char message2Up[] = "\xef\xa5\xab"; + inline constexpr char message2X[] = "\xef\xa5\xac"; + inline constexpr char messageBolt[] = "\xef\xa5\xad"; + inline constexpr char messageCancel[] = "\xef\xa5\xae"; + inline constexpr char messageChatbot[] = "\xef\x8e\x8a"; + inline constexpr char messageCheck[] = "\xef\xa5\xaf"; + inline constexpr char messageCircle[] = "\xee\xab\xad"; + inline constexpr char messageCircleBolt[] = "\xef\xa5\xb0"; + inline constexpr char messageCircleCancel[] = "\xef\xa5\xb1"; + inline constexpr char messageCircleCheck[] = "\xef\xa5\xb2"; + inline constexpr char messageCircleCode[] = "\xef\xa5\xb3"; + inline constexpr char messageCircleCog[] = "\xef\xa5\xb4"; + inline constexpr char messageCircleDollar[] = "\xef\xa5\xb5"; + inline constexpr char messageCircleDown[] = "\xef\xa5\xb6"; + inline constexpr char messageCircleExclamation[] = "\xef\xa5\xb7"; + inline constexpr char messageCircleHeart[] = "\xef\xa5\xb8"; + inline constexpr char messageCircleMinus[] = "\xef\xa5\xb9"; + inline constexpr char messageCircleOff[] = "\xee\xb5\x80"; + inline constexpr char messageCirclePause[] = "\xef\xa5\xba"; + inline constexpr char messageCirclePin[] = "\xef\xa5\xbb"; + inline constexpr char messageCirclePlus[] = "\xef\xa5\xbc"; + inline constexpr char messageCircleQuestion[] = "\xef\xa5\xbd"; + inline constexpr char messageCircleSearch[] = "\xef\xa5\xbe"; + inline constexpr char messageCircleShare[] = "\xef\xa5\xbf"; + inline constexpr char messageCircleStar[] = "\xef\xa6\x80"; + inline constexpr char messageCircleUp[] = "\xef\xa6\x81"; + inline constexpr char messageCircleUser[] = "\xef\xbb\x85"; + inline constexpr char messageCircleX[] = "\xef\xa6\x82"; + inline constexpr char messageCode[] = "\xef\x80\x93"; + inline constexpr char messageCog[] = "\xef\xa6\x83"; + inline constexpr char messageDollar[] = "\xef\xa6\x84"; + inline constexpr char messageDots[] = "\xee\xab\xae"; + inline constexpr char messageDown[] = "\xef\xa6\x85"; + inline constexpr char messageExclamation[] = "\xef\xa6\x86"; + inline constexpr char messageForward[] = "\xef\x8a\x8f"; + inline constexpr char messageHeart[] = "\xef\xa6\x87"; + inline constexpr char messageLanguage[] = "\xee\xbe\xae"; + inline constexpr char messageMinus[] = "\xef\xa6\x88"; + inline constexpr char messageOff[] = "\xee\xb5\x81"; + inline constexpr char messagePause[] = "\xef\xa6\x89"; + inline constexpr char messagePin[] = "\xef\xa6\x8a"; + inline constexpr char messagePlus[] = "\xee\xb2\x9a"; + inline constexpr char messageQuestion[] = "\xef\xa6\x8b"; + inline constexpr char messageReply[] = "\xef\xb5\x8d"; + inline constexpr char messageReport[] = "\xee\xb2\x9b"; + inline constexpr char messageSearch[] = "\xef\xa6\x8c"; + inline constexpr char messageShare[] = "\xef\x81\xb8"; + inline constexpr char messageStar[] = "\xef\xa6\x8d"; + inline constexpr char messageUp[] = "\xef\xa6\x8e"; + inline constexpr char messageUser[] = "\xef\xbb\x84"; + inline constexpr char messageX[] = "\xef\xa6\x8f"; + inline constexpr char messages[] = "\xee\xad\xac"; + inline constexpr char messagesOff[] = "\xee\xb5\x82"; + inline constexpr char meteor[] = "\xef\x87\xbd"; + inline constexpr char meteorOff[] = "\xef\x90\x8c"; + inline constexpr char meterCube[] = "\xef\xb5\xbc"; + inline constexpr char meterSquare[] = "\xef\xb5\xbd"; + inline constexpr char metronome[] = "\xef\xb4\xa5"; + inline constexpr char michelinBibGourmand[] = "\xef\xab\xa9"; + inline constexpr char michelinStar[] = "\xef\xab\xab"; + inline constexpr char michelinStarGreen[] = "\xef\xab\xaa"; + inline constexpr char mickey[] = "\xef\x8a\xa3"; + inline constexpr char microfrontends[] = "\xf0\x90\x87\xae"; + inline constexpr char microphone[] = "\xee\xab\xb0"; + inline constexpr char microphone2[] = "\xee\xbc\xac"; + inline constexpr char microphone2Off[] = "\xef\x90\x8d"; + inline constexpr char microphoneOff[] = "\xee\xb4\x96"; + inline constexpr char microscope[] = "\xee\xbd\xa4"; + inline constexpr char microscopeOff[] = "\xef\x90\x8e"; + inline constexpr char microwave[] = "\xef\x89\x88"; + inline constexpr char microwaveOff[] = "\xef\x89\xa4"; + inline constexpr char middleware[] = "\xf0\x90\x87\xad"; + inline constexpr char militaryAward[] = "\xef\x81\xb9"; + inline constexpr char militaryRank[] = "\xee\xbf\x8f"; + inline constexpr char milk[] = "\xee\xbc\x93"; + inline constexpr char milkOff[] = "\xef\x90\x8f"; + inline constexpr char milkshake[] = "\xef\x93\x88"; + inline constexpr char minimize[] = "\xee\xab\xb1"; + inline constexpr char minus[] = "\xee\xab\xb2"; + inline constexpr char minusVertical[] = "\xee\xba\xb4"; + inline constexpr char mist[] = "\xee\xb0\xb0"; + inline constexpr char mistOff[] = "\xef\x90\x90"; + inline constexpr char mobiledata[] = "\xef\xa7\xb5"; + inline constexpr char mobiledataOff[] = "\xef\xa7\xb4"; + inline constexpr char moneybag[] = "\xef\x94\x86"; + inline constexpr char moneybagEdit[] = "\xf0\x90\x84\xbd"; + inline constexpr char moneybagHeart[] = "\xf0\x90\x84\xbc"; + inline constexpr char moneybagMinus[] = "\xf0\x90\x84\xbb"; + inline constexpr char moneybagMove[] = "\xf0\x90\x84\xb9"; + inline constexpr char moneybagMoveBack[] = "\xf0\x90\x84\xba"; + inline constexpr char moneybagPlus[] = "\xf0\x90\x84\xb8"; + inline constexpr char monkeybar[] = "\xef\xba\xb4"; + inline constexpr char moodAngry[] = "\xef\x8b\x9e"; + inline constexpr char moodAnnoyed[] = "\xef\x8b\xa0"; + inline constexpr char moodAnnoyed2[] = "\xef\x8b\x9f"; + inline constexpr char moodBitcoin[] = "\xef\xbc\xb2"; + inline constexpr char moodBoy[] = "\xee\xb4\xad"; + inline constexpr char moodCheck[] = "\xef\x9e\xb3"; + inline constexpr char moodCog[] = "\xef\x9e\xb4"; + inline constexpr char moodConfused[] = "\xee\xab\xb3"; + inline constexpr char moodCrazyHappy[] = "\xee\xb6\x90"; + inline constexpr char moodCry[] = "\xee\xb2\xbb"; + inline constexpr char moodDollar[] = "\xef\x9e\xb5"; + inline constexpr char moodEdit[] = "\xef\xa8\x85"; + inline constexpr char moodEmpty[] = "\xee\xba\xb5"; + inline constexpr char moodHappy[] = "\xee\xab\xb4"; + inline constexpr char moodHeart[] = "\xef\x9e\xb6"; + inline constexpr char moodKid[] = "\xee\xb0\x83"; + inline constexpr char moodLookDown[] = "\xef\xb4\xb7"; + inline constexpr char moodLookLeft[] = "\xef\x8b\x85"; + inline constexpr char moodLookRight[] = "\xef\x8b\x86"; + inline constexpr char moodLookUp[] = "\xef\xb4\xb8"; + inline constexpr char moodMinus[] = "\xef\x9e\xb7"; + inline constexpr char moodNerd[] = "\xef\x8b\xa1"; + inline constexpr char moodNervous[] = "\xee\xbe\x96"; + inline constexpr char moodNeutral[] = "\xee\xab\xb5"; + inline constexpr char moodOff[] = "\xef\x85\xa1"; + inline constexpr char moodPin[] = "\xef\x9e\xb8"; + inline constexpr char moodPlus[] = "\xef\x9e\xb9"; + inline constexpr char moodPuzzled[] = "\xef\xb4\xb9"; + inline constexpr char moodSad[] = "\xee\xab\xb6"; + inline constexpr char moodSad2[] = "\xef\x8b\xa2"; + inline constexpr char moodSadDizzy[] = "\xef\x8b\xa3"; + inline constexpr char moodSadSquint[] = "\xef\x8b\xa4"; + inline constexpr char moodSearch[] = "\xef\x9e\xba"; + inline constexpr char moodShare[] = "\xef\xa8\x86"; + inline constexpr char moodSick[] = "\xef\x8b\xa5"; + inline constexpr char moodSilence[] = "\xef\x8b\xa6"; + inline constexpr char moodSing[] = "\xef\x8b\x87"; + inline constexpr char moodSmile[] = "\xee\xab\xb7"; + inline constexpr char moodSmileBeam[] = "\xef\x8b\xa7"; + inline constexpr char moodSmileDizzy[] = "\xef\x8b\xa8"; + inline constexpr char moodSpark[] = "\xef\xbe\xb2"; + inline constexpr char moodSurprised[] = "\xee\xb0\x84"; + inline constexpr char moodTongue[] = "\xee\xae\x95"; + inline constexpr char moodTongueWink[] = "\xef\x8b\xaa"; + inline constexpr char moodTongueWink2[] = "\xef\x8b\xa9"; + inline constexpr char moodUnamused[] = "\xef\x8b\xab"; + inline constexpr char moodUp[] = "\xef\x9e\xbb"; + inline constexpr char moodWink[] = "\xef\x8b\xad"; + inline constexpr char moodWink2[] = "\xef\x8b\xac"; + inline constexpr char moodWrrr[] = "\xef\x8b\xae"; + inline constexpr char moodX[] = "\xef\x9e\xbc"; + inline constexpr char moodXd[] = "\xef\x8b\xaf"; + inline constexpr char moon[] = "\xee\xab\xb8"; + inline constexpr char moon2[] = "\xee\xb3\xa6"; + inline constexpr char moonOff[] = "\xef\x85\xa2"; + inline constexpr char moonStars[] = "\xee\xb3\xa7"; + inline constexpr char moped[] = "\xee\xb2\xbc"; + inline constexpr char mosque[] = "\xf0\x90\x88\xb4"; + inline constexpr char motorbike[] = "\xee\xba\xb6"; + inline constexpr char mountain[] = "\xee\xbe\x97"; + inline constexpr char mountainOff[] = "\xef\x90\x91"; + inline constexpr char mouse[] = "\xee\xab\xb9"; + inline constexpr char mouse2[] = "\xef\x87\x97"; + inline constexpr char mouseOff[] = "\xef\x85\xa3"; + inline constexpr char moustache[] = "\xef\x93\x89"; + inline constexpr char movie[] = "\xee\xab\xba"; + inline constexpr char movieOff[] = "\xef\x85\xa4"; + inline constexpr char mug[] = "\xee\xab\xbb"; + inline constexpr char mugOff[] = "\xef\x85\xa5"; + inline constexpr char multiplier05x[] = "\xee\xbd\x81"; + inline constexpr char multiplier15x[] = "\xee\xbd\x82"; + inline constexpr char multiplier1x[] = "\xee\xbd\x83"; + inline constexpr char multiplier2x[] = "\xee\xbd\x84"; + inline constexpr char mushroom[] = "\xee\xbc\x94"; + inline constexpr char mushroomOff[] = "\xef\x90\x92"; + inline constexpr char music[] = "\xee\xab\xbc"; + inline constexpr char musicBolt[] = "\xef\xaf\x95"; + inline constexpr char musicCancel[] = "\xef\xaf\x96"; + inline constexpr char musicCheck[] = "\xef\xaf\x97"; + inline constexpr char musicCode[] = "\xef\xaf\x98"; + inline constexpr char musicCog[] = "\xef\xaf\x99"; + inline constexpr char musicDiscount[] = "\xef\xaf\x9a"; + inline constexpr char musicDollar[] = "\xef\xaf\x9b"; + inline constexpr char musicDown[] = "\xef\xaf\x9c"; + inline constexpr char musicExclamation[] = "\xef\xaf\x9d"; + inline constexpr char musicHeart[] = "\xef\xaf\x9e"; + inline constexpr char musicMinus[] = "\xef\xaf\x9f"; + inline constexpr char musicOff[] = "\xef\x85\xa6"; + inline constexpr char musicPause[] = "\xef\xaf\xa0"; + inline constexpr char musicPin[] = "\xef\xaf\xa1"; + inline constexpr char musicPlus[] = "\xef\xaf\xa2"; + inline constexpr char musicQuestion[] = "\xef\xaf\xa3"; + inline constexpr char musicSearch[] = "\xef\xaf\xa4"; + inline constexpr char musicShare[] = "\xef\xaf\xa5"; + inline constexpr char musicStar[] = "\xef\xaf\xa6"; + inline constexpr char musicUp[] = "\xef\xaf\xa7"; + inline constexpr char musicX[] = "\xef\xaf\xa8"; + inline constexpr char navigation[] = "\xef\x8b\x88"; + inline constexpr char navigationBolt[] = "\xef\xaf\xa9"; + inline constexpr char navigationCancel[] = "\xef\xaf\xaa"; + inline constexpr char navigationCheck[] = "\xef\xaf\xab"; + inline constexpr char navigationCode[] = "\xef\xaf\xac"; + inline constexpr char navigationCog[] = "\xef\xaf\xad"; + inline constexpr char navigationDiscount[] = "\xef\xaf\xae"; + inline constexpr char navigationDollar[] = "\xef\xaf\xaf"; + inline constexpr char navigationDown[] = "\xef\xaf\xb0"; + inline constexpr char navigationEast[] = "\xef\xb2\xba"; + inline constexpr char navigationExclamation[] = "\xef\xaf\xb1"; + inline constexpr char navigationHeart[] = "\xef\xaf\xb2"; + inline constexpr char navigationMinus[] = "\xef\xaf\xb3"; + inline constexpr char navigationNorth[] = "\xef\xb2\xbb"; + inline constexpr char navigationOff[] = "\xef\x90\x93"; + inline constexpr char navigationPause[] = "\xef\xaf\xb4"; + inline constexpr char navigationPin[] = "\xef\xaf\xb5"; + inline constexpr char navigationPlus[] = "\xef\xaf\xb6"; + inline constexpr char navigationQuestion[] = "\xef\xaf\xb7"; + inline constexpr char navigationSearch[] = "\xef\xaf\xb8"; + inline constexpr char navigationShare[] = "\xef\xaf\xb9"; + inline constexpr char navigationSouth[] = "\xef\xb2\xbc"; + inline constexpr char navigationStar[] = "\xef\xaf\xba"; + inline constexpr char navigationTop[] = "\xef\xab\xac"; + inline constexpr char navigationUp[] = "\xef\xaf\xbb"; + inline constexpr char navigationWest[] = "\xef\xb2\xbd"; + inline constexpr char navigationX[] = "\xef\xaf\xbc"; + inline constexpr char needle[] = "\xef\x94\x88"; + inline constexpr char needleThread[] = "\xef\x94\x87"; + inline constexpr char network[] = "\xef\x82\x9f"; + inline constexpr char networkOff[] = "\xef\x90\x94"; + inline constexpr char newSection[] = "\xee\xaf\x81"; + inline constexpr char news[] = "\xee\xab\xbd"; + inline constexpr char newsOff[] = "\xef\x85\xa7"; + inline constexpr char nfc[] = "\xee\xba\xb7"; + inline constexpr char nfcOff[] = "\xef\x85\xa8"; + inline constexpr char noCopyright[] = "\xee\xbe\xb9"; + inline constexpr char noCreativeCommons[] = "\xee\xbe\xba"; + inline constexpr char noDerivatives[] = "\xee\xbe\xbb"; + inline constexpr char noiseReduction[] = "\xf0\x90\x89\xa3"; + inline constexpr char northStar[] = "\xef\x80\x94"; + inline constexpr char notdef[] = "\xf0\x90\x89\x88"; + inline constexpr char note[] = "\xee\xad\xad"; + inline constexpr char noteOff[] = "\xef\x85\xa9"; + inline constexpr char notebook[] = "\xee\xae\x96"; + inline constexpr char notebookOff[] = "\xef\x90\x95"; + inline constexpr char notes[] = "\xee\xad\xae"; + inline constexpr char notesOff[] = "\xef\x85\xaa"; + inline constexpr char notification[] = "\xee\xab\xbe"; + inline constexpr char notificationOff[] = "\xef\x85\xab"; + inline constexpr char number[] = "\xef\x87\xbe"; + inline constexpr char number0[] = "\xee\xb7\xb0"; + inline constexpr char number0Small[] = "\xef\xb3\xa1"; + inline constexpr char number1[] = "\xee\xb7\xb1"; + inline constexpr char number1Small[] = "\xef\xb3\xa2"; + inline constexpr char number10[] = "\xf0\x90\x81\x9e"; + inline constexpr char number10Small[] = "\xef\xb3\xa3"; + inline constexpr char number100Small[] = "\xf0\x90\x80\x85"; + inline constexpr char number11[] = "\xf0\x90\x81\x9d"; + inline constexpr char number11Small[] = "\xef\xb3\xa4"; + inline constexpr char number12Small[] = "\xef\xb3\xa5"; + inline constexpr char number123[] = "\xef\x95\x94"; + inline constexpr char number13Small[] = "\xef\xb3\xa6"; + inline constexpr char number14Small[] = "\xef\xb3\xa7"; + inline constexpr char number15Small[] = "\xef\xb3\xa8"; + inline constexpr char number16Small[] = "\xef\xb3\xa9"; + inline constexpr char number17Small[] = "\xef\xb3\xaa"; + inline constexpr char number18Small[] = "\xef\xb3\xab"; + inline constexpr char number19Small[] = "\xef\xb3\xac"; + inline constexpr char number2[] = "\xee\xb7\xb2"; + inline constexpr char number2Small[] = "\xef\xb3\xad"; + inline constexpr char number20Small[] = "\xef\xb3\xae"; + inline constexpr char number21Small[] = "\xef\xb3\xaf"; + inline constexpr char number22Small[] = "\xef\xb3\xb0"; + inline constexpr char number23Small[] = "\xef\xb3\xb1"; + inline constexpr char number24Small[] = "\xef\xb3\xb2"; + inline constexpr char number25Small[] = "\xef\xb3\xb3"; + inline constexpr char number26Small[] = "\xef\xb3\xb4"; + inline constexpr char number27Small[] = "\xef\xb3\xb5"; + inline constexpr char number28Small[] = "\xef\xb3\xb6"; + inline constexpr char number29Small[] = "\xef\xb3\xb7"; + inline constexpr char number3[] = "\xee\xb7\xb3"; + inline constexpr char number3Small[] = "\xef\xb3\xb8"; + inline constexpr char number30Small[] = "\xf0\x90\x80\x84"; + inline constexpr char number31Small[] = "\xf0\x90\x80\x83"; + inline constexpr char number32Small[] = "\xf0\x90\x80\x82"; + inline constexpr char number33Small[] = "\xf0\x90\x80\x81"; + inline constexpr char number34Small[] = "\xf0\x90\x80\x80"; + inline constexpr char number35Small[] = "\xf0\x90\x88\x90"; + inline constexpr char number36Small[] = "\xf0\x90\x88\x91"; + inline constexpr char number37Small[] = "\xf0\x90\x88\x92"; + inline constexpr char number38Small[] = "\xf0\x90\x88\x93"; + inline constexpr char number39Small[] = "\xf0\x90\x88\x94"; + inline constexpr char number4[] = "\xee\xb7\xb4"; + inline constexpr char number4Small[] = "\xef\xb3\xb9"; + inline constexpr char number40Small[] = "\xf0\x90\x88\x95"; + inline constexpr char number41Small[] = "\xf0\x90\x88\x96"; + inline constexpr char number42Small[] = "\xf0\x90\x88\x97"; + inline constexpr char number43Small[] = "\xf0\x90\x88\x98"; + inline constexpr char number44Small[] = "\xf0\x90\x88\x99"; + inline constexpr char number45Small[] = "\xf0\x90\x88\x9a"; + inline constexpr char number46Small[] = "\xf0\x90\x88\x9b"; + inline constexpr char number47Small[] = "\xf0\x90\x88\x9c"; + inline constexpr char number48Small[] = "\xf0\x90\x88\x9d"; + inline constexpr char number49Small[] = "\xf0\x90\x88\x9e"; + inline constexpr char number5[] = "\xee\xb7\xb5"; + inline constexpr char number5Small[] = "\xef\xb3\xba"; + inline constexpr char number50Small[] = "\xf0\x90\x88\x9f"; + inline constexpr char number51Small[] = "\xef\xbf\xaf"; + inline constexpr char number52Small[] = "\xef\xbf\xae"; + inline constexpr char number53Small[] = "\xef\xbf\xad"; + inline constexpr char number54Small[] = "\xef\xbf\xac"; + inline constexpr char number55Small[] = "\xef\xbf\xab"; + inline constexpr char number56Small[] = "\xef\xbf\xaa"; + inline constexpr char number57Small[] = "\xef\xbf\xa9"; + inline constexpr char number58Small[] = "\xef\xbf\xa8"; + inline constexpr char number59Small[] = "\xef\xbf\xa7"; + inline constexpr char number6[] = "\xee\xb7\xb6"; + inline constexpr char number6Small[] = "\xef\xb3\xbb"; + inline constexpr char number60Small[] = "\xef\xbf\xa6"; + inline constexpr char number61Small[] = "\xef\xbf\xa5"; + inline constexpr char number62Small[] = "\xef\xbf\xa4"; + inline constexpr char number63Small[] = "\xef\xbf\xa3"; + inline constexpr char number64Small[] = "\xef\xbf\xa2"; + inline constexpr char number65Small[] = "\xef\xbf\xa1"; + inline constexpr char number66Small[] = "\xef\xbf\xa0"; + inline constexpr char number67Small[] = "\xef\xbf\x9f"; + inline constexpr char number68Small[] = "\xef\xbf\x9e"; + inline constexpr char number69Small[] = "\xef\xbf\x9d"; + inline constexpr char number7[] = "\xee\xb7\xb7"; + inline constexpr char number7Small[] = "\xef\xb3\xbc"; + inline constexpr char number70Small[] = "\xef\xbf\x9c"; + inline constexpr char number71Small[] = "\xef\xbf\x9b"; + inline constexpr char number72Small[] = "\xef\xbf\x9a"; + inline constexpr char number73Small[] = "\xef\xbf\x99"; + inline constexpr char number74Small[] = "\xef\xbf\x98"; + inline constexpr char number75Small[] = "\xef\xbf\x97"; + inline constexpr char number76Small[] = "\xef\xbf\x96"; + inline constexpr char number77Small[] = "\xef\xbf\x95"; + inline constexpr char number78Small[] = "\xef\xbf\x94"; + inline constexpr char number79Small[] = "\xef\xbf\x93"; + inline constexpr char number8[] = "\xee\xb7\xb8"; + inline constexpr char number8Small[] = "\xef\xb3\xbd"; + inline constexpr char number80Small[] = "\xef\xbf\x92"; + inline constexpr char number81Small[] = "\xef\xbf\x91"; + inline constexpr char number82Small[] = "\xef\xbf\x90"; + inline constexpr char number83Small[] = "\xef\xbf\x8f"; + inline constexpr char number84Small[] = "\xef\xbf\x8e"; + inline constexpr char number85Small[] = "\xef\xbf\x8d"; + inline constexpr char number86Small[] = "\xef\xbf\x8c"; + inline constexpr char number87Small[] = "\xef\xbf\x8b"; + inline constexpr char number88Small[] = "\xef\xbf\x8a"; + inline constexpr char number89Small[] = "\xef\xbf\x89"; + inline constexpr char number9[] = "\xee\xb7\xb9"; + inline constexpr char number9Small[] = "\xef\xb3\xbe"; + inline constexpr char number90Small[] = "\xef\xbf\x88"; + inline constexpr char number91Small[] = "\xef\xbf\x87"; + inline constexpr char number92Small[] = "\xef\xbf\x86"; + inline constexpr char number93Small[] = "\xef\xbf\x85"; + inline constexpr char number94Small[] = "\xef\xbf\x84"; + inline constexpr char number95Small[] = "\xef\xbf\x83"; + inline constexpr char number96Small[] = "\xef\xbf\x82"; + inline constexpr char number97Small[] = "\xef\xbf\x81"; + inline constexpr char number98Small[] = "\xef\xbf\x80"; + inline constexpr char number99Small[] = "\xef\xbe\xbf"; + inline constexpr char numbers[] = "\xef\x80\x95"; + inline constexpr char nurse[] = "\xee\xbd\xa5"; + inline constexpr char nut[] = "\xef\xb1\xa1"; + inline constexpr char objectScan[] = "\xef\xbb\xb1"; + inline constexpr char octagon[] = "\xee\xb2\xbd"; + inline constexpr char octagonMinus[] = "\xef\xb2\x92"; + inline constexpr char octagonMinus2[] = "\xef\xb2\x91"; + inline constexpr char octagonOff[] = "\xee\xba\xb8"; + inline constexpr char octagonPlus[] = "\xef\xb2\x94"; + inline constexpr char octagonPlus2[] = "\xef\xb2\x93"; + inline constexpr char octahedron[] = "\xef\xaa\xae"; + inline constexpr char octahedronOff[] = "\xef\xaa\xac"; + inline constexpr char octahedronPlus[] = "\xef\xaa\xad"; + inline constexpr char old[] = "\xee\xba\xb9"; + inline constexpr char olympicTorch[] = "\xf0\x90\x88\xa8"; + inline constexpr char olympics[] = "\xee\xba\xba"; + inline constexpr char olympicsOff[] = "\xef\x90\x96"; + inline constexpr char om[] = "\xef\x96\x8d"; + inline constexpr char omega[] = "\xee\xae\x97"; + inline constexpr char option[] = "\xf0\x90\x86\x9f"; + inline constexpr char outbound[] = "\xef\x89\x89"; + inline constexpr char outlet[] = "\xee\xaf\x97"; + inline constexpr char oval[] = "\xef\x80\xae"; + inline constexpr char ovalVertical[] = "\xef\x80\xad"; + inline constexpr char overline[] = "\xee\xba\xbb"; + inline constexpr char package[] = "\xee\xab\xbf"; + inline constexpr char packageExport[] = "\xef\x81\xba"; + inline constexpr char packageImport[] = "\xef\x81\xbb"; + inline constexpr char packageOff[] = "\xef\x85\xac"; + inline constexpr char packages[] = "\xef\x8b\x89"; + inline constexpr char pacman[] = "\xee\xba\xbc"; + inline constexpr char pageBreak[] = "\xee\xb2\x81"; + inline constexpr char paint[] = "\xee\xac\x80"; + inline constexpr char paintOff[] = "\xef\x85\xad"; + inline constexpr char palette[] = "\xee\xac\x81"; + inline constexpr char paletteOff[] = "\xef\x85\xae"; + inline constexpr char panoramaHorizontal[] = "\xee\xb4\xb3"; + inline constexpr char panoramaHorizontalOff[] = "\xef\x90\x97"; + inline constexpr char panoramaVertical[] = "\xee\xb4\xb4"; + inline constexpr char panoramaVerticalOff[] = "\xef\x90\x98"; + inline constexpr char paperBag[] = "\xef\x80\xaf"; + inline constexpr char paperBagOff[] = "\xef\x85\xaf"; + inline constexpr char paperclip[] = "\xee\xac\x82"; + inline constexpr char parachute[] = "\xee\xb5\xbc"; + inline constexpr char parachuteOff[] = "\xef\x85\xb0"; + inline constexpr char parentheses[] = "\xee\xaf\x98"; + inline constexpr char parenthesesOff[] = "\xef\x85\xb1"; + inline constexpr char parking[] = "\xee\xac\x83"; + inline constexpr char parkingCircle[] = "\xef\xb5\x9a"; + inline constexpr char parkingMeter[] = "\xf0\x90\x88\xa7"; + inline constexpr char parkingOff[] = "\xef\x85\xb2"; + inline constexpr char password[] = "\xef\x93\x8a"; + inline constexpr char passwordFingerprint[] = "\xef\xb1\xbb"; + inline constexpr char passwordMobilePhone[] = "\xef\xb1\xbc"; + inline constexpr char passwordUser[] = "\xef\xb1\xbd"; + inline constexpr char paw[] = "\xee\xbf\xb9"; + inline constexpr char pawOff[] = "\xef\x90\x99"; + inline constexpr char paywall[] = "\xef\xb5\xbe"; + inline constexpr char pdf[] = "\xef\x9e\xac"; + inline constexpr char peace[] = "\xee\xb2\xbe"; + inline constexpr char pencil[] = "\xee\xac\x84"; + inline constexpr char pencilBolt[] = "\xef\xaf\xbd"; + inline constexpr char pencilCancel[] = "\xef\xaf\xbe"; + inline constexpr char pencilCheck[] = "\xef\xaf\xbf"; + inline constexpr char pencilCode[] = "\xef\xb0\x80"; + inline constexpr char pencilCog[] = "\xef\xb0\x81"; + inline constexpr char pencilDiscount[] = "\xef\xb0\x82"; + inline constexpr char pencilDollar[] = "\xef\xb0\x83"; + inline constexpr char pencilDown[] = "\xef\xb0\x84"; + inline constexpr char pencilExclamation[] = "\xef\xb0\x85"; + inline constexpr char pencilHeart[] = "\xef\xb0\x86"; + inline constexpr char pencilMinus[] = "\xef\x87\xab"; + inline constexpr char pencilOff[] = "\xef\x85\xb3"; + inline constexpr char pencilPause[] = "\xef\xb0\x87"; + inline constexpr char pencilPin[] = "\xef\xb0\x88"; + inline constexpr char pencilPlus[] = "\xef\x87\xac"; + inline constexpr char pencilQuestion[] = "\xef\xb0\x89"; + inline constexpr char pencilSearch[] = "\xef\xb0\x8a"; + inline constexpr char pencilShare[] = "\xef\xb0\x8b"; + inline constexpr char pencilStar[] = "\xef\xb0\x8c"; + inline constexpr char pencilUp[] = "\xef\xb0\x8d"; + inline constexpr char pencilX[] = "\xef\xb0\x8e"; + inline constexpr char pendulum[] = "\xf0\x90\x88\xb3"; + inline constexpr char pennant[] = "\xee\xb5\xbd"; + inline constexpr char pennant2[] = "\xef\x81\xaa"; + inline constexpr char pennantOff[] = "\xef\x85\xb4"; + inline constexpr char pentagon[] = "\xee\xbf\xa3"; + inline constexpr char pentagonMinus[] = "\xef\xba\xb3"; + inline constexpr char pentagonNumber0[] = "\xef\xb1\xbe"; + inline constexpr char pentagonNumber1[] = "\xef\xb1\xbf"; + inline constexpr char pentagonNumber2[] = "\xef\xb2\x80"; + inline constexpr char pentagonNumber3[] = "\xef\xb2\x81"; + inline constexpr char pentagonNumber4[] = "\xef\xb2\x82"; + inline constexpr char pentagonNumber5[] = "\xef\xb2\x83"; + inline constexpr char pentagonNumber6[] = "\xef\xb2\x84"; + inline constexpr char pentagonNumber7[] = "\xef\xb2\x85"; + inline constexpr char pentagonNumber8[] = "\xef\xb2\x86"; + inline constexpr char pentagonNumber9[] = "\xef\xb2\x87"; + inline constexpr char pentagonOff[] = "\xef\x90\x9a"; + inline constexpr char pentagonPlus[] = "\xef\xb1\x89"; + inline constexpr char pentagonX[] = "\xef\xb2\x88"; + inline constexpr char pentagram[] = "\xef\x96\x86"; + inline constexpr char pepper[] = "\xee\xbc\x95"; + inline constexpr char pepperOff[] = "\xef\x85\xb5"; + inline constexpr char percentage[] = "\xee\xb3\xb4"; + inline constexpr char percentage0[] = "\xef\xbb\xa5"; + inline constexpr char percentage10[] = "\xef\xbb\xa4"; + inline constexpr char percentage100[] = "\xef\xbb\xa3"; + inline constexpr char percentage20[] = "\xef\xbb\xa2"; + inline constexpr char percentage25[] = "\xef\xbb\xa1"; + inline constexpr char percentage30[] = "\xef\xbb\xa0"; + inline constexpr char percentage33[] = "\xef\xbb\x9f"; + inline constexpr char percentage40[] = "\xef\xbb\x9e"; + inline constexpr char percentage50[] = "\xef\xbb\x9d"; + inline constexpr char percentage60[] = "\xef\xbb\x9c"; + inline constexpr char percentage66[] = "\xef\xbb\x9b"; + inline constexpr char percentage70[] = "\xef\xbb\x9a"; + inline constexpr char percentage75[] = "\xef\xbb\x99"; + inline constexpr char percentage80[] = "\xef\xbb\x98"; + inline constexpr char percentage90[] = "\xef\xbb\x97"; + inline constexpr char perfume[] = "\xef\x94\x89"; + inline constexpr char perspective[] = "\xee\xba\xbd"; + inline constexpr char perspectiveOff[] = "\xef\x85\xb6"; + inline constexpr char phone[] = "\xee\xac\x89"; + inline constexpr char phoneCall[] = "\xee\xac\x85"; + inline constexpr char phoneCalling[] = "\xee\xb1\x83"; + inline constexpr char phoneCheck[] = "\xee\xb0\x85"; + inline constexpr char phoneDone[] = "\xef\xbe\x9e"; + inline constexpr char phoneEnd[] = "\xef\xbe\x9d"; + inline constexpr char phoneIncoming[] = "\xee\xac\x86"; + inline constexpr char phoneOff[] = "\xee\xb3\xb5"; + inline constexpr char phoneOutgoing[] = "\xee\xac\x87"; + inline constexpr char phonePause[] = "\xee\xac\x88"; + inline constexpr char phonePlus[] = "\xee\xb0\x86"; + inline constexpr char phoneRinging[] = "\xef\xbe\x9c"; + inline constexpr char phoneSpark[] = "\xef\xbe\xb1"; + inline constexpr char phoneX[] = "\xee\xb0\x87"; + inline constexpr char photo[] = "\xee\xac\x8a"; + inline constexpr char photoAi[] = "\xef\xa8\xb2"; + inline constexpr char photoAlt[] = "\xf0\x90\x89\xa2"; + inline constexpr char photoBitcoin[] = "\xef\xbc\xb1"; + inline constexpr char photoBolt[] = "\xef\xa6\x90"; + inline constexpr char photoCancel[] = "\xef\x8d\x9d"; + inline constexpr char photoCheck[] = "\xef\x8d\x9e"; + inline constexpr char photoCircle[] = "\xef\xb1\x8a"; + inline constexpr char photoCircleMinus[] = "\xef\xb1\xa2"; + inline constexpr char photoCirclePlus[] = "\xef\xb1\xa3"; + inline constexpr char photoCode[] = "\xef\xa6\x91"; + inline constexpr char photoCog[] = "\xef\xa6\x92"; + inline constexpr char photoDollar[] = "\xef\xa6\x93"; + inline constexpr char photoDown[] = "\xef\x8d\x9f"; + inline constexpr char photoEdit[] = "\xef\x8d\xa0"; + inline constexpr char photoExclamation[] = "\xef\xa6\x94"; + inline constexpr char photoHeart[] = "\xef\x8d\xa1"; + inline constexpr char photoHexagon[] = "\xef\xb1\x8b"; + inline constexpr char photoMinus[] = "\xef\x8d\xa2"; + inline constexpr char photoOff[] = "\xee\xb3\xb6"; + inline constexpr char photoPause[] = "\xef\xa6\x95"; + inline constexpr char photoPentagon[] = "\xef\xb1\x8c"; + inline constexpr char photoPin[] = "\xef\xa6\x96"; + inline constexpr char photoPlus[] = "\xef\x8d\xa3"; + inline constexpr char photoQuestion[] = "\xef\xa6\x97"; + inline constexpr char photoScan[] = "\xef\xb2\xa8"; + inline constexpr char photoSearch[] = "\xef\x8d\xa4"; + inline constexpr char photoSensor[] = "\xef\x9e\x98"; + inline constexpr char photoSensor2[] = "\xef\x9e\x96"; + inline constexpr char photoSensor3[] = "\xef\x9e\x97"; + inline constexpr char photoShare[] = "\xef\xa6\x98"; + inline constexpr char photoShield[] = "\xef\x8d\xa5"; + inline constexpr char photoSpark[] = "\xef\xbe\xb0"; + inline constexpr char photoSquareRounded[] = "\xef\xb1\x8d"; + inline constexpr char photoStar[] = "\xef\x8d\xa6"; + inline constexpr char photoUp[] = "\xef\x8e\x8b"; + inline constexpr char photoVideo[] = "\xef\xb2\x95"; + inline constexpr char photoX[] = "\xef\x8d\xa7"; + inline constexpr char physiotherapist[] = "\xee\xba\xbe"; + inline constexpr char piano[] = "\xef\xab\x93"; + inline constexpr char pick[] = "\xef\xab\xbc"; + inline constexpr char picnicTable[] = "\xef\xbb\x96"; + inline constexpr char pictureInPicture[] = "\xee\xb4\xb5"; + inline constexpr char pictureInPictureOff[] = "\xee\xb5\x83"; + inline constexpr char pictureInPictureOn[] = "\xee\xb5\x84"; + inline constexpr char pictureInPictureTop[] = "\xee\xbf\xa4"; + inline constexpr char pig[] = "\xee\xbd\x92"; + inline constexpr char pigMoney[] = "\xef\x8e\x8c"; + inline constexpr char pigOff[] = "\xef\x85\xb7"; + inline constexpr char pilcrow[] = "\xef\x97\xb6"; + inline constexpr char pilcrowLeft[] = "\xef\xb5\xbf"; + inline constexpr char pilcrowRight[] = "\xef\xb6\x80"; + inline constexpr char pill[] = "\xee\xb1\x84"; + inline constexpr char pillOff[] = "\xef\x85\xb8"; + inline constexpr char pillow[] = "\xf0\x90\x88\xa6"; + inline constexpr char pills[] = "\xee\xbd\xa6"; + inline constexpr char pin[] = "\xee\xb2\x9c"; + inline constexpr char pinEnd[] = "\xef\xb5\x9b"; + inline constexpr char pinInvoke[] = "\xef\xb5\x9c"; + inline constexpr char pingPong[] = "\xef\x8e\x8d"; + inline constexpr char pinned[] = "\xee\xb5\xa0"; + inline constexpr char pinnedOff[] = "\xee\xb5\x9f"; + inline constexpr char pipeline[] = "\xf0\x90\x88\xa5"; + inline constexpr char pizza[] = "\xee\xb6\xbb"; + inline constexpr char pizzaOff[] = "\xef\x85\xb9"; + inline constexpr char placeholder[] = "\xef\x98\xa6"; + inline constexpr char plane[] = "\xee\xad\xaf"; + inline constexpr char planeArrival[] = "\xee\xae\x99"; + inline constexpr char planeDeparture[] = "\xee\xae\x9a"; + inline constexpr char planeInflight[] = "\xee\xbe\x98"; + inline constexpr char planeOff[] = "\xef\x85\xba"; + inline constexpr char planeTilt[] = "\xef\x87\xad"; + inline constexpr char planet[] = "\xee\xb0\x88"; + inline constexpr char planetOff[] = "\xef\x85\xbb"; + inline constexpr char plant[] = "\xee\xb5\x90"; + inline constexpr char plant2[] = "\xee\xb5\xbe"; + inline constexpr char plant2Off[] = "\xef\x85\xbc"; + inline constexpr char plantOff[] = "\xef\x85\xbd"; + inline constexpr char playBasketball[] = "\xef\xa9\xa6"; + inline constexpr char playCard[] = "\xee\xba\xbf"; + inline constexpr char playCard1[] = "\xf0\x90\x81\x9c"; + inline constexpr char playCard10[] = "\xf0\x90\x81\x9b"; + inline constexpr char playCard2[] = "\xf0\x90\x81\x9a"; + inline constexpr char playCard3[] = "\xf0\x90\x81\x99"; + inline constexpr char playCard4[] = "\xf0\x90\x81\x98"; + inline constexpr char playCard5[] = "\xf0\x90\x81\x97"; + inline constexpr char playCard6[] = "\xf0\x90\x81\x96"; + inline constexpr char playCard7[] = "\xf0\x90\x81\x95"; + inline constexpr char playCard8[] = "\xf0\x90\x81\x94"; + inline constexpr char playCard9[] = "\xf0\x90\x81\x93"; + inline constexpr char playCardA[] = "\xf0\x90\x81\x92"; + inline constexpr char playCardJ[] = "\xf0\x90\x81\x91"; + inline constexpr char playCardK[] = "\xf0\x90\x81\x90"; + inline constexpr char playCardOff[] = "\xef\x85\xbe"; + inline constexpr char playCardQ[] = "\xf0\x90\x81\x8f"; + inline constexpr char playCardStar[] = "\xf0\x90\x81\x8e"; + inline constexpr char playFootball[] = "\xef\xa9\xa7"; + inline constexpr char playHandball[] = "\xef\xa9\xa8"; + inline constexpr char playVolleyball[] = "\xef\xa9\xa9"; + inline constexpr char playerEject[] = "\xee\xbe\xbc"; + inline constexpr char playerPause[] = "\xee\xb5\x85"; + inline constexpr char playerPlay[] = "\xee\xb5\x86"; + inline constexpr char playerRecord[] = "\xee\xb5\x87"; + inline constexpr char playerSkipBack[] = "\xee\xb5\x88"; + inline constexpr char playerSkipForward[] = "\xee\xb5\x89"; + inline constexpr char playerStop[] = "\xee\xb5\x8a"; + inline constexpr char playerTrackNext[] = "\xee\xb5\x8b"; + inline constexpr char playerTrackPrev[] = "\xee\xb5\x8c"; + inline constexpr char playlist[] = "\xee\xbb\x80"; + inline constexpr char playlistAdd[] = "\xef\x80\x88"; + inline constexpr char playlistOff[] = "\xef\x85\xbf"; + inline constexpr char playlistX[] = "\xef\x80\x89"; + inline constexpr char playstationCircle[] = "\xef\x8a\xad"; + inline constexpr char playstationSquare[] = "\xef\x8a\xae"; + inline constexpr char playstationTriangle[] = "\xef\x8a\xaf"; + inline constexpr char playstationX[] = "\xef\x8a\xb0"; + inline constexpr char plug[] = "\xee\xaf\x99"; + inline constexpr char plugConnected[] = "\xef\x80\x8a"; + inline constexpr char plugConnectedX[] = "\xef\x82\xa0"; + inline constexpr char plugOff[] = "\xef\x86\x80"; + inline constexpr char plugX[] = "\xef\x82\xa1"; + inline constexpr char plunger[] = "\xf0\x90\x88\xb2"; + inline constexpr char plus[] = "\xee\xac\x8b"; + inline constexpr char plusEqual[] = "\xef\x9e\xad"; + inline constexpr char plusMinus[] = "\xef\x9e\xae"; + inline constexpr char png[] = "\xef\x8e\xad"; + inline constexpr char podium[] = "\xef\x87\x98"; + inline constexpr char podiumOff[] = "\xef\x90\x9b"; + inline constexpr char point[] = "\xee\xac\x8c"; + inline constexpr char pointOff[] = "\xef\x86\x81"; + inline constexpr char pointer[] = "\xef\x89\xa5"; + inline constexpr char pointer2[] = "\xf0\x90\x89\xa1"; + inline constexpr char pointerBolt[] = "\xef\xa6\x99"; + inline constexpr char pointerCancel[] = "\xef\xa6\x9a"; + inline constexpr char pointerCheck[] = "\xef\xa6\x9b"; + inline constexpr char pointerCode[] = "\xef\xa6\x9c"; + inline constexpr char pointerCog[] = "\xef\xa6\x9d"; + inline constexpr char pointerCollaboration[] = "\xf0\x90\x89\x9f"; + inline constexpr char pointerCollaboration2[] = "\xf0\x90\x89\xa0"; + inline constexpr char pointerDollar[] = "\xef\xa6\x9e"; + inline constexpr char pointerDown[] = "\xef\xa6\x9f"; + inline constexpr char pointerExclamation[] = "\xef\xa6\xa0"; + inline constexpr char pointerHeart[] = "\xef\xa6\xa1"; + inline constexpr char pointerMinus[] = "\xef\xa6\xa2"; + inline constexpr char pointerOff[] = "\xef\xa6\xa3"; + inline constexpr char pointerPause[] = "\xef\xa6\xa4"; + inline constexpr char pointerPin[] = "\xef\xa6\xa5"; + inline constexpr char pointerPlus[] = "\xef\xa6\xa6"; + inline constexpr char pointerQuestion[] = "\xef\xa6\xa7"; + inline constexpr char pointerSearch[] = "\xef\xa6\xa8"; + inline constexpr char pointerShare[] = "\xef\xa6\xa9"; + inline constexpr char pointerStar[] = "\xef\xa6\xaa"; + inline constexpr char pointerUp[] = "\xef\xa6\xab"; + inline constexpr char pointerX[] = "\xef\xa6\xac"; + inline constexpr char pokeball[] = "\xee\xbb\x81"; + inline constexpr char pokeballOff[] = "\xef\x90\x9c"; + inline constexpr char pokerChip[] = "\xef\x94\x95"; + inline constexpr char polaroid[] = "\xee\xbb\x82"; + inline constexpr char polygon[] = "\xee\xbf\x90"; + inline constexpr char polygonOff[] = "\xef\x86\x82"; + inline constexpr char poo[] = "\xef\x89\x98"; + inline constexpr char pool[] = "\xee\xb6\x91"; + inline constexpr char poolOff[] = "\xef\x90\x9d"; + inline constexpr char power[] = "\xee\xac\x8d"; + inline constexpr char pray[] = "\xee\xb2\xbf"; + inline constexpr char premiumRights[] = "\xee\xbe\xbd"; + inline constexpr char prescription[] = "\xee\xbe\x99"; + inline constexpr char presentation[] = "\xee\xad\xb0"; + inline constexpr char presentationAnalytics[] = "\xee\xbb\x83"; + inline constexpr char presentationOff[] = "\xef\x86\x83"; + inline constexpr char printer[] = "\xee\xac\x8e"; + inline constexpr char printerOff[] = "\xef\x86\x84"; + inline constexpr char prism[] = "\xef\xaa\xb1"; + inline constexpr char prismLight[] = "\xef\xba\xa6"; + inline constexpr char prismOff[] = "\xef\xaa\xaf"; + inline constexpr char prismPlus[] = "\xef\xaa\xb0"; + inline constexpr char prison[] = "\xee\xbd\xb9"; + inline constexpr char progress[] = "\xef\xa8\x8d"; + inline constexpr char progressAlert[] = "\xef\xa8\x87"; + inline constexpr char progressBolt[] = "\xef\xa8\x88"; + inline constexpr char progressCheck[] = "\xef\xa8\x89"; + inline constexpr char progressDown[] = "\xef\xa8\x8a"; + inline constexpr char progressHelp[] = "\xef\xa8\x8b"; + inline constexpr char progressX[] = "\xef\xa8\x8c"; + inline constexpr char prompt[] = "\xee\xac\x8f"; + inline constexpr char prong[] = "\xef\xb6\xa1"; + inline constexpr char propeller[] = "\xee\xbb\x84"; + inline constexpr char propellerOff[] = "\xef\x86\x85"; + inline constexpr char protocol[] = "\xef\xb6\x81"; + inline constexpr char pumpkinScary[] = "\xef\x96\x87"; + inline constexpr char puzzle[] = "\xee\xac\x90"; + inline constexpr char puzzle2[] = "\xee\xbe\x83"; + inline constexpr char puzzleOff[] = "\xef\x86\x86"; + inline constexpr char pyramid[] = "\xee\xbb\x85"; + inline constexpr char pyramidOff[] = "\xef\x86\x87"; + inline constexpr char pyramidPlus[] = "\xef\xaa\xb2"; + inline constexpr char qrcode[] = "\xee\xac\x91"; + inline constexpr char qrcodeOff[] = "\xef\x90\x9e"; + inline constexpr char questionMark[] = "\xee\xb2\x9d"; + inline constexpr char queuePopIn[] = "\xf0\x90\x88\x80"; + inline constexpr char queuePopOut[] = "\xf0\x90\x87\xbf"; + inline constexpr char quote[] = "\xee\xbe\xbe"; + inline constexpr char quoteOff[] = "\xef\x86\x88"; + inline constexpr char quoteOpen[] = "\xf0\x90\x88\xa4"; + inline constexpr char quotes[] = "\xef\xac\x9e"; + inline constexpr char radar[] = "\xef\x80\x97"; + inline constexpr char radar2[] = "\xef\x80\x96"; + inline constexpr char radarOff[] = "\xef\x90\x9f"; + inline constexpr char radio[] = "\xee\xbc\xad"; + inline constexpr char radioOff[] = "\xef\x90\xa0"; + inline constexpr char radioactive[] = "\xee\xb3\x80"; + inline constexpr char radioactiveOff[] = "\xef\x86\x89"; + inline constexpr char radiusBottomLeft[] = "\xee\xbb\x86"; + inline constexpr char radiusBottomRight[] = "\xee\xbb\x87"; + inline constexpr char radiusTopLeft[] = "\xee\xbb\x88"; + inline constexpr char radiusTopRight[] = "\xee\xbb\x89"; + inline constexpr char rainbow[] = "\xee\xb6\xbc"; + inline constexpr char rainbowOff[] = "\xef\x86\x8a"; + inline constexpr char rating12Plus[] = "\xef\x89\xa6"; + inline constexpr char rating14Plus[] = "\xef\x89\xa7"; + inline constexpr char rating16Plus[] = "\xef\x89\xa8"; + inline constexpr char rating18Plus[] = "\xef\x89\xa9"; + inline constexpr char rating21Plus[] = "\xef\x89\xaa"; + inline constexpr char razor[] = "\xef\x92\xb5"; + inline constexpr char razorElectric[] = "\xef\x92\xb4"; + inline constexpr char receipt[] = "\xee\xb7\xbd"; + inline constexpr char receipt2[] = "\xee\xb7\xba"; + inline constexpr char receiptBitcoin[] = "\xef\xb5\xa6"; + inline constexpr char receiptDollar[] = "\xef\xb5\xa7"; + inline constexpr char receiptEuro[] = "\xef\xb5\xa8"; + inline constexpr char receiptOff[] = "\xee\xb7\xbb"; + inline constexpr char receiptPound[] = "\xef\xb5\xa9"; + inline constexpr char receiptRefund[] = "\xee\xb7\xbc"; + inline constexpr char receiptRupee[] = "\xef\xb6\x82"; + inline constexpr char receiptTax[] = "\xee\xb6\xbd"; + inline constexpr char receiptYen[] = "\xef\xb5\xaa"; + inline constexpr char receiptYuan[] = "\xef\xb5\xab"; + inline constexpr char recharging[] = "\xee\xbb\x8a"; + inline constexpr char recordMail[] = "\xee\xac\x92"; + inline constexpr char recordMailOff[] = "\xef\x86\x8b"; + inline constexpr char rectangle[] = "\xee\xb4\xb7"; + inline constexpr char rectangleRoundedBottom[] = "\xef\xab\xad"; + inline constexpr char rectangleRoundedTop[] = "\xef\xab\xae"; + inline constexpr char rectangleVertical[] = "\xee\xb4\xb6"; + inline constexpr char rectangularPrism[] = "\xef\xaa\xb5"; + inline constexpr char rectangularPrismOff[] = "\xef\xaa\xb3"; + inline constexpr char rectangularPrismPlus[] = "\xef\xaa\xb4"; + inline constexpr char recycle[] = "\xee\xae\x9b"; + inline constexpr char recycleOff[] = "\xef\x86\x8c"; + inline constexpr char refresh[] = "\xee\xac\x93"; + inline constexpr char refreshAlert[] = "\xee\xb5\x97"; + inline constexpr char refreshDot[] = "\xee\xbe\xbf"; + inline constexpr char refreshOff[] = "\xef\x86\x8d"; + inline constexpr char regex[] = "\xef\x8c\x9f"; + inline constexpr char regexOff[] = "\xef\x90\xa1"; + inline constexpr char registered[] = "\xee\xac\x94"; + inline constexpr char relationManyToMany[] = "\xee\xb5\xbf"; + inline constexpr char relationOneToMany[] = "\xee\xb6\x80"; + inline constexpr char relationOneToOne[] = "\xee\xb6\x81"; + inline constexpr char reload[] = "\xef\x8e\xae"; + inline constexpr char reorder[] = "\xef\xb0\x95"; + inline constexpr char repeat[] = "\xee\xad\xb2"; + inline constexpr char repeatOff[] = "\xef\x86\x8e"; + inline constexpr char repeatOnce[] = "\xee\xad\xb1"; + inline constexpr char replace[] = "\xee\xaf\x87"; + inline constexpr char replaceOff[] = "\xef\x90\xa2"; + inline constexpr char replaceUser[] = "\xf0\x90\x83\xb0"; + inline constexpr char report[] = "\xee\xbb\x8e"; + inline constexpr char reportAnalytics[] = "\xee\xbb\x8b"; + inline constexpr char reportMedical[] = "\xee\xbb\x8c"; + inline constexpr char reportMoney[] = "\xee\xbb\x8d"; + inline constexpr char reportOff[] = "\xef\x86\x8f"; + inline constexpr char reportSearch[] = "\xee\xbe\x84"; + inline constexpr char reservedLine[] = "\xef\xa7\xb6"; + inline constexpr char resize[] = "\xee\xbb\x8f"; + inline constexpr char restore[] = "\xef\xab\xbd"; + inline constexpr char rewindBackward10[] = "\xef\xaa\xba"; + inline constexpr char rewindBackward15[] = "\xef\xaa\xbb"; + inline constexpr char rewindBackward20[] = "\xef\xaa\xbc"; + inline constexpr char rewindBackward30[] = "\xef\xaa\xbd"; + inline constexpr char rewindBackward40[] = "\xef\xaa\xbe"; + inline constexpr char rewindBackward5[] = "\xef\xaa\xbf"; + inline constexpr char rewindBackward50[] = "\xef\xab\x80"; + inline constexpr char rewindBackward60[] = "\xef\xab\x81"; + inline constexpr char rewindForward10[] = "\xef\xab\x82"; + inline constexpr char rewindForward15[] = "\xef\xab\x83"; + inline constexpr char rewindForward20[] = "\xef\xab\x84"; + inline constexpr char rewindForward30[] = "\xef\xab\x85"; + inline constexpr char rewindForward40[] = "\xef\xab\x86"; + inline constexpr char rewindForward5[] = "\xef\xab\x87"; + inline constexpr char rewindForward50[] = "\xef\xab\x88"; + inline constexpr char rewindForward60[] = "\xef\xab\x89"; + inline constexpr char ribbonHealth[] = "\xef\x96\x8e"; + inline constexpr char rings[] = "\xef\xa9\xaa"; + inline constexpr char ripple[] = "\xee\xb6\x82"; + inline constexpr char rippleDown[] = "\xf0\x90\x86\xaa"; + inline constexpr char rippleOff[] = "\xef\x86\x90"; + inline constexpr char rippleUp[] = "\xf0\x90\x86\xa9"; + inline constexpr char road[] = "\xef\x80\x98"; + inline constexpr char roadOff[] = "\xef\x86\x91"; + inline constexpr char roadSign[] = "\xee\xb3\x9d"; + inline constexpr char robot[] = "\xef\x80\x8b"; + inline constexpr char robotFace[] = "\xef\xb2\xbe"; + inline constexpr char robotOff[] = "\xef\x86\x92"; + inline constexpr char rocket[] = "\xee\xb1\x85"; + inline constexpr char rocketOff[] = "\xef\x86\x93"; + inline constexpr char rollerSkating[] = "\xee\xbf\x91"; + inline constexpr char rollercoaster[] = "\xef\x82\xa2"; + inline constexpr char rollercoasterOff[] = "\xef\x90\xa3"; + inline constexpr char rosette[] = "\xef\x96\x99"; + inline constexpr char rosetteAsterisk[] = "\xf0\x90\x86\xa8"; + inline constexpr char rosetteDiscount[] = "\xee\xb9\xbc"; + inline constexpr char rosetteDiscountCheck[] = "\xef\x87\xb8"; + inline constexpr char rosetteDiscountCheckOff[] = "\xef\xbc\x90"; + inline constexpr char rosetteDiscountOff[] = "\xef\x8f\xa6"; + inline constexpr char rosetteNumber0[] = "\xef\x96\x8f"; + inline constexpr char rosetteNumber1[] = "\xef\x96\x90"; + inline constexpr char rosetteNumber2[] = "\xef\x96\x91"; + inline constexpr char rosetteNumber3[] = "\xef\x96\x92"; + inline constexpr char rosetteNumber4[] = "\xef\x96\x93"; + inline constexpr char rosetteNumber5[] = "\xef\x96\x94"; + inline constexpr char rosetteNumber6[] = "\xef\x96\x95"; + inline constexpr char rosetteNumber7[] = "\xef\x96\x96"; + inline constexpr char rosetteNumber8[] = "\xef\x96\x97"; + inline constexpr char rosetteNumber9[] = "\xef\x96\x98"; + inline constexpr char rotate[] = "\xee\xac\x96"; + inline constexpr char rotate2[] = "\xee\xae\xb4"; + inline constexpr char rotate360[] = "\xee\xbe\x85"; + inline constexpr char rotate3d[] = "\xef\x80\xa0"; + inline constexpr char rotateClockwise[] = "\xee\xac\x95"; + inline constexpr char rotateClockwise2[] = "\xee\xae\xb5"; + inline constexpr char rotateDot[] = "\xee\xbf\xa5"; + inline constexpr char rotateRectangle[] = "\xee\xb0\x95"; + inline constexpr char roulette[] = "\xf0\x90\x89\x9e"; + inline constexpr char route[] = "\xee\xac\x97"; + inline constexpr char route2[] = "\xef\x92\xb6"; + inline constexpr char routeAltLeft[] = "\xef\xb2\xa9"; + inline constexpr char routeAltRight[] = "\xef\xb2\xaa"; + inline constexpr char routeOff[] = "\xef\x86\x94"; + inline constexpr char routeScan[] = "\xef\xb2\xbf"; + inline constexpr char routeSquare[] = "\xef\xb2\xac"; + inline constexpr char routeSquare2[] = "\xef\xb2\xab"; + inline constexpr char routeX[] = "\xef\xb2\xae"; + inline constexpr char routeX2[] = "\xef\xb2\xad"; + inline constexpr char router[] = "\xee\xac\x98"; + inline constexpr char routerOff[] = "\xef\x90\xa4"; + inline constexpr char rowInsertBottom[] = "\xee\xbb\x90"; + inline constexpr char rowInsertTop[] = "\xee\xbb\x91"; + inline constexpr char rowRemove[] = "\xef\xab\xbe"; + inline constexpr char rss[] = "\xee\xac\x99"; + inline constexpr char rubberStamp[] = "\xef\x96\xab"; + inline constexpr char rubberStampOff[] = "\xef\x96\xaa"; + inline constexpr char rugby[] = "\xf0\x90\x89\x87"; + inline constexpr char ruler[] = "\xee\xac\x9a"; + inline constexpr char ruler2[] = "\xee\xbb\x92"; + inline constexpr char ruler2Off[] = "\xef\x86\x95"; + inline constexpr char ruler3[] = "\xef\x8a\x90"; + inline constexpr char rulerMeasure[] = "\xef\x8a\x91"; + inline constexpr char rulerMeasure2[] = "\xef\xbc\x8f"; + inline constexpr char rulerOff[] = "\xef\x86\x96"; + inline constexpr char run[] = "\xee\xb2\x82"; + inline constexpr char rvTruck[] = "\xef\xb3\x80"; + inline constexpr char sTurnDown[] = "\xef\x94\x96"; + inline constexpr char sTurnLeft[] = "\xef\x94\x97"; + inline constexpr char sTurnRight[] = "\xef\x94\x98"; + inline constexpr char sTurnUp[] = "\xef\x94\x99"; + inline constexpr char sailboat[] = "\xee\xb2\x83"; + inline constexpr char sailboat2[] = "\xef\x97\xb7"; + inline constexpr char sailboatOff[] = "\xef\x90\xa5"; + inline constexpr char salad[] = "\xef\x94\x8a"; + inline constexpr char salt[] = "\xee\xbc\x96"; + inline constexpr char sandbox[] = "\xef\xb5\xac"; + inline constexpr char satellite[] = "\xee\xbb\x93"; + inline constexpr char satelliteOff[] = "\xef\x86\x97"; + inline constexpr char sausage[] = "\xee\xbc\x97"; + inline constexpr char scale[] = "\xee\xaf\x82"; + inline constexpr char scaleOff[] = "\xef\x86\x98"; + inline constexpr char scaleOutline[] = "\xee\xbd\x93"; + inline constexpr char scaleOutlineOff[] = "\xef\x86\x99"; + inline constexpr char scan[] = "\xee\xaf\x88"; + inline constexpr char scanCube[] = "\xf0\x90\x89\x9d"; + inline constexpr char scanEye[] = "\xef\x87\xbf"; + inline constexpr char scanLetterA[] = "\xf0\x90\x88\xa3"; + inline constexpr char scanLetterT[] = "\xf0\x90\x88\xa2"; + inline constexpr char scanPosition[] = "\xef\xb6\xac"; + inline constexpr char scanTraces[] = "\xf0\x90\x87\xac"; + inline constexpr char schema[] = "\xef\x88\x80"; + inline constexpr char schemaOff[] = "\xef\x90\xa6"; + inline constexpr char school[] = "\xee\xb3\xb7"; + inline constexpr char schoolBell[] = "\xef\x99\x8a"; + inline constexpr char schoolOff[] = "\xef\x86\x9a"; + inline constexpr char scissors[] = "\xee\xac\x9b"; + inline constexpr char scissorsOff[] = "\xef\x86\x9b"; + inline constexpr char scooter[] = "\xee\xb1\xac"; + inline constexpr char scooterElectric[] = "\xee\xb3\x81"; + inline constexpr char scoreboard[] = "\xef\xa9\xab"; + inline constexpr char screenShare[] = "\xee\xb4\x98"; + inline constexpr char screenShareOff[] = "\xee\xb4\x97"; + inline constexpr char screenshot[] = "\xef\x88\x81"; + inline constexpr char scribble[] = "\xef\x82\xa3"; + inline constexpr char scribbleOff[] = "\xef\x90\xa7"; + inline constexpr char script[] = "\xef\x8b\x9a"; + inline constexpr char scriptMinus[] = "\xef\x8b\x97"; + inline constexpr char scriptPlus[] = "\xef\x8b\x98"; + inline constexpr char scriptX[] = "\xef\x8b\x99"; + inline constexpr char scubaDiving[] = "\xef\xb5\x8e"; + inline constexpr char scubaDivingTank[] = "\xef\xbb\xba"; + inline constexpr char scubaMask[] = "\xee\xbb\x94"; + inline constexpr char scubaMaskOff[] = "\xef\x90\xa8"; + inline constexpr char sdk[] = "\xef\x8e\xaf"; + inline constexpr char search[] = "\xee\xac\x9c"; + inline constexpr char searchOff[] = "\xef\x86\x9c"; + inline constexpr char section[] = "\xee\xbb\x95"; + inline constexpr char sectionSign[] = "\xef\x80\x99"; + inline constexpr char seedling[] = "\xee\xb5\x91"; + inline constexpr char seedlingOff[] = "\xef\x86\x9d"; + inline constexpr char segway[] = "\xf0\x90\x88\xa1"; + inline constexpr char select[] = "\xee\xb2\x9e"; + inline constexpr char selectAll[] = "\xef\xa7\xb7"; + inline constexpr char selector[] = "\xee\xac\x9d"; + inline constexpr char send[] = "\xee\xac\x9e"; + inline constexpr char send2[] = "\xef\xb5\x9d"; + inline constexpr char sendOff[] = "\xef\x90\xa9"; + inline constexpr char seo[] = "\xef\x89\xab"; + inline constexpr char separator[] = "\xee\xaf\x9a"; + inline constexpr char separatorHorizontal[] = "\xee\xb1\xb9"; + inline constexpr char separatorVertical[] = "\xee\xb1\xba"; + inline constexpr char server[] = "\xee\xac\x9f"; + inline constexpr char server2[] = "\xef\x81\xbc"; + inline constexpr char serverBolt[] = "\xef\x8c\xa0"; + inline constexpr char serverCog[] = "\xef\x8c\xa1"; + inline constexpr char serverOff[] = "\xef\x86\x9e"; + inline constexpr char serverSpark[] = "\xef\xbe\xaf"; + inline constexpr char serverless[] = "\xf0\x90\x87\xab"; + inline constexpr char servicemark[] = "\xee\xb0\x89"; + inline constexpr char settings[] = "\xee\xac\xa0"; + inline constexpr char settings2[] = "\xef\x96\xac"; + inline constexpr char settingsAi[] = "\xf0\x90\x86\xa7"; + inline constexpr char settingsAutomation[] = "\xee\xbb\x96"; + inline constexpr char settingsBolt[] = "\xef\xa6\xad"; + inline constexpr char settingsCancel[] = "\xef\xa6\xae"; + inline constexpr char settingsCheck[] = "\xef\xa6\xaf"; + inline constexpr char settingsCode[] = "\xef\xa6\xb0"; + inline constexpr char settingsCog[] = "\xef\xa6\xb1"; + inline constexpr char settingsDollar[] = "\xef\xa6\xb2"; + inline constexpr char settingsDown[] = "\xef\xa6\xb3"; + inline constexpr char settingsExclamation[] = "\xef\xa6\xb4"; + inline constexpr char settingsHeart[] = "\xef\xa6\xb5"; + inline constexpr char settingsMinus[] = "\xef\xa6\xb6"; + inline constexpr char settingsOff[] = "\xef\x86\x9f"; + inline constexpr char settingsPause[] = "\xef\xa6\xb7"; + inline constexpr char settingsPin[] = "\xef\xa6\xb8"; + inline constexpr char settingsPlus[] = "\xef\xa6\xb9"; + inline constexpr char settingsQuestion[] = "\xef\xa6\xba"; + inline constexpr char settingsSearch[] = "\xef\xa6\xbb"; + inline constexpr char settingsShare[] = "\xef\xa6\xbc"; + inline constexpr char settingsSpark[] = "\xef\xbe\xae"; + inline constexpr char settingsStar[] = "\xef\xa6\xbd"; + inline constexpr char settingsUp[] = "\xef\xa6\xbe"; + inline constexpr char settingsX[] = "\xef\xa6\xbf"; + inline constexpr char shadow[] = "\xee\xbb\x98"; + inline constexpr char shadowOff[] = "\xee\xbb\x97"; + inline constexpr char shape[] = "\xee\xae\x9c"; + inline constexpr char shape2[] = "\xee\xbb\x99"; + inline constexpr char shape3[] = "\xee\xbb\x9a"; + inline constexpr char shapeOff[] = "\xef\x86\xa0"; + inline constexpr char share[] = "\xee\xac\xa1"; + inline constexpr char share2[] = "\xef\x9e\x99"; + inline constexpr char share3[] = "\xef\x9e\xbd"; + inline constexpr char shareOff[] = "\xef\x86\xa1"; + inline constexpr char shareplay[] = "\xef\xba\xa5"; + inline constexpr char shield[] = "\xee\xac\xa4"; + inline constexpr char shieldBolt[] = "\xef\xa7\x80"; + inline constexpr char shieldCancel[] = "\xef\xa7\x81"; + inline constexpr char shieldCheck[] = "\xee\xac\xa2"; + inline constexpr char shieldCheckered[] = "\xee\xbe\x9a"; + inline constexpr char shieldChevron[] = "\xee\xbe\x9b"; + inline constexpr char shieldCode[] = "\xef\xa7\x82"; + inline constexpr char shieldCog[] = "\xef\xa7\x83"; + inline constexpr char shieldDollar[] = "\xef\xa7\x84"; + inline constexpr char shieldDown[] = "\xef\xa7\x85"; + inline constexpr char shieldExclamation[] = "\xef\xa7\x86"; + inline constexpr char shieldHalf[] = "\xef\x8d\x98"; + inline constexpr char shieldHeart[] = "\xef\xa7\x87"; + inline constexpr char shieldLock[] = "\xee\xb5\x98"; + inline constexpr char shieldMinus[] = "\xef\xa7\x88"; + inline constexpr char shieldOff[] = "\xee\xb3\xb8"; + inline constexpr char shieldPause[] = "\xef\xa7\x89"; + inline constexpr char shieldPin[] = "\xef\xa7\x8a"; + inline constexpr char shieldPlus[] = "\xef\xa7\x8b"; + inline constexpr char shieldQuestion[] = "\xef\xa7\x8c"; + inline constexpr char shieldSearch[] = "\xef\xa7\x8d"; + inline constexpr char shieldShare[] = "\xef\xa7\x8e"; + inline constexpr char shieldStar[] = "\xef\xa7\x8f"; + inline constexpr char shieldUp[] = "\xef\xa7\x90"; + inline constexpr char shieldX[] = "\xee\xac\xa3"; + inline constexpr char ship[] = "\xee\xb2\x84"; + inline constexpr char shipOff[] = "\xef\x90\xaa"; + inline constexpr char shirt[] = "\xee\xb0\x8a"; + inline constexpr char shirtOff[] = "\xef\x86\xa2"; + inline constexpr char shirtSport[] = "\xef\x89\xac"; + inline constexpr char shoe[] = "\xee\xbf\x92"; + inline constexpr char shoeOff[] = "\xef\x86\xa4"; + inline constexpr char shoppingBag[] = "\xef\x97\xb8"; + inline constexpr char shoppingBagCheck[] = "\xef\xb0\x96"; + inline constexpr char shoppingBagDiscount[] = "\xef\xb0\x97"; + inline constexpr char shoppingBagEdit[] = "\xef\xb0\x98"; + inline constexpr char shoppingBagExclamation[] = "\xef\xb0\x99"; + inline constexpr char shoppingBagHeart[] = "\xef\xb6\xa2"; + inline constexpr char shoppingBagMinus[] = "\xef\xb0\x9a"; + inline constexpr char shoppingBagPlus[] = "\xef\xb0\x9b"; + inline constexpr char shoppingBagSearch[] = "\xef\xb0\x9c"; + inline constexpr char shoppingBagX[] = "\xef\xb0\x9d"; + inline constexpr char shoppingCart[] = "\xee\xac\xa5"; + inline constexpr char shoppingCartBolt[] = "\xef\xad\x97"; + inline constexpr char shoppingCartCancel[] = "\xef\xad\x98"; + inline constexpr char shoppingCartCheck[] = "\xef\xad\x99"; + inline constexpr char shoppingCartCode[] = "\xef\xad\x9a"; + inline constexpr char shoppingCartCog[] = "\xef\xad\x9b"; + inline constexpr char shoppingCartCopy[] = "\xef\xad\x9c"; + inline constexpr char shoppingCartDiscount[] = "\xef\xad\x9d"; + inline constexpr char shoppingCartDollar[] = "\xef\xad\x9e"; + inline constexpr char shoppingCartDown[] = "\xef\xad\x9f"; + inline constexpr char shoppingCartExclamation[] = "\xef\xad\xa0"; + inline constexpr char shoppingCartHeart[] = "\xef\xad\xa1"; + inline constexpr char shoppingCartMinus[] = "\xef\xad\xa2"; + inline constexpr char shoppingCartOff[] = "\xee\xbb\x9c"; + inline constexpr char shoppingCartPause[] = "\xef\xad\xa3"; + inline constexpr char shoppingCartPin[] = "\xef\xad\xa4"; + inline constexpr char shoppingCartPlus[] = "\xef\xad\xa5"; + inline constexpr char shoppingCartQuestion[] = "\xef\xad\xa6"; + inline constexpr char shoppingCartSearch[] = "\xef\xad\xa7"; + inline constexpr char shoppingCartShare[] = "\xef\xad\xa8"; + inline constexpr char shoppingCartStar[] = "\xef\xad\xa9"; + inline constexpr char shoppingCartUp[] = "\xef\xad\xaa"; + inline constexpr char shoppingCartX[] = "\xef\xad\xab"; + inline constexpr char shovel[] = "\xef\x87\x99"; + inline constexpr char shovelPitchforks[] = "\xef\xb4\xba"; + inline constexpr char shredder[] = "\xee\xbb\x9f"; + inline constexpr char signLeft[] = "\xef\x81\xab"; + inline constexpr char signRight[] = "\xef\x81\xac"; + inline constexpr char signal2g[] = "\xef\x9e\x9a"; + inline constexpr char signal3g[] = "\xef\x87\xae"; + inline constexpr char signal4g[] = "\xef\x87\xaf"; + inline constexpr char signal4gPlus[] = "\xef\x89\x99"; + inline constexpr char signal5g[] = "\xef\x87\xb0"; + inline constexpr char signal6g[] = "\xef\xa7\xb8"; + inline constexpr char signalE[] = "\xef\xa7\xb9"; + inline constexpr char signalG[] = "\xef\xa7\xba"; + inline constexpr char signalH[] = "\xef\xa7\xbc"; + inline constexpr char signalHPlus[] = "\xef\xa7\xbb"; + inline constexpr char signalLte[] = "\xef\xa7\xbd"; + inline constexpr char signature[] = "\xee\xbb\xa0"; + inline constexpr char signatureOff[] = "\xef\x86\xa5"; + inline constexpr char sitemap[] = "\xee\xae\x9d"; + inline constexpr char sitemapOff[] = "\xef\x86\xa6"; + inline constexpr char skateboard[] = "\xee\xb3\x82"; + inline constexpr char skateboardOff[] = "\xef\x90\xab"; + inline constexpr char skateboarding[] = "\xef\xab\x8a"; + inline constexpr char sketching[] = "\xf0\x90\x89\x9c"; + inline constexpr char skewX[] = "\xef\xb4\xbb"; + inline constexpr char skewY[] = "\xef\xb4\xbc"; + inline constexpr char skiJumping[] = "\xef\xa9\xac"; + inline constexpr char skull[] = "\xef\x8a\x92"; + inline constexpr char slash[] = "\xef\x93\xb9"; + inline constexpr char slashes[] = "\xef\x96\x88"; + inline constexpr char sleigh[] = "\xee\xbe\x9c"; + inline constexpr char slice[] = "\xee\xaf\x9b"; + inline constexpr char slideshow[] = "\xee\xaf\x89"; + inline constexpr char smartHome[] = "\xee\xb3\x9e"; + inline constexpr char smartHomeOff[] = "\xef\x86\xa7"; + inline constexpr char smoking[] = "\xee\xb3\x84"; + inline constexpr char smokingNo[] = "\xee\xb3\x83"; + inline constexpr char snowboarding[] = "\xef\xb5\x8f"; + inline constexpr char snowflake[] = "\xee\xb0\x8b"; + inline constexpr char snowflakeOff[] = "\xef\x86\xa8"; + inline constexpr char snowman[] = "\xef\x89\xad"; + inline constexpr char soccerField[] = "\xee\xb6\x92"; + inline constexpr char social[] = "\xee\xaf\xac"; + inline constexpr char socialOff[] = "\xef\x86\xa9"; + inline constexpr char sock[] = "\xee\xbb\xa1"; + inline constexpr char sofa[] = "\xee\xbe\xaf"; + inline constexpr char sofaOff[] = "\xef\x90\xac"; + inline constexpr char solarElectricity[] = "\xef\xb3\x81"; + inline constexpr char solarPanel[] = "\xef\x9e\xbf"; + inline constexpr char solarPanel2[] = "\xef\x9e\xbe"; + inline constexpr char sort09[] = "\xef\x95\x8d"; + inline constexpr char sort90[] = "\xef\x95\x8e"; + inline constexpr char sortAZ[] = "\xef\x95\x8f"; + inline constexpr char sortAscending[] = "\xee\xac\xa6"; + inline constexpr char sortAscending2[] = "\xee\xbb\xa2"; + inline constexpr char sortAscendingLetters[] = "\xee\xbc\x98"; + inline constexpr char sortAscendingNumbers[] = "\xee\xbc\x99"; + inline constexpr char sortAscendingShapes[] = "\xef\xb6\x94"; + inline constexpr char sortAscendingSmallBig[] = "\xef\xb6\x95"; + inline constexpr char sortDescending[] = "\xee\xac\xa7"; + inline constexpr char sortDescending2[] = "\xee\xbb\xa3"; + inline constexpr char sortDescendingLetters[] = "\xee\xbc\x9a"; + inline constexpr char sortDescendingNumbers[] = "\xee\xbc\x9b"; + inline constexpr char sortDescendingShapes[] = "\xef\xb6\x97"; + inline constexpr char sortDescendingSmallBig[] = "\xef\xb6\x96"; + inline constexpr char sortZA[] = "\xef\x95\x90"; + inline constexpr char sos[] = "\xef\x89\x8a"; + inline constexpr char soup[] = "\xee\xbc\xae"; + inline constexpr char soupOff[] = "\xef\x90\xad"; + inline constexpr char sourceCode[] = "\xef\x92\xa2"; + inline constexpr char space[] = "\xee\xb0\x8c"; + inline constexpr char spaceOff[] = "\xef\x86\xaa"; + inline constexpr char spaces[] = "\xef\xba\xa4"; + inline constexpr char spacingHorizontal[] = "\xee\xbd\x94"; + inline constexpr char spacingVertical[] = "\xee\xbd\x95"; + inline constexpr char spade[] = "\xee\xbf\xba"; + inline constexpr char sparkle[] = "\xf0\x90\x89\x99"; + inline constexpr char sparkle2[] = "\xf0\x90\x89\x9b"; + inline constexpr char sparkleHighlight[] = "\xf0\x90\x89\x9a"; + inline constexpr char sparkles[] = "\xef\x9b\x97"; + inline constexpr char sparkles2[] = "\xf0\x90\x86\xa6"; + inline constexpr char speakerphone[] = "\xee\xb5\xa1"; + inline constexpr char speedboat[] = "\xee\xb6\x93"; + inline constexpr char sphere[] = "\xef\xaa\xb8"; + inline constexpr char sphere2[] = "\xf0\x90\x89\x98"; + inline constexpr char sphereOff[] = "\xef\xaa\xb6"; + inline constexpr char spherePlus[] = "\xef\xaa\xb7"; + inline constexpr char spider[] = "\xef\x8a\x93"; + inline constexpr char spiral[] = "\xef\x8a\x94"; + inline constexpr char spiralOff[] = "\xef\x90\xae"; + inline constexpr char sportBilliard[] = "\xee\xbb\xa4"; + inline constexpr char spray[] = "\xef\x94\x8b"; + inline constexpr char spy[] = "\xef\x88\xa7"; + inline constexpr char spyOff[] = "\xef\x90\xaf"; + inline constexpr char sql[] = "\xef\x9f\x80"; + inline constexpr char square[] = "\xee\xac\xac"; + inline constexpr char squareArrowDown[] = "\xef\x92\xb7"; + inline constexpr char squareArrowLeft[] = "\xef\x92\xb8"; + inline constexpr char squareArrowRight[] = "\xef\x92\xb9"; + inline constexpr char squareArrowUp[] = "\xef\x92\xba"; + inline constexpr char squareAsterisk[] = "\xef\x80\x9a"; + inline constexpr char squareCheck[] = "\xee\xac\xa8"; + inline constexpr char squareChevronDown[] = "\xef\x98\xa7"; + inline constexpr char squareChevronLeft[] = "\xef\x98\xa8"; + inline constexpr char squareChevronRight[] = "\xef\x98\xa9"; + inline constexpr char squareChevronUp[] = "\xef\x98\xaa"; + inline constexpr char squareChevronsDown[] = "\xef\x99\x8b"; + inline constexpr char squareChevronsLeft[] = "\xef\x99\x8c"; + inline constexpr char squareChevronsRight[] = "\xef\x99\x8d"; + inline constexpr char squareChevronsUp[] = "\xef\x99\x8e"; + inline constexpr char squareDashed[] = "\xf0\x90\x82\xbb"; + inline constexpr char squareDot[] = "\xee\xb5\x99"; + inline constexpr char squareF0[] = "\xef\x94\xa6"; + inline constexpr char squareF1[] = "\xef\x94\xa7"; + inline constexpr char squareF2[] = "\xef\x94\xa8"; + inline constexpr char squareF3[] = "\xef\x94\xa9"; + inline constexpr char squareF4[] = "\xef\x94\xaa"; + inline constexpr char squareF5[] = "\xef\x94\xab"; + inline constexpr char squareF6[] = "\xef\x94\xac"; + inline constexpr char squareF7[] = "\xef\x94\xad"; + inline constexpr char squareF8[] = "\xef\x94\xae"; + inline constexpr char squareF9[] = "\xef\x94\xaf"; + inline constexpr char squareForbid[] = "\xee\xb5\x9b"; + inline constexpr char squareForbid2[] = "\xee\xb5\x9a"; + inline constexpr char squareHalf[] = "\xee\xbf\xbb"; + inline constexpr char squareKey[] = "\xef\x98\xb8"; + inline constexpr char squareLetterA[] = "\xef\x91\xbc"; + inline constexpr char squareLetterB[] = "\xef\x91\xbd"; + inline constexpr char squareLetterC[] = "\xef\x91\xbe"; + inline constexpr char squareLetterD[] = "\xef\x91\xbf"; + inline constexpr char squareLetterE[] = "\xef\x92\x80"; + inline constexpr char squareLetterF[] = "\xef\x92\x81"; + inline constexpr char squareLetterG[] = "\xef\x92\x82"; + inline constexpr char squareLetterH[] = "\xef\x92\x83"; + inline constexpr char squareLetterI[] = "\xef\x92\x84"; + inline constexpr char squareLetterJ[] = "\xef\x92\x85"; + inline constexpr char squareLetterK[] = "\xef\x92\x86"; + inline constexpr char squareLetterL[] = "\xef\x92\x87"; + inline constexpr char squareLetterM[] = "\xef\x92\x88"; + inline constexpr char squareLetterN[] = "\xef\x92\x89"; + inline constexpr char squareLetterO[] = "\xef\x92\x8a"; + inline constexpr char squareLetterP[] = "\xef\x92\x8b"; + inline constexpr char squareLetterQ[] = "\xef\x92\x8c"; + inline constexpr char squareLetterR[] = "\xef\x92\x8d"; + inline constexpr char squareLetterS[] = "\xef\x92\x8e"; + inline constexpr char squareLetterT[] = "\xef\x92\x8f"; + inline constexpr char squareLetterU[] = "\xef\x92\x90"; + inline constexpr char squareLetterV[] = "\xef\x92\xbb"; + inline constexpr char squareLetterW[] = "\xef\x92\x91"; + inline constexpr char squareLetterX[] = "\xef\x92\xbc"; + inline constexpr char squareLetterY[] = "\xef\x92\x92"; + inline constexpr char squareLetterZ[] = "\xef\x92\x93"; + inline constexpr char squareMinus[] = "\xf0\x90\x86\x9e"; + inline constexpr char squareMinus2[] = "\xee\xac\xa9"; + inline constexpr char squareNumber0[] = "\xee\xbb\xa5"; + inline constexpr char squareNumber1[] = "\xee\xbb\xa6"; + inline constexpr char squareNumber2[] = "\xee\xbb\xa7"; + inline constexpr char squareNumber3[] = "\xee\xbb\xa8"; + inline constexpr char squareNumber4[] = "\xee\xbb\xa9"; + inline constexpr char squareNumber5[] = "\xee\xbb\xaa"; + inline constexpr char squareNumber6[] = "\xee\xbb\xab"; + inline constexpr char squareNumber7[] = "\xee\xbb\xac"; + inline constexpr char squareNumber8[] = "\xee\xbb\xad"; + inline constexpr char squareNumber9[] = "\xee\xbb\xae"; + inline constexpr char squareOff[] = "\xee\xbb\xaf"; + inline constexpr char squarePercentage[] = "\xef\xb6\x83"; + inline constexpr char squarePlus[] = "\xee\xac\xaa"; + inline constexpr char squarePlus2[] = "\xef\xb2\x96"; + inline constexpr char squareRoot[] = "\xee\xbb\xb1"; + inline constexpr char squareRoot2[] = "\xee\xbb\xb0"; + inline constexpr char squareRotated[] = "\xee\xb3\x9f"; + inline constexpr char squareRotatedAsterisk[] = "\xf0\x90\x86\xa5"; + inline constexpr char squareRotatedForbid[] = "\xef\x80\x9c"; + inline constexpr char squareRotatedForbid2[] = "\xef\x80\x9b"; + inline constexpr char squareRotatedOff[] = "\xee\xbb\xb2"; + inline constexpr char squareRounded[] = "\xef\x96\x9a"; + inline constexpr char squareRoundedArrowDown[] = "\xef\x98\xb9"; + inline constexpr char squareRoundedArrowLeft[] = "\xef\x98\xba"; + inline constexpr char squareRoundedArrowRight[] = "\xef\x98\xbb"; + inline constexpr char squareRoundedArrowUp[] = "\xef\x98\xbc"; + inline constexpr char squareRoundedCheck[] = "\xef\x98\xbd"; + inline constexpr char squareRoundedChevronDown[] = "\xef\x98\xab"; + inline constexpr char squareRoundedChevronLeft[] = "\xef\x98\xac"; + inline constexpr char squareRoundedChevronRight[] = "\xef\x98\xad"; + inline constexpr char squareRoundedChevronUp[] = "\xef\x98\xae"; + inline constexpr char squareRoundedChevronsDown[] = "\xef\x99\x8f"; + inline constexpr char squareRoundedChevronsLeft[] = "\xef\x99\x90"; + inline constexpr char squareRoundedChevronsRight[] = "\xef\x99\x91"; + inline constexpr char squareRoundedChevronsUp[] = "\xef\x99\x92"; + inline constexpr char squareRoundedLetterA[] = "\xef\x96\xae"; + inline constexpr char squareRoundedLetterB[] = "\xef\x96\xaf"; + inline constexpr char squareRoundedLetterC[] = "\xef\x96\xb0"; + inline constexpr char squareRoundedLetterD[] = "\xef\x96\xb1"; + inline constexpr char squareRoundedLetterE[] = "\xef\x96\xb2"; + inline constexpr char squareRoundedLetterF[] = "\xef\x96\xb3"; + inline constexpr char squareRoundedLetterG[] = "\xef\x96\xb4"; + inline constexpr char squareRoundedLetterH[] = "\xef\x96\xb5"; + inline constexpr char squareRoundedLetterI[] = "\xef\x96\xb6"; + inline constexpr char squareRoundedLetterJ[] = "\xef\x96\xb7"; + inline constexpr char squareRoundedLetterK[] = "\xef\x96\xb8"; + inline constexpr char squareRoundedLetterL[] = "\xef\x96\xb9"; + inline constexpr char squareRoundedLetterM[] = "\xef\x96\xba"; + inline constexpr char squareRoundedLetterN[] = "\xef\x96\xbb"; + inline constexpr char squareRoundedLetterO[] = "\xef\x96\xbc"; + inline constexpr char squareRoundedLetterP[] = "\xef\x96\xbd"; + inline constexpr char squareRoundedLetterQ[] = "\xef\x96\xbe"; + inline constexpr char squareRoundedLetterR[] = "\xef\x96\xbf"; + inline constexpr char squareRoundedLetterS[] = "\xef\x97\x80"; + inline constexpr char squareRoundedLetterT[] = "\xef\x97\x81"; + inline constexpr char squareRoundedLetterU[] = "\xef\x97\x82"; + inline constexpr char squareRoundedLetterV[] = "\xef\x97\x83"; + inline constexpr char squareRoundedLetterW[] = "\xef\x97\x84"; + inline constexpr char squareRoundedLetterX[] = "\xef\x97\x85"; + inline constexpr char squareRoundedLetterY[] = "\xef\x97\x86"; + inline constexpr char squareRoundedLetterZ[] = "\xef\x97\x87"; + inline constexpr char squareRoundedMinus[] = "\xef\x98\xbe"; + inline constexpr char squareRoundedMinus2[] = "\xef\xb2\x97"; + inline constexpr char squareRoundedNumber0[] = "\xef\x97\x88"; + inline constexpr char squareRoundedNumber1[] = "\xef\x97\x89"; + inline constexpr char squareRoundedNumber2[] = "\xef\x97\x8a"; + inline constexpr char squareRoundedNumber3[] = "\xef\x97\x8b"; + inline constexpr char squareRoundedNumber4[] = "\xef\x97\x8c"; + inline constexpr char squareRoundedNumber5[] = "\xef\x97\x8d"; + inline constexpr char squareRoundedNumber6[] = "\xef\x97\x8e"; + inline constexpr char squareRoundedNumber7[] = "\xef\x97\x8f"; + inline constexpr char squareRoundedNumber8[] = "\xef\x97\x90"; + inline constexpr char squareRoundedNumber9[] = "\xef\x97\x91"; + inline constexpr char squareRoundedPercentage[] = "\xef\xb6\x84"; + inline constexpr char squareRoundedPlus[] = "\xef\x98\xbf"; + inline constexpr char squareRoundedPlus2[] = "\xef\xb2\x98"; + inline constexpr char squareRoundedX[] = "\xef\x99\x80"; + inline constexpr char squareToggle[] = "\xee\xbb\xb4"; + inline constexpr char squareToggleHorizontal[] = "\xee\xbb\xb3"; + inline constexpr char squareX[] = "\xee\xac\xab"; + inline constexpr char squares[] = "\xee\xbb\xb6"; + inline constexpr char squaresDiagonal[] = "\xee\xbb\xb5"; + inline constexpr char squaresSelected[] = "\xef\xba\xa3"; + inline constexpr char stack[] = "\xee\xac\xad"; + inline constexpr char stack2[] = "\xee\xbb\xb7"; + inline constexpr char stack3[] = "\xee\xbe\x9d"; + inline constexpr char stackBack[] = "\xef\xb4\xa6"; + inline constexpr char stackBackward[] = "\xef\xb4\xa7"; + inline constexpr char stackForward[] = "\xef\xb4\xa8"; + inline constexpr char stackFront[] = "\xef\xb4\xa9"; + inline constexpr char stackMiddle[] = "\xef\xb4\xaa"; + inline constexpr char stackPop[] = "\xef\x88\xb4"; + inline constexpr char stackPush[] = "\xef\x88\xb5"; + inline constexpr char stairs[] = "\xee\xb2\xa6"; + inline constexpr char stairsDown[] = "\xee\xb2\xa4"; + inline constexpr char stairsUp[] = "\xee\xb2\xa5"; + inline constexpr char star[] = "\xee\xac\xae"; + inline constexpr char starHalf[] = "\xee\xb4\x99"; + inline constexpr char starOff[] = "\xee\xb5\xa2"; + inline constexpr char stars[] = "\xee\xb4\xb8"; + inline constexpr char starsOff[] = "\xef\x90\xb0"; + inline constexpr char statusChange[] = "\xef\x8e\xb0"; + inline constexpr char steam[] = "\xef\x89\x8b"; + inline constexpr char steeringWheel[] = "\xee\xb1\xbb"; + inline constexpr char steeringWheelOff[] = "\xef\x90\xb1"; + inline constexpr char stepInto[] = "\xee\xb3\xa0"; + inline constexpr char stepOut[] = "\xee\xb3\xa1"; + inline constexpr char stereoGlasses[] = "\xef\x93\x8b"; + inline constexpr char stethoscope[] = "\xee\xb6\xbe"; + inline constexpr char stethoscopeOff[] = "\xef\x90\xb2"; + inline constexpr char sticker[] = "\xee\xac\xaf"; + inline constexpr char sticker2[] = "\xef\xb4\xbd"; + inline constexpr char stopwatch[] = "\xef\xbe\x9b"; + inline constexpr char storm[] = "\xef\x89\x8c"; + inline constexpr char stormOff[] = "\xef\x90\xb3"; + inline constexpr char stretching[] = "\xef\x8b\x9b"; + inline constexpr char stretching2[] = "\xef\xa9\xad"; + inline constexpr char strikethrough[] = "\xee\xae\x9e"; + inline constexpr char strokeCurved[] = "\xf0\x90\x87\xbe"; + inline constexpr char strokeDynamic[] = "\xf0\x90\x87\xbd"; + inline constexpr char strokeStraight[] = "\xf0\x90\x87\xbc"; + inline constexpr char submarine[] = "\xee\xb6\x94"; + inline constexpr char subscript[] = "\xee\xae\x9f"; + inline constexpr char subtask[] = "\xee\xb2\x9f"; + inline constexpr char subtitles[] = "\xf0\x90\x86\xa1"; + inline constexpr char subtitlesAi[] = "\xf0\x90\x86\xa4"; + inline constexpr char subtitlesEdit[] = "\xf0\x90\x86\xa3"; + inline constexpr char subtitlesOff[] = "\xf0\x90\x86\xa2"; + inline constexpr char sum[] = "\xee\xad\xb3"; + inline constexpr char sumOff[] = "\xef\x86\xab"; + inline constexpr char sun[] = "\xee\xac\xb0"; + inline constexpr char sunElectricity[] = "\xef\xb3\x82"; + inline constexpr char sunHigh[] = "\xef\x88\xb6"; + inline constexpr char sunLow[] = "\xef\x88\xb7"; + inline constexpr char sunMoon[] = "\xef\x92\xa3"; + inline constexpr char sunOff[] = "\xee\xb5\xa3"; + inline constexpr char sunWind[] = "\xef\x88\xb8"; + inline constexpr char sunglasses[] = "\xef\x88\xb9"; + inline constexpr char sunrise[] = "\xee\xbc\x9c"; + inline constexpr char sunset[] = "\xee\xb0\xb1"; + inline constexpr char sunset2[] = "\xef\x88\xba"; + inline constexpr char superscript[] = "\xee\xae\xa0"; + inline constexpr char svg[] = "\xef\x89\x9a"; + inline constexpr char swimming[] = "\xee\xb2\x92"; + inline constexpr char swipe[] = "\xef\x95\x91"; + inline constexpr char swipeDown[] = "\xef\xb5\x9e"; + inline constexpr char swipeLeft[] = "\xef\xb5\x9f"; + inline constexpr char swipeRight[] = "\xef\xb5\xa0"; + inline constexpr char swipeUp[] = "\xef\xb5\xa1"; + inline constexpr char switchIcon[] = "\xee\xac\xb3"; + inline constexpr char switch2[] = "\xee\xb6\xbf"; + inline constexpr char switch3[] = "\xee\xb7\x80"; + inline constexpr char switchHorizontal[] = "\xee\xac\xb1"; + inline constexpr char switchVertical[] = "\xee\xac\xb2"; + inline constexpr char sword[] = "\xef\x80\xb0"; + inline constexpr char swordOff[] = "\xef\x90\xb4"; + inline constexpr char swords[] = "\xef\x84\xb2"; + inline constexpr char tabClose[] = "\xf0\x90\x89\xb0"; + inline constexpr char table[] = "\xee\xae\xa1"; + inline constexpr char tableAlias[] = "\xef\x89\x9b"; + inline constexpr char tableColumn[] = "\xef\xab\xbf"; + inline constexpr char tableDashed[] = "\xf0\x90\x82\xba"; + inline constexpr char tableDown[] = "\xef\xa8\x9c"; + inline constexpr char tableExport[] = "\xee\xbb\xb8"; + inline constexpr char tableHeart[] = "\xef\xa8\x9d"; + inline constexpr char tableImport[] = "\xee\xbb\xb9"; + inline constexpr char tableMinus[] = "\xef\xa8\x9e"; + inline constexpr char tableOff[] = "\xee\xbb\xba"; + inline constexpr char tableOptions[] = "\xef\x89\x9c"; + inline constexpr char tablePlus[] = "\xef\xa8\x9f"; + inline constexpr char tableRow[] = "\xef\xac\x80"; + inline constexpr char tableShare[] = "\xef\xa8\xa0"; + inline constexpr char tableShortcut[] = "\xef\x89\x9d"; + inline constexpr char tableSpark[] = "\xef\xbe\xad"; + inline constexpr char tag[] = "\xf0\x90\x82\x96"; + inline constexpr char tagMinus[] = "\xee\xac\xb4"; + inline constexpr char tagOff[] = "\xee\xbf\x80"; + inline constexpr char tagPlus[] = "\xf0\x90\x82\x97"; + inline constexpr char tagStarred[] = "\xef\xb2\x99"; + inline constexpr char tags[] = "\xee\xbe\x86"; + inline constexpr char tagsOff[] = "\xee\xbf\x81"; + inline constexpr char taiwanDollar[] = "\xf0\x90\x89\x86"; + inline constexpr char tallymark1[] = "\xee\xb1\x86"; + inline constexpr char tallymark2[] = "\xee\xb1\x87"; + inline constexpr char tallymark3[] = "\xee\xb1\x88"; + inline constexpr char tallymark4[] = "\xee\xb1\x89"; + inline constexpr char tallymarks[] = "\xee\xb1\x8a"; + inline constexpr char tank[] = "\xee\xb6\x95"; + inline constexpr char target[] = "\xee\xac\xb5"; + inline constexpr char target2[] = "\xf0\x90\x89\x85"; + inline constexpr char targetArrow[] = "\xef\x94\x9a"; + inline constexpr char targetOff[] = "\xef\x86\xad"; + inline constexpr char tax[] = "\xef\xbb\xae"; + inline constexpr char taxEuro[] = "\xef\xbb\xb0"; + inline constexpr char taxPound[] = "\xef\xbb\xaf"; + inline constexpr char teapot[] = "\xef\x95\x92"; + inline constexpr char telescope[] = "\xef\x81\xbd"; + inline constexpr char telescopeOff[] = "\xef\x86\xae"; + inline constexpr char temperature[] = "\xee\xac\xb8"; + inline constexpr char temperatureCelsius[] = "\xee\xac\xb6"; + inline constexpr char temperatureFahrenheit[] = "\xee\xac\xb7"; + inline constexpr char temperatureMinus[] = "\xee\xaf\xad"; + inline constexpr char temperatureOff[] = "\xef\x86\xaf"; + inline constexpr char temperaturePlus[] = "\xee\xaf\xae"; + inline constexpr char temperatureSnow[] = "\xef\xb6\xa3"; + inline constexpr char temperatureSun[] = "\xef\xb6\xa4"; + inline constexpr char templateIcon[] = "\xee\xac\xb9"; + inline constexpr char templateOff[] = "\xef\x86\xb0"; + inline constexpr char tent[] = "\xee\xbb\xbb"; + inline constexpr char tentOff[] = "\xef\x90\xb5"; + inline constexpr char terminal[] = "\xee\xaf\x9c"; + inline constexpr char terminal2[] = "\xee\xaf\xaf"; + inline constexpr char testPipe[] = "\xee\xac\xba"; + inline constexpr char testPipe2[] = "\xef\x82\xa4"; + inline constexpr char testPipeOff[] = "\xef\x86\xb1"; + inline constexpr char tex[] = "\xef\x93\xa0"; + inline constexpr char textCaption[] = "\xef\x92\xa4"; + inline constexpr char textColor[] = "\xef\x8b\x9c"; + inline constexpr char textDecrease[] = "\xef\x88\x82"; + inline constexpr char textDirectionLtr[] = "\xee\xbb\xbc"; + inline constexpr char textDirectionRtl[] = "\xee\xbb\xbd"; + inline constexpr char textGrammar[] = "\xef\xb5\xad"; + inline constexpr char textIncrease[] = "\xef\x88\x83"; + inline constexpr char textOrientation[] = "\xef\x8a\xa4"; + inline constexpr char textOutline[] = "\xf0\x90\x89\xaf"; + inline constexpr char textPlus[] = "\xef\x8a\xa5"; + inline constexpr char textRecognition[] = "\xef\x88\x84"; + inline constexpr char textRegexAsterisk[] = "\xf0\x90\x89\xae"; + inline constexpr char textRegexEnd[] = "\xf0\x90\x89\xad"; + inline constexpr char textRegexPlus[] = "\xf0\x90\x89\xac"; + inline constexpr char textRegexQuestion[] = "\xf0\x90\x89\xab"; + inline constexpr char textRegexStart[] = "\xf0\x90\x89\xaa"; + inline constexpr char textResize[] = "\xee\xbe\x87"; + inline constexpr char textScan2[] = "\xef\xb3\x83"; + inline constexpr char textScanAi[] = "\xf0\x90\x89\x97"; + inline constexpr char textSize[] = "\xef\x8a\xb1"; + inline constexpr char textSpellcheck[] = "\xef\x8a\xa6"; + inline constexpr char textWrap[] = "\xee\xaf\x9d"; + inline constexpr char textWrapColumn[] = "\xef\xba\xb2"; + inline constexpr char textWrapDisabled[] = "\xee\xb2\xa7"; + inline constexpr char texture[] = "\xef\x94\x9b"; + inline constexpr char theater[] = "\xef\x9e\x9b"; + inline constexpr char thermometer[] = "\xee\xbd\xa7"; + inline constexpr char thumbDown[] = "\xee\xac\xbb"; + inline constexpr char thumbDownOff[] = "\xef\x90\xb6"; + inline constexpr char thumbUp[] = "\xee\xac\xbc"; + inline constexpr char thumbUpOff[] = "\xef\x90\xb7"; + inline constexpr char ticTac[] = "\xef\x94\x9c"; + inline constexpr char ticket[] = "\xee\xac\xbd"; + inline constexpr char ticketOff[] = "\xef\x86\xb2"; + inline constexpr char tie[] = "\xef\x81\xbe"; + inline constexpr char tilde[] = "\xef\x92\xa5"; + inline constexpr char tiltShift[] = "\xee\xbb\xbe"; + inline constexpr char tiltShiftOff[] = "\xef\x86\xb3"; + inline constexpr char timeDuration0[] = "\xef\xab\x94"; + inline constexpr char timeDuration10[] = "\xef\xab\x95"; + inline constexpr char timeDuration15[] = "\xef\xab\x96"; + inline constexpr char timeDuration30[] = "\xef\xab\x97"; + inline constexpr char timeDuration45[] = "\xef\xab\x98"; + inline constexpr char timeDuration5[] = "\xef\xab\x99"; + inline constexpr char timeDuration60[] = "\xef\xab\x9a"; + inline constexpr char timeDuration90[] = "\xef\xab\x9b"; + inline constexpr char timeDurationOff[] = "\xef\xab\x9c"; + inline constexpr char timeline[] = "\xef\x80\xb1"; + inline constexpr char timelineEvent[] = "\xef\x95\x93"; + inline constexpr char timelineEventExclamation[] = "\xef\x99\xa2"; + inline constexpr char timelineEventMinus[] = "\xef\x99\xa3"; + inline constexpr char timelineEventPlus[] = "\xef\x99\xa4"; + inline constexpr char timelineEventText[] = "\xef\x99\xa5"; + inline constexpr char timelineEventX[] = "\xef\x99\xa6"; + inline constexpr char timezone[] = "\xef\xbb\xad"; + inline constexpr char tipJar[] = "\xef\xbb\xaa"; + inline constexpr char tipJarEuro[] = "\xef\xbb\xac"; + inline constexpr char tipJarPound[] = "\xef\xbb\xab"; + inline constexpr char tir[] = "\xee\xaf\xb0"; + inline constexpr char toggleLeft[] = "\xee\xac\xbe"; + inline constexpr char toggleRight[] = "\xee\xac\xbf"; + inline constexpr char toiletPaper[] = "\xee\xbf\x93"; + inline constexpr char toiletPaperOff[] = "\xef\x86\xb4"; + inline constexpr char toml[] = "\xef\xa9\x9d"; + inline constexpr char tool[] = "\xee\xad\x80"; + inline constexpr char tools[] = "\xee\xaf\x8a"; + inline constexpr char toolsKitchen[] = "\xee\xb5\xa4"; + inline constexpr char toolsKitchen2[] = "\xee\xbb\xbf"; + inline constexpr char toolsKitchen2Off[] = "\xef\x86\xb5"; + inline constexpr char toolsKitchen3[] = "\xef\xb4\xab"; + inline constexpr char toolsKitchenOff[] = "\xef\x86\xb6"; + inline constexpr char toolsOff[] = "\xef\x86\xb7"; + inline constexpr char tooltip[] = "\xef\x8b\x9d"; + inline constexpr char topologyBus[] = "\xef\x97\x99"; + inline constexpr char topologyComplex[] = "\xef\x97\x9a"; + inline constexpr char topologyFull[] = "\xef\x97\x9c"; + inline constexpr char topologyFullHierarchy[] = "\xef\x97\x9b"; + inline constexpr char topologyRing[] = "\xef\x97\x9f"; + inline constexpr char topologyRing2[] = "\xef\x97\x9d"; + inline constexpr char topologyRing3[] = "\xef\x97\x9e"; + inline constexpr char topologyStar[] = "\xef\x97\xa5"; + inline constexpr char topologyStar2[] = "\xef\x97\xa0"; + inline constexpr char topologyStar3[] = "\xef\x97\xa1"; + inline constexpr char topologyStarRing[] = "\xef\x97\xa4"; + inline constexpr char topologyStarRing2[] = "\xef\x97\xa2"; + inline constexpr char topologyStarRing3[] = "\xef\x97\xa3"; + inline constexpr char torii[] = "\xef\x96\x9b"; + inline constexpr char tornado[] = "\xee\xb3\xa2"; + inline constexpr char tournament[] = "\xee\xb3\x90"; + inline constexpr char tower[] = "\xef\x8b\x8b"; + inline constexpr char towerOff[] = "\xef\x8b\x8a"; + inline constexpr char track[] = "\xee\xbc\x80"; + inline constexpr char tractor[] = "\xee\xb0\x8d"; + inline constexpr char trademark[] = "\xee\xb0\x8e"; + inline constexpr char trafficCone[] = "\xee\xb0\x8f"; + inline constexpr char trafficConeOff[] = "\xef\x86\xb8"; + inline constexpr char trafficLights[] = "\xee\xb4\xb9"; + inline constexpr char trafficLightsOff[] = "\xef\x86\xb9"; + inline constexpr char train[] = "\xee\xb6\x96"; + inline constexpr char transactionBitcoin[] = "\xef\xb5\xae"; + inline constexpr char transactionDollar[] = "\xef\xb5\xaf"; + inline constexpr char transactionEuro[] = "\xef\xb5\xb0"; + inline constexpr char transactionPound[] = "\xef\xb5\xb1"; + inline constexpr char transactionRupee[] = "\xef\xb6\x85"; + inline constexpr char transactionYen[] = "\xef\xb5\xb2"; + inline constexpr char transactionYuan[] = "\xef\xb5\xb3"; + inline constexpr char transfer[] = "\xef\xb0\x9f"; + inline constexpr char transferIn[] = "\xee\xbc\xaf"; + inline constexpr char transferOut[] = "\xee\xbc\xb0"; + inline constexpr char transferVertical[] = "\xef\xb0\x9e"; + inline constexpr char transform[] = "\xef\x8e\x8e"; + inline constexpr char transformPoint[] = "\xef\xb6\xa9"; + inline constexpr char transformPointBottomLeft[] = "\xef\xb6\xa5"; + inline constexpr char transformPointBottomRight[] = "\xef\xb6\xa6"; + inline constexpr char transformPointTopLeft[] = "\xef\xb6\xa7"; + inline constexpr char transformPointTopRight[] = "\xef\xb6\xa8"; + inline constexpr char transitionBottom[] = "\xef\x8a\xb2"; + inline constexpr char transitionLeft[] = "\xef\x8a\xb3"; + inline constexpr char transitionRight[] = "\xef\x8a\xb4"; + inline constexpr char transitionTop[] = "\xef\x8a\xb5"; + inline constexpr char trash[] = "\xee\xad\x81"; + inline constexpr char trashOff[] = "\xee\xb5\xa5"; + inline constexpr char trashX[] = "\xee\xbe\x88"; + inline constexpr char treadmill[] = "\xef\xa9\xae"; + inline constexpr char tree[] = "\xee\xbc\x81"; + inline constexpr char trees[] = "\xee\xb0\x90"; + inline constexpr char trekking[] = "\xef\x96\xad"; + inline constexpr char trendingDown[] = "\xee\xad\x82"; + inline constexpr char trendingDown2[] = "\xee\xb7\x81"; + inline constexpr char trendingDown3[] = "\xee\xb7\x82"; + inline constexpr char trendingUp[] = "\xee\xad\x83"; + inline constexpr char trendingUp2[] = "\xee\xb7\x83"; + inline constexpr char trendingUp3[] = "\xee\xb7\x84"; + inline constexpr char trendingUpDown[] = "\xf0\x90\x87\xbb"; + inline constexpr char triangle[] = "\xee\xad\x84"; + inline constexpr char triangleInverted[] = "\xef\x80\x9d"; + inline constexpr char triangleMinus[] = "\xef\xb2\x9b"; + inline constexpr char triangleMinus2[] = "\xef\xb2\x9a"; + inline constexpr char triangleOff[] = "\xee\xbc\x82"; + inline constexpr char trianglePlus[] = "\xef\xb2\x9d"; + inline constexpr char trianglePlus2[] = "\xef\xb2\x9c"; + inline constexpr char triangleSquareCircle[] = "\xee\xb3\xa8"; + inline constexpr char triangles[] = "\xef\x82\xa5"; + inline constexpr char trident[] = "\xee\xb3\x85"; + inline constexpr char trolley[] = "\xef\x93\x8c"; + inline constexpr char trophy[] = "\xee\xad\x85"; + inline constexpr char trophyOff[] = "\xef\x90\xb8"; + inline constexpr char trowel[] = "\xef\x8d\xa8"; + inline constexpr char truck[] = "\xee\xaf\x84"; + inline constexpr char truckDelivery[] = "\xee\xb1\x8b"; + inline constexpr char truckLoading[] = "\xef\x87\x9a"; + inline constexpr char truckOff[] = "\xee\xbc\x83"; + inline constexpr char truckReturn[] = "\xee\xb1\x8c"; + inline constexpr char txt[] = "\xef\x8e\xb1"; + inline constexpr char typeface[] = "\xef\xb6\xab"; + inline constexpr char typography[] = "\xee\xaf\x85"; + inline constexpr char typographyOff[] = "\xef\x86\xba"; + inline constexpr char uTurnLeft[] = "\xef\xba\xa2"; + inline constexpr char uTurnRight[] = "\xef\xba\xa1"; + inline constexpr char ufo[] = "\xef\x89\xaf"; + inline constexpr char ufoOff[] = "\xef\x89\xae"; + inline constexpr char uhd[] = "\xf0\x90\x82\xaa"; + inline constexpr char umbrella[] = "\xee\xaf\xb1"; + inline constexpr char umbrella2[] = "\xef\xbc\x8e"; + inline constexpr char umbrellaClosed[] = "\xef\xbc\x8c"; + inline constexpr char umbrellaClosed2[] = "\xef\xbc\x8d"; + inline constexpr char umbrellaOff[] = "\xef\x86\xbb"; + inline constexpr char underline[] = "\xee\xae\xa2"; + inline constexpr char underlineOff[] = "\xf0\x90\x89\xa9"; + inline constexpr char unicycle[] = "\xf0\x90\x89\x84"; + inline constexpr char universe[] = "\xef\xb3\x84"; + inline constexpr char unlink[] = "\xee\xad\x86"; + inline constexpr char upload[] = "\xee\xad\x87"; + inline constexpr char urgent[] = "\xee\xad\x88"; + inline constexpr char usb[] = "\xef\x80\x8c"; + inline constexpr char user[] = "\xee\xad\x8d"; + inline constexpr char userBitcoin[] = "\xef\xbc\xb0"; + inline constexpr char userBolt[] = "\xef\xa7\x91"; + inline constexpr char userCancel[] = "\xef\xa7\x92"; + inline constexpr char userCheck[] = "\xee\xad\x89"; + inline constexpr char userCircle[] = "\xee\xbd\xa8"; + inline constexpr char userCode[] = "\xef\xa7\x93"; + inline constexpr char userCog[] = "\xef\xa7\x94"; + inline constexpr char userDollar[] = "\xef\xa7\x95"; + inline constexpr char userDown[] = "\xef\xa7\x96"; + inline constexpr char userEdit[] = "\xef\x9f\x8c"; + inline constexpr char userExclamation[] = "\xee\xb0\x92"; + inline constexpr char userHeart[] = "\xef\x9f\x8d"; + inline constexpr char userHexagon[] = "\xef\xb1\x8e"; + inline constexpr char userKey[] = "\xf0\x90\x87\xaa"; + inline constexpr char userMinus[] = "\xee\xad\x8a"; + inline constexpr char userOff[] = "\xee\xb3\xb9"; + inline constexpr char userPause[] = "\xef\xa7\x97"; + inline constexpr char userPentagon[] = "\xef\xb1\x8f"; + inline constexpr char userPin[] = "\xef\x9f\x8e"; + inline constexpr char userPlus[] = "\xee\xad\x8b"; + inline constexpr char userQuestion[] = "\xef\x9f\x8f"; + inline constexpr char userScan[] = "\xef\xb2\xaf"; + inline constexpr char userScreen[] = "\xef\xba\xa0"; + inline constexpr char userSearch[] = "\xee\xbe\x89"; + inline constexpr char userShare[] = "\xef\xa7\x98"; + inline constexpr char userShield[] = "\xef\x9f\x90"; + inline constexpr char userSquare[] = "\xef\xb1\x91"; + inline constexpr char userSquareRounded[] = "\xef\xb1\x90"; + inline constexpr char userStar[] = "\xef\x9f\x91"; + inline constexpr char userUp[] = "\xef\x9f\x92"; + inline constexpr char userX[] = "\xee\xad\x8c"; + inline constexpr char users[] = "\xee\xaf\xb2"; + inline constexpr char usersGroup[] = "\xef\xa8\xa1"; + inline constexpr char usersMinus[] = "\xef\xa8\x8e"; + inline constexpr char usersPlus[] = "\xef\xa8\x8f"; + inline constexpr char uvIndex[] = "\xef\x8e\xb2"; + inline constexpr char uxCircle[] = "\xef\x8d\xa9"; + inline constexpr char vaccine[] = "\xee\xbc\x84"; + inline constexpr char vaccineBottle[] = "\xee\xbd\xa9"; + inline constexpr char vaccineBottleOff[] = "\xef\x90\xb9"; + inline constexpr char vaccineOff[] = "\xef\x86\xbc"; + inline constexpr char vacuumCleaner[] = "\xef\x97\xa6"; + inline constexpr char variable[] = "\xee\xbc\x85"; + inline constexpr char variableMinus[] = "\xef\x8d\xaa"; + inline constexpr char variableOff[] = "\xef\x86\xbd"; + inline constexpr char variablePlus[] = "\xef\x8d\xab"; + inline constexpr char vector[] = "\xee\xb2\xa9"; + inline constexpr char vectorBezier[] = "\xee\xbc\x9d"; + inline constexpr char vectorBezier2[] = "\xef\x86\xa3"; + inline constexpr char vectorBezierArc[] = "\xef\x93\x8d"; + inline constexpr char vectorBezierCircle[] = "\xef\x93\x8e"; + inline constexpr char vectorOff[] = "\xef\x86\xbe"; + inline constexpr char vectorSpline[] = "\xef\x95\xa5"; + inline constexpr char vectorTriangle[] = "\xee\xb2\xa8"; + inline constexpr char vectorTriangleOff[] = "\xef\x86\xbf"; + inline constexpr char venus[] = "\xee\xb2\x86"; + inline constexpr char versions[] = "\xee\xb5\x92"; + inline constexpr char versionsOff[] = "\xef\x87\x80"; + inline constexpr char video[] = "\xee\xb4\xa2"; + inline constexpr char videoMinus[] = "\xee\xb4\x9f"; + inline constexpr char videoOff[] = "\xee\xb4\xa0"; + inline constexpr char videoPlus[] = "\xee\xb4\xa1"; + inline constexpr char view360[] = "\xee\xb6\x84"; + inline constexpr char view360Arrow[] = "\xef\x98\xaf"; + inline constexpr char view360Number[] = "\xef\x95\xa6"; + inline constexpr char view360Off[] = "\xef\x87\x81"; + inline constexpr char viewfinder[] = "\xee\xad\x8e"; + inline constexpr char viewfinderOff[] = "\xef\x87\x82"; + inline constexpr char viewportNarrow[] = "\xee\xaf\xb3"; + inline constexpr char viewportShort[] = "\xef\xbb\xa9"; + inline constexpr char viewportTall[] = "\xef\xbb\xa8"; + inline constexpr char viewportWide[] = "\xee\xaf\xb4"; + inline constexpr char vignette[] = "\xf0\x90\x89\x96"; + inline constexpr char vinyl[] = "\xef\x80\x8d"; + inline constexpr char vip[] = "\xef\x8e\xb3"; + inline constexpr char vip2[] = "\xf0\x90\x87\xba"; + inline constexpr char vipOff[] = "\xef\x90\xba"; + inline constexpr char virtualSpace[] = "\xf0\x90\x89\xa8"; + inline constexpr char virus[] = "\xee\xad\xb4"; + inline constexpr char virusOff[] = "\xee\xb5\xa6"; + inline constexpr char virusSearch[] = "\xee\xb5\xa7"; + inline constexpr char vocabulary[] = "\xee\xbc\x9e"; + inline constexpr char vocabularyOff[] = "\xef\x90\xbb"; + inline constexpr char volcano[] = "\xef\x9e\x9c"; + inline constexpr char volume[] = "\xee\xad\x91"; + inline constexpr char volume2[] = "\xee\xad\x8f"; + inline constexpr char volume3[] = "\xee\xad\x90"; + inline constexpr char volume4[] = "\xf0\x90\x86\x9d"; + inline constexpr char volumeOff[] = "\xef\x87\x83"; + inline constexpr char vs[] = "\xef\xb1\x92"; + inline constexpr char walk[] = "\xee\xb2\x87"; + inline constexpr char wall[] = "\xee\xbd\xba"; + inline constexpr char wallOff[] = "\xef\x90\xbc"; + inline constexpr char wallet[] = "\xee\xad\xb5"; + inline constexpr char walletOff[] = "\xef\x87\x84"; + inline constexpr char wallpaper[] = "\xee\xbd\x96"; + inline constexpr char wallpaperOff[] = "\xef\x87\x85"; + inline constexpr char wand[] = "\xee\xaf\x8b"; + inline constexpr char wandOff[] = "\xef\x87\x86"; + inline constexpr char wash[] = "\xef\x8c\x91"; + inline constexpr char washDry[] = "\xef\x8c\x84"; + inline constexpr char washDry1[] = "\xef\x8b\xba"; + inline constexpr char washDry2[] = "\xef\x8b\xbb"; + inline constexpr char washDry3[] = "\xef\x8b\xbc"; + inline constexpr char washDryA[] = "\xef\x8b\xbd"; + inline constexpr char washDryDip[] = "\xef\x8b\xbe"; + inline constexpr char washDryF[] = "\xef\x8b\xbf"; + inline constexpr char washDryFlat[] = "\xef\xa9\xbf"; + inline constexpr char washDryHang[] = "\xef\x8c\x80"; + inline constexpr char washDryOff[] = "\xef\x8c\x81"; + inline constexpr char washDryP[] = "\xef\x8c\x82"; + inline constexpr char washDryShade[] = "\xef\x8c\x83"; + inline constexpr char washDryW[] = "\xef\x8c\xa2"; + inline constexpr char washDryclean[] = "\xef\x8c\x85"; + inline constexpr char washDrycleanOff[] = "\xef\x8c\xa3"; + inline constexpr char washEco[] = "\xef\xaa\x80"; + inline constexpr char washGentle[] = "\xef\x8c\x86"; + inline constexpr char washHand[] = "\xef\xaa\x81"; + inline constexpr char washMachine[] = "\xef\x89\x9e"; + inline constexpr char washOff[] = "\xef\x8c\x87"; + inline constexpr char washPress[] = "\xef\x8c\x88"; + inline constexpr char washTemperature1[] = "\xef\x8c\x89"; + inline constexpr char washTemperature2[] = "\xef\x8c\x8a"; + inline constexpr char washTemperature3[] = "\xef\x8c\x8b"; + inline constexpr char washTemperature4[] = "\xef\x8c\x8c"; + inline constexpr char washTemperature5[] = "\xef\x8c\x8d"; + inline constexpr char washTemperature6[] = "\xef\x8c\x8e"; + inline constexpr char washTumbleDry[] = "\xef\x8c\x8f"; + inline constexpr char washTumbleOff[] = "\xef\x8c\x90"; + inline constexpr char waterpolo[] = "\xef\xa9\xaf"; + inline constexpr char waveSawTool[] = "\xee\xb3\x93"; + inline constexpr char waveSine[] = "\xee\xb3\x94"; + inline constexpr char waveSquare[] = "\xee\xb3\x95"; + inline constexpr char wavesElectricity[] = "\xef\xb3\x85"; + inline constexpr char webhook[] = "\xef\x80\x9e"; + inline constexpr char webhookOff[] = "\xef\x90\xbd"; + inline constexpr char weight[] = "\xef\x96\x89"; + inline constexpr char wheat[] = "\xf0\x90\x82\xa8"; + inline constexpr char wheatOff[] = "\xf0\x90\x82\xa9"; + inline constexpr char wheel[] = "\xef\xb1\xa4"; + inline constexpr char wheelchair[] = "\xef\x87\x9b"; + inline constexpr char wheelchairOff[] = "\xef\x90\xbe"; + inline constexpr char whirl[] = "\xef\x94\x9d"; + inline constexpr char whisk[] = "\xf0\x90\x86\xa0"; + inline constexpr char wifi[] = "\xee\xad\x92"; + inline constexpr char wifi0[] = "\xee\xae\xa3"; + inline constexpr char wifi1[] = "\xee\xae\xa4"; + inline constexpr char wifi2[] = "\xee\xae\xa5"; + inline constexpr char wifiOff[] = "\xee\xb3\xba"; + inline constexpr char wind[] = "\xee\xb0\xb4"; + inline constexpr char windElectricity[] = "\xef\xb3\x86"; + inline constexpr char windOff[] = "\xef\x87\x87"; + inline constexpr char windmill[] = "\xee\xb6\x85"; + inline constexpr char windmillOff[] = "\xef\x87\x88"; + inline constexpr char window[] = "\xee\xbc\x86"; + inline constexpr char windowMaximize[] = "\xef\x87\xb1"; + inline constexpr char windowMinimize[] = "\xef\x87\xb2"; + inline constexpr char windowOff[] = "\xef\x87\x89"; + inline constexpr char windsock[] = "\xef\x81\xad"; + inline constexpr char wiper[] = "\xee\xb2\xab"; + inline constexpr char wiperWash[] = "\xee\xb2\xaa"; + inline constexpr char woman[] = "\xee\xad\x93"; + inline constexpr char wood[] = "\xef\x8d\x99"; + inline constexpr char world[] = "\xee\xad\x94"; + inline constexpr char worldBolt[] = "\xef\xa7\x99"; + inline constexpr char worldCancel[] = "\xef\xa7\x9a"; + inline constexpr char worldCheck[] = "\xef\xa7\x9b"; + inline constexpr char worldCode[] = "\xef\xa7\x9c"; + inline constexpr char worldCog[] = "\xef\xa7\x9d"; + inline constexpr char worldDollar[] = "\xef\xa7\x9e"; + inline constexpr char worldDown[] = "\xef\xa7\x9f"; + inline constexpr char worldDownload[] = "\xee\xbe\x8a"; + inline constexpr char worldExclamation[] = "\xef\xa7\xa0"; + inline constexpr char worldHeart[] = "\xef\xa7\xa1"; + inline constexpr char worldLatitude[] = "\xee\xb4\xae"; + inline constexpr char worldLongitude[] = "\xee\xb4\xaf"; + inline constexpr char worldMap[] = "\xf0\x90\x87\xa9"; + inline constexpr char worldMinus[] = "\xef\xa7\xa2"; + inline constexpr char worldOff[] = "\xef\x87\x8a"; + inline constexpr char worldPause[] = "\xef\xa7\xa3"; + inline constexpr char worldPin[] = "\xef\xa7\xa4"; + inline constexpr char worldPlus[] = "\xef\xa7\xa5"; + inline constexpr char worldQuestion[] = "\xef\xa7\xa6"; + inline constexpr char worldSearch[] = "\xef\xa7\xa7"; + inline constexpr char worldShare[] = "\xef\xa7\xa8"; + inline constexpr char worldStar[] = "\xef\xa7\xa9"; + inline constexpr char worldUp[] = "\xef\xa7\xaa"; + inline constexpr char worldUpload[] = "\xee\xbe\x8b"; + inline constexpr char worldWww[] = "\xef\x8e\x8f"; + inline constexpr char worldX[] = "\xef\xa7\xab"; + inline constexpr char wreckingBall[] = "\xee\xb6\x97"; + inline constexpr char writing[] = "\xee\xbc\x88"; + inline constexpr char writingOff[] = "\xef\x87\x8b"; + inline constexpr char writingSign[] = "\xee\xbc\x87"; + inline constexpr char writingSignOff[] = "\xef\x87\x8c"; + inline constexpr char x[] = "\xee\xad\x95"; + inline constexpr char xMark[] = "\xf0\x90\x88\xa0"; + inline constexpr char xPowerY[] = "\xf0\x90\x81\xb2"; + inline constexpr char xboxA[] = "\xef\x8a\xb6"; + inline constexpr char xboxB[] = "\xef\x8a\xb7"; + inline constexpr char xboxX[] = "\xef\x8a\xb8"; + inline constexpr char xboxY[] = "\xef\x8a\xb9"; + inline constexpr char xd[] = "\xef\xa8\xb3"; + inline constexpr char xxx[] = "\xef\xb0\xa0"; + inline constexpr char yinYang[] = "\xee\xb0\xb5"; + inline constexpr char yoga[] = "\xef\x80\x9f"; + inline constexpr char zeppelin[] = "\xef\x89\xb0"; + inline constexpr char zeppelinOff[] = "\xef\x90\xbf"; + inline constexpr char zeroConfig[] = "\xf0\x90\x87\xa8"; + inline constexpr char zip[] = "\xef\x8e\xb4"; + inline constexpr char zodiacAquarius[] = "\xee\xb2\xac"; + inline constexpr char zodiacAries[] = "\xee\xb2\xad"; + inline constexpr char zodiacCancer[] = "\xee\xb2\xae"; + inline constexpr char zodiacCapricorn[] = "\xee\xb2\xaf"; + inline constexpr char zodiacGemini[] = "\xee\xb2\xb0"; + inline constexpr char zodiacLeo[] = "\xee\xb2\xb1"; + inline constexpr char zodiacLibra[] = "\xee\xb2\xb2"; + inline constexpr char zodiacPisces[] = "\xee\xb2\xb3"; + inline constexpr char zodiacSagittarius[] = "\xee\xb2\xb4"; + inline constexpr char zodiacScorpio[] = "\xee\xb2\xb5"; + inline constexpr char zodiacTaurus[] = "\xee\xb2\xb6"; + inline constexpr char zodiacVirgo[] = "\xee\xb2\xb7"; + inline constexpr char zoom[] = "\xef\xb6\xaa"; + inline constexpr char zoomCancel[] = "\xee\xb1\x8d"; + inline constexpr char zoomCheck[] = "\xee\xbc\x89"; + inline constexpr char zoomCode[] = "\xef\x81\xbf"; + inline constexpr char zoomExclamation[] = "\xef\x82\x80"; + inline constexpr char zoomIn[] = "\xee\xad\x96"; + inline constexpr char zoomInArea[] = "\xef\x87\x9c"; + inline constexpr char zoomMoney[] = "\xee\xbc\x8a"; + inline constexpr char zoomOut[] = "\xee\xad\x97"; + inline constexpr char zoomOutArea[] = "\xef\x87\x9d"; + inline constexpr char zoomPan[] = "\xef\x87\x9e"; + inline constexpr char zoomQuestion[] = "\xee\xb7\xab"; + inline constexpr char zoomReplace[] = "\xef\x8a\xa7"; + inline constexpr char zoomReset[] = "\xef\x8a\x95"; + inline constexpr char zoomScan[] = "\xef\xb2\xb0"; + inline constexpr char zzz[] = "\xef\x88\xa8"; + inline constexpr char zzzOff[] = "\xef\x91\x80"; + inline constexpr char icon123[] = "\xef\x95\x94"; + inline constexpr char icon360[] = "\xef\x98\xaf"; + inline constexpr char codeAsterix[] = "\xef\x8c\x92"; + inline constexpr char discount2[] = "\xee\xb9\xbc"; + inline constexpr char discount2Off[] = "\xef\x8f\xa6"; + inline constexpr char discountCheck[] = "\xef\x87\xb8"; + inline constexpr char handRock[] = "\xee\xba\x97"; + inline constexpr char sortDeacendingSmallBig[] = "\xef\xb6\x96"; + inline constexpr char shiJumping[] = "\xef\xa9\xac"; + inline constexpr char boxSeam[] = "\xee\xab\xbf"; + inline constexpr char kering[] = "\xee\xbe\xb8"; + inline constexpr char icon2fa[] = "\xee\xb2\xa0"; + inline constexpr char icon3dCubeSphere[] = "\xee\xb3\x97"; + inline constexpr char icon3dCubeSphereOff[] = "\xef\x8e\xb5"; + inline constexpr char icon3dRotate[] = "\xef\x80\xa0"; + inline constexpr char icon12Hours[] = "\xef\xb1\x93"; + inline constexpr char icon24Hours[] = "\xef\x97\xa7"; + inline constexpr char icon360View[] = "\xef\x95\xa6"; + inline constexpr char circle0[] = "\xee\xb8\xb4"; + inline constexpr char circle1[] = "\xee\xb8\xb5"; + inline constexpr char circle2[] = "\xee\xb8\xb6"; + inline constexpr char circle3[] = "\xee\xb8\xb7"; + inline constexpr char circle4[] = "\xee\xb8\xb8"; + inline constexpr char circle5[] = "\xee\xb8\xb9"; + inline constexpr char circle6[] = "\xee\xb8\xba"; + inline constexpr char circle7[] = "\xee\xb8\xbb"; + inline constexpr char circle8[] = "\xee\xb8\xbc"; + inline constexpr char circle9[] = "\xee\xb8\xbd"; + inline constexpr char hexagon0[] = "\xef\x91\x99"; + inline constexpr char hexagon1[] = "\xef\x91\x9a"; + inline constexpr char hexagon2[] = "\xef\x91\x9b"; + inline constexpr char hexagon3[] = "\xef\x91\x9c"; + inline constexpr char hexagon4[] = "\xef\x91\x9d"; + inline constexpr char hexagon5[] = "\xef\x91\x9e"; + inline constexpr char hexagon6[] = "\xef\x91\x9f"; + inline constexpr char hexagon7[] = "\xef\x91\xa0"; + inline constexpr char hexagon8[] = "\xef\x91\xa1"; + inline constexpr char hexagon9[] = "\xef\x91\xa2"; + inline constexpr char square0[] = "\xee\xbb\xa5"; + inline constexpr char square1[] = "\xee\xbb\xa6"; + inline constexpr char square2[] = "\xee\xbb\xa7"; + inline constexpr char square3[] = "\xee\xbb\xa8"; + inline constexpr char square4[] = "\xee\xbb\xa9"; + inline constexpr char square5[] = "\xee\xbb\xaa"; + inline constexpr char square6[] = "\xee\xbb\xab"; + inline constexpr char square7[] = "\xee\xbb\xac"; + inline constexpr char square8[] = "\xee\xbb\xad"; + inline constexpr char square9[] = "\xee\xbb\xae"; + inline constexpr char messageCircle2[] = "\xee\xab\xad"; + inline constexpr char moodSuprised[] = "\xee\xb0\x84"; + inline constexpr char circleDashedLetterLetterV[] = "\xef\xbe\x84"; + inline constexpr char seeding[] = "\xee\xb5\x91"; + inline constexpr char seedingOff[] = "\xef\x86\x9d"; + inline constexpr char brandAdobePremier[] = "\xef\xbc\xa6"; + inline constexpr char foodsteps[] = "\xf0\x90\x89\xa5"; + inline constexpr char moodConfuzed[] = "\xee\xab\xb3"; + inline constexpr char currencyRubel[] = "\xee\xb9\xa7"; + inline constexpr char sportBillard[] = "\xee\xbb\xa4"; + inline constexpr char physotherapist[] = "\xee\xba\xbe"; + inline constexpr char ikosaedr[] = "\xef\xbb\x86"; + inline constexpr char genderTrasvesti[] = "\xef\x83\xb2"; + inline constexpr char brandKakoTalk[] = "\xef\xb4\xad"; + inline constexpr char brandAdobeAfterEffect[] = "\xef\xbc\xaa"; + + inline constexpr char allGlyphs[] = + "\xee\xa8\x82\xee\xa8\x83\xee\xa8\x84\xee\xa8\x85\xee\xa8\x86\xee\xa8\x87\xee\xa8\x88\xee\xa8\x89\xee\xa8\x8a\xee\xa8\x8b\xee\xa8\x8c\xee\xa8\x8d\xee\xa8\x8e\xee\xa8\x8f\xee\xa8\x90\xee\xa8\x91\xee\xa8\x92\xee\xa8\x93\xee\xa8\x94\xee\xa8\x95\xee\xa8\x96\xee\xa8\x97\xee\xa8\x98\xee\xa8\x99\xee\xa8\x9a\xee\xa8\x9b\xee\xa8\x9c\xee\xa8\x9d\xee\xa8\x9e\xee\xa8\x9f\xee\xa8\xa0\xee\xa8\xa1" + "\xee\xa8\xa2\xee\xa8\xa3\xee\xa8\xa4\xee\xa8\xa5\xee\xa8\xa6\xee\xa8\xa7\xee\xa8\xa8\xee\xa8\xa9\xee\xa8\xaa\xee\xa8\xab\xee\xa8\xac\xee\xa8\xad\xee\xa8\xae\xee\xa8\xaf\xee\xa8\xb0\xee\xa8\xb1\xee\xa8\xb2\xee\xa8\xb3\xee\xa8\xb4\xee\xa8\xb5\xee\xa8\xb6\xee\xa8\xb7\xee\xa8\xb8\xee\xa8\xb9\xee\xa8\xba\xee\xa8\xbb\xee\xa8\xbc\xee\xa8\xbd\xee\xa8\xbe\xee\xa8\xbf\xee\xa9\x80\xee\xa9\x81" + "\xee\xa9\x82\xee\xa9\x83\xee\xa9\x84\xee\xa9\x85\xee\xa9\x86\xee\xa9\x87\xee\xa9\x88\xee\xa9\x89\xee\xa9\x8a\xee\xa9\x8b\xee\xa9\x8c\xee\xa9\x8d\xee\xa9\x8e\xee\xa9\x8f\xee\xa9\x90\xee\xa9\x91\xee\xa9\x92\xee\xa9\x93\xee\xa9\x94\xee\xa9\x95\xee\xa9\x96\xee\xa9\x97\xee\xa9\x98\xee\xa9\x99\xee\xa9\x9a\xee\xa9\x9b\xee\xa9\x9c\xee\xa9\x9d\xee\xa9\x9e\xee\xa9\x9f\xee\xa9\xa0\xee\xa9\xa1" + "\xee\xa9\xa2\xee\xa9\xa3\xee\xa9\xa4\xee\xa9\xa5\xee\xa9\xa6\xee\xa9\xa7\xee\xa9\xa8\xee\xa9\xa9\xee\xa9\xaa\xee\xa9\xab\xee\xa9\xac\xee\xa9\xad\xee\xa9\xae\xee\xa9\xaf\xee\xa9\xb0\xee\xa9\xb1\xee\xa9\xb2\xee\xa9\xb3\xee\xa9\xb4\xee\xa9\xb5\xee\xa9\xb6\xee\xa9\xb7\xee\xa9\xb8\xee\xa9\xb9\xee\xa9\xba\xee\xa9\xbb\xee\xa9\xbc\xee\xa9\xbd\xee\xa9\xbe\xee\xa9\xbf\xee\xaa\x80\xee\xaa\x81" + "\xee\xaa\x82\xee\xaa\x83\xee\xaa\x84\xee\xaa\x85\xee\xaa\x86\xee\xaa\x87\xee\xaa\x88\xee\xaa\x89\xee\xaa\x8a\xee\xaa\x8b\xee\xaa\x8c\xee\xaa\x8d\xee\xaa\x8e\xee\xaa\x8f\xee\xaa\x90\xee\xaa\x91\xee\xaa\x92\xee\xaa\x93\xee\xaa\x94\xee\xaa\x95\xee\xaa\x96\xee\xaa\x97\xee\xaa\x98\xee\xaa\x99\xee\xaa\x9a\xee\xaa\x9b\xee\xaa\x9c\xee\xaa\x9d\xee\xaa\x9e\xee\xaa\x9f\xee\xaa\xa0\xee\xaa\xa1" + "\xee\xaa\xa2\xee\xaa\xa3\xee\xaa\xa4\xee\xaa\xa5\xee\xaa\xa6\xee\xaa\xa7\xee\xaa\xa8\xee\xaa\xaa\xee\xaa\xab\xee\xaa\xac\xee\xaa\xad\xee\xaa\xae\xee\xaa\xaf\xee\xaa\xb0\xee\xaa\xb1\xee\xaa\xb2\xee\xaa\xb3\xee\xaa\xb4\xee\xaa\xb5\xee\xaa\xb6\xee\xaa\xb7\xee\xaa\xb8\xee\xaa\xb9\xee\xaa\xba\xee\xaa\xbc\xee\xaa\xbd\xee\xaa\xbe\xee\xaa\xbf\xee\xab\x80\xee\xab\x81\xee\xab\x82\xee\xab\x83" + "\xee\xab\x84\xee\xab\x85\xee\xab\x86\xee\xab\x87\xee\xab\x88\xee\xab\x89\xee\xab\x8a\xee\xab\x8b\xee\xab\x8c\xee\xab\x8d\xee\xab\x8e\xee\xab\x8f\xee\xab\x90\xee\xab\x91\xee\xab\x92\xee\xab\x93\xee\xab\x94\xee\xab\x95\xee\xab\x96\xee\xab\x97\xee\xab\x98\xee\xab\x99\xee\xab\x9a\xee\xab\x9b\xee\xab\x9c\xee\xab\x9d\xee\xab\x9e\xee\xab\x9f\xee\xab\xa0\xee\xab\xa1\xee\xab\xa2\xee\xab\xa3" + "\xee\xab\xa4\xee\xab\xa5\xee\xab\xa6\xee\xab\xa7\xee\xab\xa8\xee\xab\xa9\xee\xab\xaa\xee\xab\xab\xee\xab\xac\xee\xab\xad\xee\xab\xae\xee\xab\xaf\xee\xab\xb0\xee\xab\xb1\xee\xab\xb2\xee\xab\xb3\xee\xab\xb4\xee\xab\xb5\xee\xab\xb6\xee\xab\xb7\xee\xab\xb8\xee\xab\xb9\xee\xab\xba\xee\xab\xbb\xee\xab\xbc\xee\xab\xbd\xee\xab\xbe\xee\xab\xbf\xee\xac\x80\xee\xac\x81\xee\xac\x82\xee\xac\x83" + "\xee\xac\x84\xee\xac\x85\xee\xac\x86\xee\xac\x87\xee\xac\x88\xee\xac\x89\xee\xac\x8a\xee\xac\x8b\xee\xac\x8c\xee\xac\x8d\xee\xac\x8e\xee\xac\x8f\xee\xac\x90\xee\xac\x91\xee\xac\x92\xee\xac\x93\xee\xac\x94\xee\xac\x95\xee\xac\x96\xee\xac\x97\xee\xac\x98\xee\xac\x99\xee\xac\x9a\xee\xac\x9b\xee\xac\x9c\xee\xac\x9d\xee\xac\x9e\xee\xac\x9f\xee\xac\xa0\xee\xac\xa1\xee\xac\xa2\xee\xac\xa3" + "\xee\xac\xa4\xee\xac\xa5\xee\xac\xa6\xee\xac\xa7\xee\xac\xa8\xee\xac\xa9\xee\xac\xaa\xee\xac\xab\xee\xac\xac\xee\xac\xad\xee\xac\xae\xee\xac\xaf\xee\xac\xb0\xee\xac\xb1\xee\xac\xb2\xee\xac\xb3\xee\xac\xb4\xee\xac\xb5\xee\xac\xb6\xee\xac\xb7\xee\xac\xb8\xee\xac\xb9\xee\xac\xba\xee\xac\xbb\xee\xac\xbc\xee\xac\xbd\xee\xac\xbe\xee\xac\xbf\xee\xad\x80\xee\xad\x81\xee\xad\x82\xee\xad\x83" + "\xee\xad\x84\xee\xad\x85\xee\xad\x86\xee\xad\x87\xee\xad\x88\xee\xad\x89\xee\xad\x8a\xee\xad\x8b\xee\xad\x8c\xee\xad\x8d\xee\xad\x8e\xee\xad\x8f\xee\xad\x90\xee\xad\x91\xee\xad\x92\xee\xad\x93\xee\xad\x94\xee\xad\x95\xee\xad\x96\xee\xad\x97\xee\xad\x98\xee\xad\x99\xee\xad\x9a\xee\xad\x9b\xee\xad\x9c\xee\xad\x9d\xee\xad\x9e\xee\xad\x9f\xee\xad\xa0\xee\xad\xa1\xee\xad\xa2\xee\xad\xa3" + "\xee\xad\xa4\xee\xad\xa5\xee\xad\xa6\xee\xad\xa7\xee\xad\xa8\xee\xad\xa9\xee\xad\xaa\xee\xad\xab\xee\xad\xac\xee\xad\xad\xee\xad\xae\xee\xad\xaf\xee\xad\xb0\xee\xad\xb1\xee\xad\xb2\xee\xad\xb3\xee\xad\xb4\xee\xad\xb5\xee\xad\xb6\xee\xad\xb7\xee\xad\xb8\xee\xad\xb9\xee\xad\xba\xee\xad\xbb\xee\xad\xbc\xee\xad\xbd\xee\xad\xbe\xee\xad\xbf\xee\xae\x80\xee\xae\x82\xee\xae\x83\xee\xae\x84" + "\xee\xae\x85\xee\xae\x86\xee\xae\x87\xee\xae\x88\xee\xae\x89\xee\xae\x8a\xee\xae\x8b\xee\xae\x8c\xee\xae\x8d\xee\xae\x8e\xee\xae\x8f\xee\xae\x90\xee\xae\x91\xee\xae\x92\xee\xae\x93\xee\xae\x94\xee\xae\x95\xee\xae\x96\xee\xae\x97\xee\xae\x99\xee\xae\x9a\xee\xae\x9b\xee\xae\x9c\xee\xae\x9d\xee\xae\x9e\xee\xae\x9f\xee\xae\xa0\xee\xae\xa1\xee\xae\xa2\xee\xae\xa3\xee\xae\xa4\xee\xae\xa5" + "\xee\xae\xa6\xee\xae\xa7\xee\xae\xa8\xee\xae\xa9\xee\xae\xaa\xee\xae\xab\xee\xae\xac\xee\xae\xad\xee\xae\xae\xee\xae\xaf\xee\xae\xb0\xee\xae\xb1\xee\xae\xb2\xee\xae\xb3\xee\xae\xb4\xee\xae\xb5\xee\xae\xb6\xee\xae\xb7\xee\xae\xb8\xee\xae\xb9\xee\xae\xba\xee\xae\xbb\xee\xae\xbc\xee\xae\xbd\xee\xae\xbe\xee\xaf\x80\xee\xaf\x81\xee\xaf\x82\xee\xaf\x84\xee\xaf\x85\xee\xaf\x86\xee\xaf\x87" + "\xee\xaf\x88\xee\xaf\x89\xee\xaf\x8a\xee\xaf\x8b\xee\xaf\x8c\xee\xaf\x8d\xee\xaf\x8e\xee\xaf\x8f\xee\xaf\x90\xee\xaf\x91\xee\xaf\x92\xee\xaf\x93\xee\xaf\x94\xee\xaf\x95\xee\xaf\x96\xee\xaf\x97\xee\xaf\x98\xee\xaf\x99\xee\xaf\x9a\xee\xaf\x9b\xee\xaf\x9c\xee\xaf\x9d\xee\xaf\x9e\xee\xaf\x9f\xee\xaf\xa1\xee\xaf\xa2\xee\xaf\xa3\xee\xaf\xa4\xee\xaf\xa5\xee\xaf\xa6\xee\xaf\xa7\xee\xaf\xa8" + "\xee\xaf\xa9\xee\xaf\xaa\xee\xaf\xab\xee\xaf\xac\xee\xaf\xad\xee\xaf\xae\xee\xaf\xaf\xee\xaf\xb0\xee\xaf\xb1\xee\xaf\xb2\xee\xaf\xb3\xee\xaf\xb4\xee\xaf\xb5\xee\xaf\xb6\xee\xaf\xb7\xee\xaf\xb9\xee\xaf\xba\xee\xaf\xbb\xee\xb0\x80\xee\xb0\x81\xee\xb0\x82\xee\xb0\x83\xee\xb0\x84\xee\xb0\x85\xee\xb0\x86\xee\xb0\x87\xee\xb0\x88\xee\xb0\x89\xee\xb0\x8a\xee\xb0\x8b\xee\xb0\x8c\xee\xb0\x8d" + "\xee\xb0\x8e\xee\xb0\x8f\xee\xb0\x90\xee\xb0\x92\xee\xb0\x93\xee\xb0\x94\xee\xb0\x95\xee\xb0\x96\xee\xb0\x97\xee\xb0\x98\xee\xb0\x99\xee\xb0\x9a\xee\xb0\x9b\xee\xb0\x9c\xee\xb0\x9d\xee\xb0\x9e\xee\xb0\x9f\xee\xb0\xa0\xee\xb0\xa1\xee\xb0\xa2\xee\xb0\xa3\xee\xb0\xa4\xee\xb0\xa5\xee\xb0\xa6\xee\xb0\xa7\xee\xb0\xa8\xee\xb0\xa9\xee\xb0\xaa\xee\xb0\xab\xee\xb0\xac\xee\xb0\xad\xee\xb0\xae" + "\xee\xb0\xaf\xee\xb0\xb0\xee\xb0\xb1\xee\xb0\xb4\xee\xb0\xb5\xee\xb0\xb6\xee\xb0\xb7\xee\xb0\xb8\xee\xb0\xb9\xee\xb0\xba\xee\xb0\xbb\xee\xb0\xbc\xee\xb0\xbd\xee\xb0\xbe\xee\xb0\xbf\xee\xb1\x80\xee\xb1\x81\xee\xb1\x82\xee\xb1\x83\xee\xb1\x84\xee\xb1\x85\xee\xb1\x86\xee\xb1\x87\xee\xb1\x88\xee\xb1\x89\xee\xb1\x8a\xee\xb1\x8b\xee\xb1\x8c\xee\xb1\x8d\xee\xb1\x8e\xee\xb1\x90\xee\xb1\x91" + "\xee\xb1\x92\xee\xb1\x93\xee\xb1\x94\xee\xb1\x95\xee\xb1\x96\xee\xb1\x97\xee\xb1\x98\xee\xb1\x99\xee\xb1\x9a\xee\xb1\x9b\xee\xb1\x9c\xee\xb1\x9d\xee\xb1\x9e\xee\xb1\x9f\xee\xb1\xa0\xee\xb1\xa1\xee\xb1\xa2\xee\xb1\xa3\xee\xb1\xa4\xee\xb1\xa5\xee\xb1\xa6\xee\xb1\xa7\xee\xb1\xa8\xee\xb1\xa9\xee\xb1\xab\xee\xb1\xac\xee\xb1\xae\xee\xb1\xaf\xee\xb1\xb0\xee\xb1\xb1\xee\xb1\xb2\xee\xb1\xb3" + "\xee\xb1\xb4\xee\xb1\xb5\xee\xb1\xb6\xee\xb1\xb7\xee\xb1\xb8\xee\xb1\xb9\xee\xb1\xba\xee\xb1\xbb\xee\xb1\xbc\xee\xb1\xbd\xee\xb1\xbe\xee\xb1\xbf\xee\xb2\x80\xee\xb2\x81\xee\xb2\x82\xee\xb2\x83\xee\xb2\x84\xee\xb2\x86\xee\xb2\x87\xee\xb2\x88\xee\xb2\x89\xee\xb2\x8a\xee\xb2\x8b\xee\xb2\x8c\xee\xb2\x8d\xee\xb2\x8e\xee\xb2\x8f\xee\xb2\x90\xee\xb2\x91\xee\xb2\x92\xee\xb2\x93\xee\xb2\x94" + "\xee\xb2\x95\xee\xb2\x96\xee\xb2\x97\xee\xb2\x98\xee\xb2\x99\xee\xb2\x9a\xee\xb2\x9b\xee\xb2\x9c\xee\xb2\x9d\xee\xb2\x9e\xee\xb2\x9f\xee\xb2\xa0\xee\xb2\xa1\xee\xb2\xa2\xee\xb2\xa3\xee\xb2\xa4\xee\xb2\xa5\xee\xb2\xa6\xee\xb2\xa7\xee\xb2\xa8\xee\xb2\xa9\xee\xb2\xaa\xee\xb2\xab\xee\xb2\xac\xee\xb2\xad\xee\xb2\xae\xee\xb2\xaf\xee\xb2\xb0\xee\xb2\xb1\xee\xb2\xb2\xee\xb2\xb3\xee\xb2\xb4" + "\xee\xb2\xb5\xee\xb2\xb6\xee\xb2\xb7\xee\xb2\xb8\xee\xb2\xb9\xee\xb2\xba\xee\xb2\xbb\xee\xb2\xbc\xee\xb2\xbd\xee\xb2\xbe\xee\xb2\xbf\xee\xb3\x80\xee\xb3\x81\xee\xb3\x82\xee\xb3\x83\xee\xb3\x84\xee\xb3\x85\xee\xb3\x86\xee\xb3\x87\xee\xb3\x88\xee\xb3\x89\xee\xb3\x8a\xee\xb3\x8b\xee\xb3\x90\xee\xb3\x93\xee\xb3\x94\xee\xb3\x95\xee\xb3\x97\xee\xb3\x98\xee\xb3\x99\xee\xb3\x9a\xee\xb3\x9b" + "\xee\xb3\x9c\xee\xb3\x9d\xee\xb3\x9e\xee\xb3\x9f\xee\xb3\xa0\xee\xb3\xa1\xee\xb3\xa2\xee\xb3\xa3\xee\xb3\xa4\xee\xb3\xa5\xee\xb3\xa6\xee\xb3\xa7\xee\xb3\xa8\xee\xb3\xa9\xee\xb3\xaa\xee\xb3\xab\xee\xb3\xac\xee\xb3\xad\xee\xb3\xae\xee\xb3\xaf\xee\xb3\xb0\xee\xb3\xb1\xee\xb3\xb2\xee\xb3\xb3\xee\xb3\xb4\xee\xb3\xb5\xee\xb3\xb6\xee\xb3\xb7\xee\xb3\xb8\xee\xb3\xb9\xee\xb3\xba\xee\xb3\xbb" + "\xee\xb3\xbc\xee\xb3\xbd\xee\xb3\xbe\xee\xb3\xbf\xee\xb4\x80\xee\xb4\x81\xee\xb4\x82\xee\xb4\x83\xee\xb4\x84\xee\xb4\x85\xee\xb4\x86\xee\xb4\x87\xee\xb4\x88\xee\xb4\x89\xee\xb4\x8a\xee\xb4\x8b\xee\xb4\x8c\xee\xb4\x8d\xee\xb4\x8e\xee\xb4\x8f\xee\xb4\x90\xee\xb4\x91\xee\xb4\x92\xee\xb4\x93\xee\xb4\x94\xee\xb4\x95\xee\xb4\x96\xee\xb4\x97\xee\xb4\x98\xee\xb4\x99\xee\xb4\x9a\xee\xb4\x9b" + "\xee\xb4\x9c\xee\xb4\x9d\xee\xb4\x9e\xee\xb4\x9f\xee\xb4\xa0\xee\xb4\xa1\xee\xb4\xa2\xee\xb4\xa3\xee\xb4\xa4\xee\xb4\xa5\xee\xb4\xa6\xee\xb4\xa7\xee\xb4\xa8\xee\xb4\xa9\xee\xb4\xaa\xee\xb4\xab\xee\xb4\xac\xee\xb4\xad\xee\xb4\xae\xee\xb4\xaf\xee\xb4\xb0\xee\xb4\xb2\xee\xb4\xb3\xee\xb4\xb4\xee\xb4\xb5\xee\xb4\xb6\xee\xb4\xb7\xee\xb4\xb8\xee\xb4\xb9\xee\xb4\xbc\xee\xb4\xbd\xee\xb4\xbe" + "\xee\xb5\x80\xee\xb5\x81\xee\xb5\x82\xee\xb5\x83\xee\xb5\x84\xee\xb5\x85\xee\xb5\x86\xee\xb5\x87\xee\xb5\x88\xee\xb5\x89\xee\xb5\x8a\xee\xb5\x8b\xee\xb5\x8c\xee\xb5\x8d\xee\xb5\x8e\xee\xb5\x8f\xee\xb5\x90\xee\xb5\x91\xee\xb5\x92\xee\xb5\x93\xee\xb5\x94\xee\xb5\x95\xee\xb5\x96\xee\xb5\x97\xee\xb5\x98\xee\xb5\x99\xee\xb5\x9a\xee\xb5\x9b\xee\xb5\x9c\xee\xb5\x9d\xee\xb5\x9e\xee\xb5\x9f" + "\xee\xb5\xa0\xee\xb5\xa1\xee\xb5\xa2\xee\xb5\xa3\xee\xb5\xa4\xee\xb5\xa5\xee\xb5\xa6\xee\xb5\xa7\xee\xb5\xa8\xee\xb5\xa9\xee\xb5\xaa\xee\xb5\xab\xee\xb5\xac\xee\xb5\xad\xee\xb5\xae\xee\xb5\xaf\xee\xb5\xb0\xee\xb5\xb1\xee\xb5\xb2\xee\xb5\xb3\xee\xb5\xb4\xee\xb5\xb5\xee\xb5\xb6\xee\xb5\xb7\xee\xb5\xb8\xee\xb5\xb9\xee\xb5\xba\xee\xb5\xbb\xee\xb5\xbc\xee\xb5\xbd\xee\xb5\xbe\xee\xb5\xbf" + "\xee\xb6\x80\xee\xb6\x81\xee\xb6\x82\xee\xb6\x84\xee\xb6\x85\xee\xb6\x86\xee\xb6\x87\xee\xb6\x88\xee\xb6\x89\xee\xb6\x8a\xee\xb6\x8c\xee\xb6\x8d\xee\xb6\x8e\xee\xb6\x8f\xee\xb6\x90\xee\xb6\x91\xee\xb6\x92\xee\xb6\x93\xee\xb6\x94\xee\xb6\x95\xee\xb6\x96\xee\xb6\x97\xee\xb6\x98\xee\xb6\x9a\xee\xb6\x9b\xee\xb6\x9c\xee\xb6\x9d\xee\xb6\x9e\xee\xb6\x9f\xee\xb6\xa0\xee\xb6\xa1\xee\xb6\xa2" + "\xee\xb6\xa3\xee\xb6\xa4\xee\xb6\xa6\xee\xb6\xa7\xee\xb6\xa8\xee\xb6\xa9\xee\xb6\xaa\xee\xb6\xab\xee\xb6\xac\xee\xb6\xad\xee\xb6\xae\xee\xb6\xaf\xee\xb6\xb0\xee\xb6\xb1\xee\xb6\xb2\xee\xb6\xb3\xee\xb6\xb4\xee\xb6\xb5\xee\xb6\xb6\xee\xb6\xb7\xee\xb6\xb8\xee\xb6\xb9\xee\xb6\xba\xee\xb6\xbb\xee\xb6\xbc\xee\xb6\xbd\xee\xb6\xbe\xee\xb6\xbf\xee\xb7\x80\xee\xb7\x81\xee\xb7\x82\xee\xb7\x83" + "\xee\xb7\x84\xee\xb7\x85\xee\xb7\x86\xee\xb7\x87\xee\xb7\x88\xee\xb7\x89\xee\xb7\x8a\xee\xb7\x8b\xee\xb7\x8c\xee\xb7\x8d\xee\xb7\x8e\xee\xb7\x8f\xee\xb7\x90\xee\xb7\x91\xee\xb7\x92\xee\xb7\x93\xee\xb7\x94\xee\xb7\x95\xee\xb7\x96\xee\xb7\x97\xee\xb7\x98\xee\xb7\x99\xee\xb7\x9a\xee\xb7\x9b\xee\xb7\x9c\xee\xb7\x9d\xee\xb7\x9e\xee\xb7\x9f\xee\xb7\xa0\xee\xb7\xa1\xee\xb7\xa2\xee\xb7\xa3" + "\xee\xb7\xa4\xee\xb7\xa5\xee\xb7\xa6\xee\xb7\xa7\xee\xb7\xa8\xee\xb7\xa9\xee\xb7\xaa\xee\xb7\xab\xee\xb7\xac\xee\xb7\xad\xee\xb7\xae\xee\xb7\xaf\xee\xb7\xb0\xee\xb7\xb1\xee\xb7\xb2\xee\xb7\xb3\xee\xb7\xb4\xee\xb7\xb5\xee\xb7\xb6\xee\xb7\xb7\xee\xb7\xb8\xee\xb7\xb9\xee\xb7\xba\xee\xb7\xbb\xee\xb7\xbc\xee\xb7\xbd\xee\xb7\xbe\xee\xb7\xbf\xee\xb8\x80\xee\xb8\x81\xee\xb8\x82\xee\xb8\x83" + "\xee\xb8\x84\xee\xb8\x85\xee\xb8\x86\xee\xb8\x87\xee\xb8\x88\xee\xb8\x89\xee\xb8\x8a\xee\xb8\x8b\xee\xb8\x8c\xee\xb8\x8d\xee\xb8\x8e\xee\xb8\x8f\xee\xb8\x90\xee\xb8\x91\xee\xb8\x92\xee\xb8\x93\xee\xb8\x94\xee\xb8\x95\xee\xb8\x96\xee\xb8\x97\xee\xb8\x98\xee\xb8\x99\xee\xb8\x9a\xee\xb8\x9b\xee\xb8\x9c\xee\xb8\x9d\xee\xb8\x9e\xee\xb8\x9f\xee\xb8\xa0\xee\xb8\xa1\xee\xb8\xa2\xee\xb8\xa3" + "\xee\xb8\xa4\xee\xb8\xa5\xee\xb8\xa6\xee\xb8\xa7\xee\xb8\xa8\xee\xb8\xa9\xee\xb8\xaa\xee\xb8\xab\xee\xb8\xac\xee\xb8\xad\xee\xb8\xae\xee\xb8\xaf\xee\xb8\xb0\xee\xb8\xb1\xee\xb8\xb2\xee\xb8\xb3\xee\xb8\xb4\xee\xb8\xb5\xee\xb8\xb6\xee\xb8\xb7\xee\xb8\xb8\xee\xb8\xb9\xee\xb8\xba\xee\xb8\xbb\xee\xb8\xbc\xee\xb8\xbd\xee\xb8\xbe\xee\xb8\xbf\xee\xb9\x80\xee\xb9\x81\xee\xb9\x82\xee\xb9\x83" + "\xee\xb9\x84\xee\xb9\x85\xee\xb9\x86\xee\xb9\x87\xee\xb9\x88\xee\xb9\x89\xee\xb9\x8a\xee\xb9\x8b\xee\xb9\x8c\xee\xb9\x8d\xee\xb9\x8e\xee\xb9\x8f\xee\xb9\x90\xee\xb9\x91\xee\xb9\x93\xee\xb9\x94\xee\xb9\x95\xee\xb9\x96\xee\xb9\x97\xee\xb9\x98\xee\xb9\x99\xee\xb9\x9a\xee\xb9\x9b\xee\xb9\x9c\xee\xb9\x9d\xee\xb9\x9e\xee\xb9\x9f\xee\xb9\xa0\xee\xb9\xa1\xee\xb9\xa2\xee\xb9\xa3\xee\xb9\xa4" + "\xee\xb9\xa5\xee\xb9\xa6\xee\xb9\xa7\xee\xb9\xa8\xee\xb9\xa9\xee\xb9\xaa\xee\xb9\xab\xee\xb9\xac\xee\xb9\xad\xee\xb9\xae\xee\xb9\xaf\xee\xb9\xb0\xee\xb9\xb1\xee\xb9\xb2\xee\xb9\xb3\xee\xb9\xb4\xee\xb9\xb5\xee\xb9\xb6\xee\xb9\xb7\xee\xb9\xb8\xee\xb9\xb9\xee\xb9\xba\xee\xb9\xbb\xee\xb9\xbc\xee\xb9\xbd\xee\xb9\xbe\xee\xba\x81\xee\xba\x82\xee\xba\x83\xee\xba\x84\xee\xba\x85\xee\xba\x86" + "\xee\xba\x87\xee\xba\x88\xee\xba\x89\xee\xba\x8a\xee\xba\x8b\xee\xba\x8c\xee\xba\x8d\xee\xba\x8e\xee\xba\x8f\xee\xba\x90\xee\xba\x91\xee\xba\x92\xee\xba\x93\xee\xba\x94\xee\xba\x95\xee\xba\x96\xee\xba\x97\xee\xba\x98\xee\xba\x99\xee\xba\x9a\xee\xba\x9b\xee\xba\x9c\xee\xba\x9d\xee\xba\x9e\xee\xba\x9f\xee\xba\xa0\xee\xba\xa1\xee\xba\xa2\xee\xba\xa3\xee\xba\xa4\xee\xba\xa5\xee\xba\xa6" + "\xee\xba\xa7\xee\xba\xa8\xee\xba\xa9\xee\xba\xaa\xee\xba\xab\xee\xba\xac\xee\xba\xad\xee\xba\xae\xee\xba\xaf\xee\xba\xb0\xee\xba\xb1\xee\xba\xb2\xee\xba\xb3\xee\xba\xb4\xee\xba\xb5\xee\xba\xb6\xee\xba\xb7\xee\xba\xb8\xee\xba\xb9\xee\xba\xba\xee\xba\xbb\xee\xba\xbc\xee\xba\xbd\xee\xba\xbe\xee\xba\xbf\xee\xbb\x80\xee\xbb\x81\xee\xbb\x82\xee\xbb\x83\xee\xbb\x84\xee\xbb\x85\xee\xbb\x86" + "\xee\xbb\x87\xee\xbb\x88\xee\xbb\x89\xee\xbb\x8a\xee\xbb\x8b\xee\xbb\x8c\xee\xbb\x8d\xee\xbb\x8e\xee\xbb\x8f\xee\xbb\x90\xee\xbb\x91\xee\xbb\x92\xee\xbb\x93\xee\xbb\x94\xee\xbb\x95\xee\xbb\x96\xee\xbb\x97\xee\xbb\x98\xee\xbb\x99\xee\xbb\x9a\xee\xbb\x9c\xee\xbb\x9f\xee\xbb\xa0\xee\xbb\xa1\xee\xbb\xa2\xee\xbb\xa3\xee\xbb\xa4\xee\xbb\xa5\xee\xbb\xa6\xee\xbb\xa7\xee\xbb\xa8\xee\xbb\xa9" + "\xee\xbb\xaa\xee\xbb\xab\xee\xbb\xac\xee\xbb\xad\xee\xbb\xae\xee\xbb\xaf\xee\xbb\xb0\xee\xbb\xb1\xee\xbb\xb2\xee\xbb\xb3\xee\xbb\xb4\xee\xbb\xb5\xee\xbb\xb6\xee\xbb\xb7\xee\xbb\xb8\xee\xbb\xb9\xee\xbb\xba\xee\xbb\xbb\xee\xbb\xbc\xee\xbb\xbd\xee\xbb\xbe\xee\xbb\xbf\xee\xbc\x80\xee\xbc\x81\xee\xbc\x82\xee\xbc\x83\xee\xbc\x84\xee\xbc\x85\xee\xbc\x86\xee\xbc\x87\xee\xbc\x88\xee\xbc\x89" + "\xee\xbc\x8a\xee\xbc\x8b\xee\xbc\x8c\xee\xbc\x8d\xee\xbc\x8e\xee\xbc\x90\xee\xbc\x91\xee\xbc\x92\xee\xbc\x93\xee\xbc\x94\xee\xbc\x95\xee\xbc\x96\xee\xbc\x97\xee\xbc\x98\xee\xbc\x99\xee\xbc\x9a\xee\xbc\x9b\xee\xbc\x9c\xee\xbc\x9d\xee\xbc\x9e\xee\xbc\x9f\xee\xbc\xa0\xee\xbc\xa1\xee\xbc\xa2\xee\xbc\xa3\xee\xbc\xa4\xee\xbc\xa5\xee\xbc\xa6\xee\xbc\xa7\xee\xbc\xa8\xee\xbc\xa9\xee\xbc\xaa" + "\xee\xbc\xab\xee\xbc\xac\xee\xbc\xad\xee\xbc\xae\xee\xbc\xaf\xee\xbc\xb0\xee\xbc\xb1\xee\xbc\xb2\xee\xbc\xb3\xee\xbc\xb4\xee\xbc\xb5\xee\xbc\xb6\xee\xbc\xb7\xee\xbc\xb8\xee\xbc\xb9\xee\xbc\xba\xee\xbc\xbb\xee\xbc\xbc\xee\xbc\xbd\xee\xbc\xbe\xee\xbc\xbf\xee\xbd\x80\xee\xbd\x81\xee\xbd\x82\xee\xbd\x83\xee\xbd\x84\xee\xbd\x85\xee\xbd\x86\xee\xbd\x87\xee\xbd\x88\xee\xbd\x89\xee\xbd\x8b" + "\xee\xbd\x8c\xee\xbd\x8d\xee\xbd\x8e\xee\xbd\x8f\xee\xbd\x90\xee\xbd\x91\xee\xbd\x92\xee\xbd\x93\xee\xbd\x94\xee\xbd\x95\xee\xbd\x96\xee\xbd\x97\xee\xbd\x98\xee\xbd\x99\xee\xbd\x9a\xee\xbd\x9b\xee\xbd\x9c\xee\xbd\x9d\xee\xbd\x9e\xee\xbd\x9f\xee\xbd\xa0\xee\xbd\xa1\xee\xbd\xa2\xee\xbd\xa3\xee\xbd\xa4\xee\xbd\xa5\xee\xbd\xa6\xee\xbd\xa7\xee\xbd\xa8\xee\xbd\xa9\xee\xbd\xaa\xee\xbd\xab" + "\xee\xbd\xac\xee\xbd\xad\xee\xbd\xae\xee\xbd\xaf\xee\xbd\xb0\xee\xbd\xb1\xee\xbd\xb2\xee\xbd\xb3\xee\xbd\xb4\xee\xbd\xb5\xee\xbd\xb6\xee\xbd\xb7\xee\xbd\xb8\xee\xbd\xb9\xee\xbd\xba\xee\xbd\xbb\xee\xbd\xbc\xee\xbd\xbd\xee\xbd\xbe\xee\xbd\xbf\xee\xbe\x80\xee\xbe\x81\xee\xbe\x82\xee\xbe\x83\xee\xbe\x84\xee\xbe\x85\xee\xbe\x86\xee\xbe\x87\xee\xbe\x88\xee\xbe\x89\xee\xbe\x8a\xee\xbe\x8b" + "\xee\xbe\x8c\xee\xbe\x8d\xee\xbe\x8e\xee\xbe\x8f\xee\xbe\x90\xee\xbe\x91\xee\xbe\x92\xee\xbe\x93\xee\xbe\x94\xee\xbe\x95\xee\xbe\x96\xee\xbe\x97\xee\xbe\x98\xee\xbe\x99\xee\xbe\x9a\xee\xbe\x9b\xee\xbe\x9c\xee\xbe\x9d\xee\xbe\x9e\xee\xbe\x9f\xee\xbe\xa0\xee\xbe\xa1\xee\xbe\xa2\xee\xbe\xa3\xee\xbe\xa4\xee\xbe\xa5\xee\xbe\xa6\xee\xbe\xa7\xee\xbe\xa8\xee\xbe\xa9\xee\xbe\xaa\xee\xbe\xab" + "\xee\xbe\xac\xee\xbe\xad\xee\xbe\xae\xee\xbe\xaf\xee\xbe\xb0\xee\xbe\xb1\xee\xbe\xb2\xee\xbe\xb3\xee\xbe\xb4\xee\xbe\xb5\xee\xbe\xb6\xee\xbe\xb7\xee\xbe\xb8\xee\xbe\xb9\xee\xbe\xba\xee\xbe\xbb\xee\xbe\xbc\xee\xbe\xbd\xee\xbe\xbe\xee\xbe\xbf\xee\xbf\x80\xee\xbf\x81\xee\xbf\x82\xee\xbf\x83\xee\xbf\x84\xee\xbf\x85\xee\xbf\x86\xee\xbf\x87\xee\xbf\x88\xee\xbf\x89\xee\xbf\x8a\xee\xbf\x8b" + "\xee\xbf\x8c\xee\xbf\x8d\xee\xbf\x8f\xee\xbf\x90\xee\xbf\x91\xee\xbf\x92\xee\xbf\x93\xee\xbf\x94\xee\xbf\x95\xee\xbf\x96\xee\xbf\x97\xee\xbf\x98\xee\xbf\x99\xee\xbf\x9a\xee\xbf\x9b\xee\xbf\x9c\xee\xbf\x9d\xee\xbf\x9e\xee\xbf\x9f\xee\xbf\xa0\xee\xbf\xa1\xee\xbf\xa2\xee\xbf\xa3\xee\xbf\xa4\xee\xbf\xa5\xee\xbf\xa6\xee\xbf\xa7\xee\xbf\xa8\xee\xbf\xa9\xee\xbf\xaa\xee\xbf\xab\xee\xbf\xac" + "\xee\xbf\xad\xee\xbf\xae\xee\xbf\xaf\xee\xbf\xb0\xee\xbf\xb1\xee\xbf\xb2\xee\xbf\xb3\xee\xbf\xb4\xee\xbf\xb5\xee\xbf\xb6\xee\xbf\xb7\xee\xbf\xb8\xee\xbf\xb9\xee\xbf\xba\xee\xbf\xbb\xee\xbf\xbc\xee\xbf\xbd\xee\xbf\xbe\xee\xbf\xbf\xef\x80\x80\xef\x80\x81\xef\x80\x82\xef\x80\x83\xef\x80\x84\xef\x80\x85\xef\x80\x86\xef\x80\x87\xef\x80\x88\xef\x80\x89\xef\x80\x8a\xef\x80\x8b\xef\x80\x8c" + "\xef\x80\x8d\xef\x80\x8e\xef\x80\x8f\xef\x80\x90\xef\x80\x91\xef\x80\x92\xef\x80\x93\xef\x80\x94\xef\x80\x95\xef\x80\x96\xef\x80\x97\xef\x80\x98\xef\x80\x99\xef\x80\x9a\xef\x80\x9b\xef\x80\x9c\xef\x80\x9d\xef\x80\x9e\xef\x80\x9f\xef\x80\xa0\xef\x80\xa1\xef\x80\xa2\xef\x80\xa3\xef\x80\xa4\xef\x80\xa5\xef\x80\xa6\xef\x80\xa7\xef\x80\xa8\xef\x80\xa9\xef\x80\xaa\xef\x80\xab\xef\x80\xac" + "\xef\x80\xad\xef\x80\xae\xef\x80\xaf\xef\x80\xb0\xef\x80\xb1\xef\x80\xb2\xef\x80\xb3\xef\x80\xb4\xef\x80\xb5\xef\x80\xb6\xef\x80\xb7\xef\x80\xb8\xef\x80\xb9\xef\x80\xba\xef\x80\xbb\xef\x80\xbc\xef\x80\xbd\xef\x80\xbe\xef\x80\xbf\xef\x81\x80\xef\x81\x81\xef\x81\x82\xef\x81\x83\xef\x81\x84\xef\x81\x85\xef\x81\x86\xef\x81\x87\xef\x81\x88\xef\x81\x89\xef\x81\x8a\xef\x81\x8b\xef\x81\x8c" + "\xef\x81\x8d\xef\x81\x8e\xef\x81\x8f\xef\x81\x90\xef\x81\x91\xef\x81\x92\xef\x81\x93\xef\x81\x94\xef\x81\x95\xef\x81\x96\xef\x81\x97\xef\x81\x98\xef\x81\x99\xef\x81\x9a\xef\x81\x9b\xef\x81\x9c\xef\x81\x9d\xef\x81\x9e\xef\x81\x9f\xef\x81\xa0\xef\x81\xa1\xef\x81\xa2\xef\x81\xa3\xef\x81\xa4\xef\x81\xa5\xef\x81\xa7\xef\x81\xa8\xef\x81\xa9\xef\x81\xaa\xef\x81\xab\xef\x81\xac\xef\x81\xad" + "\xef\x81\xae\xef\x81\xb0\xef\x81\xb1\xef\x81\xb2\xef\x81\xb3\xef\x81\xb4\xef\x81\xb5\xef\x81\xb6\xef\x81\xb7\xef\x81\xb8\xef\x81\xb9\xef\x81\xba\xef\x81\xbb\xef\x81\xbc\xef\x81\xbd\xef\x81\xbe\xef\x81\xbf\xef\x82\x80\xef\x82\x81\xef\x82\x82\xef\x82\x83\xef\x82\x84\xef\x82\x85\xef\x82\x86\xef\x82\x87\xef\x82\x88\xef\x82\x89\xef\x82\x8a\xef\x82\x8b\xef\x82\x8c\xef\x82\x8d\xef\x82\x8e" + "\xef\x82\x8f\xef\x82\x90\xef\x82\x91\xef\x82\x92\xef\x82\x93\xef\x82\x94\xef\x82\x95\xef\x82\x96\xef\x82\x97\xef\x82\x98\xef\x82\x99\xef\x82\x9a\xef\x82\x9b\xef\x82\x9c\xef\x82\x9d\xef\x82\x9e\xef\x82\x9f\xef\x82\xa0\xef\x82\xa1\xef\x82\xa2\xef\x82\xa3\xef\x82\xa4\xef\x82\xa5\xef\x82\xa6\xef\x82\xa7\xef\x82\xa8\xef\x82\xa9\xef\x82\xaa\xef\x82\xab\xef\x82\xac\xef\x82\xad\xef\x82\xae" + "\xef\x82\xaf\xef\x82\xb0\xef\x82\xb1\xef\x82\xb2\xef\x82\xb3\xef\x82\xb4\xef\x82\xb5\xef\x82\xb6\xef\x82\xb7\xef\x82\xb8\xef\x82\xb9\xef\x82\xba\xef\x82\xbb\xef\x82\xbc\xef\x82\xbd\xef\x82\xbe\xef\x82\xbf\xef\x83\x80\xef\x83\x81\xef\x83\x82\xef\x83\x83\xef\x83\x84\xef\x83\x85\xef\x83\x86\xef\x83\x87\xef\x83\x88\xef\x83\x89\xef\x83\x8a\xef\x83\x8b\xef\x83\x8c\xef\x83\x8d\xef\x83\x8e" + "\xef\x83\x8f\xef\x83\x90\xef\x83\x91\xef\x83\x92\xef\x83\x93\xef\x83\x94\xef\x83\x95\xef\x83\x96\xef\x83\x97\xef\x83\x98\xef\x83\x99\xef\x83\x9a\xef\x83\x9b\xef\x83\x9c\xef\x83\x9d\xef\x83\x9e\xef\x83\x9f\xef\x83\xa0\xef\x83\xa1\xef\x83\xa2\xef\x83\xa3\xef\x83\xa4\xef\x83\xa5\xef\x83\xa6\xef\x83\xa7\xef\x83\xa8\xef\x83\xa9\xef\x83\xaa\xef\x83\xab\xef\x83\xac\xef\x83\xad\xef\x83\xae" + "\xef\x83\xaf\xef\x83\xb0\xef\x83\xb1\xef\x83\xb2\xef\x83\xb3\xef\x83\xb4\xef\x83\xb5\xef\x83\xb6\xef\x83\xb7\xef\x83\xb8\xef\x83\xb9\xef\x83\xba\xef\x83\xbb\xef\x83\xbc\xef\x83\xbd\xef\x83\xbe\xef\x83\xbf\xef\x84\x80\xef\x84\x81\xef\x84\x82\xef\x84\x83\xef\x84\x84\xef\x84\x85\xef\x84\x86\xef\x84\x87\xef\x84\x88\xef\x84\x89\xef\x84\x8a\xef\x84\x8b\xef\x84\x8c\xef\x84\x8d\xef\x84\x8e" + "\xef\x84\x8f\xef\x84\x90\xef\x84\x91\xef\x84\x92\xef\x84\x93\xef\x84\x94\xef\x84\x95\xef\x84\x96\xef\x84\x97\xef\x84\x98\xef\x84\x99\xef\x84\x9a\xef\x84\x9b\xef\x84\x9c\xef\x84\x9d\xef\x84\x9e\xef\x84\x9f\xef\x84\xa0\xef\x84\xa1\xef\x84\xa2\xef\x84\xa3\xef\x84\xa4\xef\x84\xa5\xef\x84\xa6\xef\x84\xa7\xef\x84\xa8\xef\x84\xa9\xef\x84\xaa\xef\x84\xab\xef\x84\xac\xef\x84\xad\xef\x84\xae" + "\xef\x84\xaf\xef\x84\xb0\xef\x84\xb1\xef\x84\xb2\xef\x84\xb3\xef\x84\xb4\xef\x84\xb5\xef\x84\xb6\xef\x84\xb7\xef\x84\xb8\xef\x84\xb9\xef\x84\xba\xef\x84\xbc\xef\x84\xbd\xef\x84\xbe\xef\x84\xbf\xef\x85\x80\xef\x85\x81\xef\x85\x82\xef\x85\x83\xef\x85\x84\xef\x85\x85\xef\x85\x86\xef\x85\x87\xef\x85\x88\xef\x85\x89\xef\x85\x8a\xef\x85\x8b\xef\x85\x8c\xef\x85\x8d\xef\x85\x8e\xef\x85\x8f" + "\xef\x85\x90\xef\x85\x91\xef\x85\x93\xef\x85\x94\xef\x85\x95\xef\x85\x96\xef\x85\x97\xef\x85\x98\xef\x85\x99\xef\x85\x9a\xef\x85\x9b\xef\x85\x9c\xef\x85\x9d\xef\x85\x9e\xef\x85\x9f\xef\x85\xa0\xef\x85\xa1\xef\x85\xa2\xef\x85\xa3\xef\x85\xa4\xef\x85\xa5\xef\x85\xa6\xef\x85\xa7\xef\x85\xa8\xef\x85\xa9\xef\x85\xaa\xef\x85\xab\xef\x85\xac\xef\x85\xad\xef\x85\xae\xef\x85\xaf\xef\x85\xb0" + "\xef\x85\xb1\xef\x85\xb2\xef\x85\xb3\xef\x85\xb4\xef\x85\xb5\xef\x85\xb6\xef\x85\xb7\xef\x85\xb8\xef\x85\xb9\xef\x85\xba\xef\x85\xbb\xef\x85\xbc\xef\x85\xbd\xef\x85\xbe\xef\x85\xbf\xef\x86\x80\xef\x86\x81\xef\x86\x82\xef\x86\x83\xef\x86\x84\xef\x86\x85\xef\x86\x86\xef\x86\x87\xef\x86\x88\xef\x86\x89\xef\x86\x8a\xef\x86\x8b\xef\x86\x8c\xef\x86\x8d\xef\x86\x8e\xef\x86\x8f\xef\x86\x90" + "\xef\x86\x91\xef\x86\x92\xef\x86\x93\xef\x86\x94\xef\x86\x95\xef\x86\x96\xef\x86\x97\xef\x86\x98\xef\x86\x99\xef\x86\x9a\xef\x86\x9b\xef\x86\x9c\xef\x86\x9d\xef\x86\x9e\xef\x86\x9f\xef\x86\xa0\xef\x86\xa1\xef\x86\xa2\xef\x86\xa3\xef\x86\xa4\xef\x86\xa5\xef\x86\xa6\xef\x86\xa7\xef\x86\xa8\xef\x86\xa9\xef\x86\xaa\xef\x86\xab\xef\x86\xad\xef\x86\xae\xef\x86\xaf\xef\x86\xb0\xef\x86\xb1" + "\xef\x86\xb2\xef\x86\xb3\xef\x86\xb4\xef\x86\xb5\xef\x86\xb6\xef\x86\xb7\xef\x86\xb8\xef\x86\xb9\xef\x86\xba\xef\x86\xbb\xef\x86\xbc\xef\x86\xbd\xef\x86\xbe\xef\x86\xbf\xef\x87\x80\xef\x87\x81\xef\x87\x82\xef\x87\x83\xef\x87\x84\xef\x87\x85\xef\x87\x86\xef\x87\x87\xef\x87\x88\xef\x87\x89\xef\x87\x8a\xef\x87\x8b\xef\x87\x8c\xef\x87\x8d\xef\x87\x8e\xef\x87\x8f\xef\x87\x90\xef\x87\x91" + "\xef\x87\x92\xef\x87\x93\xef\x87\x94\xef\x87\x96\xef\x87\x97\xef\x87\x98\xef\x87\x99\xef\x87\x9a\xef\x87\x9b\xef\x87\x9c\xef\x87\x9d\xef\x87\x9e\xef\x87\x9f\xef\x87\xa0\xef\x87\xa1\xef\x87\xa2\xef\x87\xa3\xef\x87\xa4\xef\x87\xa5\xef\x87\xa6\xef\x87\xa7\xef\x87\xa8\xef\x87\xa9\xef\x87\xaa\xef\x87\xab\xef\x87\xac\xef\x87\xad\xef\x87\xae\xef\x87\xaf\xef\x87\xb0\xef\x87\xb1\xef\x87\xb2" + "\xef\x87\xb3\xef\x87\xb4\xef\x87\xb5\xef\x87\xb6\xef\x87\xb7\xef\x87\xb8\xef\x87\xb9\xef\x87\xba\xef\x87\xbb\xef\x87\xbc\xef\x87\xbd\xef\x87\xbe\xef\x87\xbf\xef\x88\x80\xef\x88\x81\xef\x88\x82\xef\x88\x83\xef\x88\x84\xef\x88\x85\xef\x88\x86\xef\x88\x87\xef\x88\x88\xef\x88\x89\xef\x88\x8a\xef\x88\x8b\xef\x88\x8c\xef\x88\x8d\xef\x88\x8e\xef\x88\x8f\xef\x88\x90\xef\x88\x91\xef\x88\x92" + "\xef\x88\x93\xef\x88\x94\xef\x88\x95\xef\x88\x96\xef\x88\x97\xef\x88\x98\xef\x88\x99\xef\x88\x9a\xef\x88\x9b\xef\x88\x9c\xef\x88\x9d\xef\x88\x9e\xef\x88\x9f\xef\x88\xa0\xef\x88\xa1\xef\x88\xa2\xef\x88\xa3\xef\x88\xa4\xef\x88\xa5\xef\x88\xa6\xef\x88\xa7\xef\x88\xa8\xef\x88\xa9\xef\x88\xaa\xef\x88\xab\xef\x88\xac\xef\x88\xad\xef\x88\xae\xef\x88\xaf\xef\x88\xb0\xef\x88\xb1\xef\x88\xb2" + "\xef\x88\xb3\xef\x88\xb4\xef\x88\xb5\xef\x88\xb6\xef\x88\xb7\xef\x88\xb8\xef\x88\xb9\xef\x88\xba\xef\x88\xbb\xef\x88\xbc\xef\x88\xbd\xef\x88\xbe\xef\x89\x80\xef\x89\x81\xef\x89\x82\xef\x89\x83\xef\x89\x84\xef\x89\x85\xef\x89\x86\xef\x89\x87\xef\x89\x88\xef\x89\x89\xef\x89\x8a\xef\x89\x8b\xef\x89\x8c\xef\x89\x8d\xef\x89\x8e\xef\x89\x8f\xef\x89\x90\xef\x89\x91\xef\x89\x92\xef\x89\x93" + "\xef\x89\x94\xef\x89\x95\xef\x89\x96\xef\x89\x97\xef\x89\x98\xef\x89\x99\xef\x89\x9a\xef\x89\x9b\xef\x89\x9c\xef\x89\x9d\xef\x89\x9e\xef\x89\x9f\xef\x89\xa0\xef\x89\xa1\xef\x89\xa2\xef\x89\xa3\xef\x89\xa4\xef\x89\xa5\xef\x89\xa6\xef\x89\xa7\xef\x89\xa8\xef\x89\xa9\xef\x89\xaa\xef\x89\xab\xef\x89\xac\xef\x89\xad\xef\x89\xae\xef\x89\xaf\xef\x89\xb0\xef\x89\xb1\xef\x89\xb2\xef\x89\xb3" + "\xef\x89\xb4\xef\x89\xb5\xef\x89\xb6\xef\x89\xb7\xef\x89\xb8\xef\x89\xb9\xef\x89\xba\xef\x89\xbb\xef\x89\xbc\xef\x89\xbd\xef\x89\xbe\xef\x89\xbf\xef\x8a\x80\xef\x8a\x81\xef\x8a\x82\xef\x8a\x83\xef\x8a\x84\xef\x8a\x85\xef\x8a\x86\xef\x8a\x87\xef\x8a\x88\xef\x8a\x89\xef\x8a\x8a\xef\x8a\x8b\xef\x8a\x8c\xef\x8a\x8d\xef\x8a\x8e\xef\x8a\x8f\xef\x8a\x90\xef\x8a\x91\xef\x8a\x92\xef\x8a\x93" + "\xef\x8a\x94\xef\x8a\x95\xef\x8a\x96\xef\x8a\x97\xef\x8a\x98\xef\x8a\x99\xef\x8a\x9a\xef\x8a\x9b\xef\x8a\x9c\xef\x8a\x9d\xef\x8a\x9e\xef\x8a\x9f\xef\x8a\xa0\xef\x8a\xa1\xef\x8a\xa2\xef\x8a\xa3\xef\x8a\xa4\xef\x8a\xa5\xef\x8a\xa6\xef\x8a\xa7\xef\x8a\xa8\xef\x8a\xa9\xef\x8a\xaa\xef\x8a\xab\xef\x8a\xad\xef\x8a\xae\xef\x8a\xaf\xef\x8a\xb0\xef\x8a\xb1\xef\x8a\xb2\xef\x8a\xb3\xef\x8a\xb4" + "\xef\x8a\xb5\xef\x8a\xb6\xef\x8a\xb7\xef\x8a\xb8\xef\x8a\xb9\xef\x8a\xba\xef\x8a\xbb\xef\x8a\xbc\xef\x8a\xbd\xef\x8a\xbe\xef\x8a\xbf\xef\x8b\x80\xef\x8b\x81\xef\x8b\x82\xef\x8b\x83\xef\x8b\x84\xef\x8b\x85\xef\x8b\x86\xef\x8b\x87\xef\x8b\x88\xef\x8b\x89\xef\x8b\x8a\xef\x8b\x8b\xef\x8b\x8c\xef\x8b\x8d\xef\x8b\x8e\xef\x8b\x8f\xef\x8b\x90\xef\x8b\x91\xef\x8b\x92\xef\x8b\x93\xef\x8b\x94" + "\xef\x8b\x95\xef\x8b\x96\xef\x8b\x97\xef\x8b\x98\xef\x8b\x99\xef\x8b\x9a\xef\x8b\x9b\xef\x8b\x9c\xef\x8b\x9d\xef\x8b\x9e\xef\x8b\x9f\xef\x8b\xa0\xef\x8b\xa1\xef\x8b\xa2\xef\x8b\xa3\xef\x8b\xa4\xef\x8b\xa5\xef\x8b\xa6\xef\x8b\xa7\xef\x8b\xa8\xef\x8b\xa9\xef\x8b\xaa\xef\x8b\xab\xef\x8b\xac\xef\x8b\xad\xef\x8b\xae\xef\x8b\xaf\xef\x8b\xb0\xef\x8b\xb1\xef\x8b\xb2\xef\x8b\xb3\xef\x8b\xb4" + "\xef\x8b\xb5\xef\x8b\xb6\xef\x8b\xb7\xef\x8b\xb8\xef\x8b\xb9\xef\x8b\xba\xef\x8b\xbb\xef\x8b\xbc\xef\x8b\xbd\xef\x8b\xbe\xef\x8b\xbf\xef\x8c\x80\xef\x8c\x81\xef\x8c\x82\xef\x8c\x83\xef\x8c\x84\xef\x8c\x85\xef\x8c\x86\xef\x8c\x87\xef\x8c\x88\xef\x8c\x89\xef\x8c\x8a\xef\x8c\x8b\xef\x8c\x8c\xef\x8c\x8d\xef\x8c\x8e\xef\x8c\x8f\xef\x8c\x90\xef\x8c\x91\xef\x8c\x92\xef\x8c\x93\xef\x8c\x94" + "\xef\x8c\x95\xef\x8c\x96\xef\x8c\x97\xef\x8c\x98\xef\x8c\x99\xef\x8c\x9a\xef\x8c\x9b\xef\x8c\x9c\xef\x8c\x9d\xef\x8c\x9e\xef\x8c\x9f\xef\x8c\xa0\xef\x8c\xa1\xef\x8c\xa2\xef\x8c\xa3\xef\x8c\xa4\xef\x8c\xa5\xef\x8c\xa6\xef\x8c\xa7\xef\x8c\xa8\xef\x8c\xa9\xef\x8c\xaa\xef\x8c\xab\xef\x8c\xac\xef\x8c\xad\xef\x8c\xae\xef\x8c\xaf\xef\x8c\xb0\xef\x8c\xb1\xef\x8c\xb2\xef\x8c\xb3\xef\x8c\xb4" + "\xef\x8c\xb5\xef\x8c\xb6\xef\x8c\xb7\xef\x8c\xb8\xef\x8c\xb9\xef\x8c\xba\xef\x8c\xbb\xef\x8c\xbc\xef\x8c\xbd\xef\x8c\xbe\xef\x8c\xbf\xef\x8d\x80\xef\x8d\x81\xef\x8d\x82\xef\x8d\x83\xef\x8d\x84\xef\x8d\x85\xef\x8d\x86\xef\x8d\x87\xef\x8d\x88\xef\x8d\x89\xef\x8d\x8a\xef\x8d\x8b\xef\x8d\x8c\xef\x8d\x8d\xef\x8d\x8e\xef\x8d\x8f\xef\x8d\x90\xef\x8d\x91\xef\x8d\x92\xef\x8d\x93\xef\x8d\x94" + "\xef\x8d\x95\xef\x8d\x96\xef\x8d\x98\xef\x8d\x99\xef\x8d\x9a\xef\x8d\x9b\xef\x8d\x9c\xef\x8d\x9d\xef\x8d\x9e\xef\x8d\x9f\xef\x8d\xa0\xef\x8d\xa1\xef\x8d\xa2\xef\x8d\xa3\xef\x8d\xa4\xef\x8d\xa5\xef\x8d\xa6\xef\x8d\xa7\xef\x8d\xa8\xef\x8d\xa9\xef\x8d\xaa\xef\x8d\xab\xef\x8d\xac\xef\x8d\xad\xef\x8d\xae\xef\x8d\xaf\xef\x8d\xb0\xef\x8d\xb1\xef\x8d\xb2\xef\x8d\xb3\xef\x8d\xb4\xef\x8d\xb5" + "\xef\x8d\xb6\xef\x8d\xb7\xef\x8d\xb8\xef\x8d\xb9\xef\x8d\xba\xef\x8d\xbb\xef\x8d\xbc\xef\x8d\xbd\xef\x8d\xbe\xef\x8d\xbf\xef\x8e\x80\xef\x8e\x81\xef\x8e\x82\xef\x8e\x83\xef\x8e\x84\xef\x8e\x85\xef\x8e\x86\xef\x8e\x87\xef\x8e\x88\xef\x8e\x89\xef\x8e\x8a\xef\x8e\x8b\xef\x8e\x8c\xef\x8e\x8d\xef\x8e\x8e\xef\x8e\x8f\xef\x8e\x90\xef\x8e\x91\xef\x8e\x92\xef\x8e\x93\xef\x8e\x94\xef\x8e\x95" + "\xef\x8e\x96\xef\x8e\x97\xef\x8e\x98\xef\x8e\x99\xef\x8e\x9a\xef\x8e\x9b\xef\x8e\x9d\xef\x8e\x9e\xef\x8e\x9f\xef\x8e\xa0\xef\x8e\xa1\xef\x8e\xa2\xef\x8e\xa3\xef\x8e\xa4\xef\x8e\xa5\xef\x8e\xa6\xef\x8e\xa7\xef\x8e\xa8\xef\x8e\xa9\xef\x8e\xaa\xef\x8e\xab\xef\x8e\xac\xef\x8e\xad\xef\x8e\xae\xef\x8e\xaf\xef\x8e\xb0\xef\x8e\xb1\xef\x8e\xb2\xef\x8e\xb3\xef\x8e\xb4\xef\x8e\xb5\xef\x8e\xb6" + "\xef\x8e\xb7\xef\x8e\xb8\xef\x8e\xb9\xef\x8e\xba\xef\x8e\xbb\xef\x8e\xbc\xef\x8e\xbd\xef\x8e\xbe\xef\x8e\xbf\xef\x8f\x80\xef\x8f\x81\xef\x8f\x82\xef\x8f\x83\xef\x8f\x84\xef\x8f\x85\xef\x8f\x86\xef\x8f\x87\xef\x8f\x88\xef\x8f\x89\xef\x8f\x8a\xef\x8f\x8b\xef\x8f\x8c\xef\x8f\x8d\xef\x8f\x8e\xef\x8f\x8f\xef\x8f\x90\xef\x8f\x91\xef\x8f\x92\xef\x8f\x93\xef\x8f\x94\xef\x8f\x95\xef\x8f\x96" + "\xef\x8f\x97\xef\x8f\x98\xef\x8f\x99\xef\x8f\x9a\xef\x8f\x9b\xef\x8f\x9c\xef\x8f\x9d\xef\x8f\x9e\xef\x8f\x9f\xef\x8f\xa0\xef\x8f\xa1\xef\x8f\xa2\xef\x8f\xa3\xef\x8f\xa4\xef\x8f\xa5\xef\x8f\xa6\xef\x8f\xa7\xef\x8f\xa8\xef\x8f\xa9\xef\x8f\xaa\xef\x8f\xab\xef\x8f\xac\xef\x8f\xad\xef\x8f\xae\xef\x8f\xaf\xef\x8f\xb0\xef\x8f\xb1\xef\x8f\xb2\xef\x8f\xb3\xef\x8f\xb4\xef\x8f\xb5\xef\x8f\xb6" + "\xef\x8f\xb7\xef\x8f\xb8\xef\x8f\xb9\xef\x8f\xba\xef\x8f\xbb\xef\x8f\xbc\xef\x8f\xbd\xef\x8f\xbe\xef\x8f\xbf\xef\x90\x80\xef\x90\x81\xef\x90\x82\xef\x90\x83\xef\x90\x84\xef\x90\x85\xef\x90\x86\xef\x90\x87\xef\x90\x88\xef\x90\x89\xef\x90\x8a\xef\x90\x8b\xef\x90\x8c\xef\x90\x8d\xef\x90\x8e\xef\x90\x8f\xef\x90\x90\xef\x90\x91\xef\x90\x92\xef\x90\x93\xef\x90\x94\xef\x90\x95\xef\x90\x96" + "\xef\x90\x97\xef\x90\x98\xef\x90\x99\xef\x90\x9a\xef\x90\x9b\xef\x90\x9c\xef\x90\x9d\xef\x90\x9e\xef\x90\x9f\xef\x90\xa0\xef\x90\xa1\xef\x90\xa2\xef\x90\xa3\xef\x90\xa4\xef\x90\xa5\xef\x90\xa6\xef\x90\xa7\xef\x90\xa8\xef\x90\xa9\xef\x90\xaa\xef\x90\xab\xef\x90\xac\xef\x90\xad\xef\x90\xae\xef\x90\xaf\xef\x90\xb0\xef\x90\xb1\xef\x90\xb2\xef\x90\xb3\xef\x90\xb4\xef\x90\xb5\xef\x90\xb6" + "\xef\x90\xb7\xef\x90\xb8\xef\x90\xb9\xef\x90\xba\xef\x90\xbb\xef\x90\xbc\xef\x90\xbd\xef\x90\xbe\xef\x90\xbf\xef\x91\x80\xef\x91\x81\xef\x91\x82\xef\x91\x83\xef\x91\x84\xef\x91\x85\xef\x91\x86\xef\x91\x87\xef\x91\x88\xef\x91\x89\xef\x91\x8a\xef\x91\x8b\xef\x91\x8c\xef\x91\x8d\xef\x91\x8e\xef\x91\x8f\xef\x91\x90\xef\x91\x91\xef\x91\x92\xef\x91\x93\xef\x91\x94\xef\x91\x95\xef\x91\x96" + "\xef\x91\x97\xef\x91\x98\xef\x91\x99\xef\x91\x9a\xef\x91\x9b\xef\x91\x9c\xef\x91\x9d\xef\x91\x9e\xef\x91\x9f\xef\x91\xa0\xef\x91\xa1\xef\x91\xa2\xef\x91\xa3\xef\x91\xa4\xef\x91\xa5\xef\x91\xa6\xef\x91\xa7\xef\x91\xa8\xef\x91\xa9\xef\x91\xaa\xef\x91\xab\xef\x91\xac\xef\x91\xad\xef\x91\xae\xef\x91\xaf\xef\x91\xb0\xef\x91\xb1\xef\x91\xb2\xef\x91\xb3\xef\x91\xb4\xef\x91\xb5\xef\x91\xb6" + "\xef\x91\xb7\xef\x91\xb8\xef\x91\xb9\xef\x91\xba\xef\x91\xbb\xef\x91\xbc\xef\x91\xbd\xef\x91\xbe\xef\x91\xbf\xef\x92\x80\xef\x92\x81\xef\x92\x82\xef\x92\x83\xef\x92\x84\xef\x92\x85\xef\x92\x86\xef\x92\x87\xef\x92\x88\xef\x92\x89\xef\x92\x8a\xef\x92\x8b\xef\x92\x8c\xef\x92\x8d\xef\x92\x8e\xef\x92\x8f\xef\x92\x90\xef\x92\x91\xef\x92\x92\xef\x92\x93\xef\x92\x94\xef\x92\x95\xef\x92\x96" + "\xef\x92\x97\xef\x92\x98\xef\x92\x99\xef\x92\x9a\xef\x92\x9b\xef\x92\x9c\xef\x92\x9d\xef\x92\x9e\xef\x92\x9f\xef\x92\xa0\xef\x92\xa1\xef\x92\xa2\xef\x92\xa3\xef\x92\xa4\xef\x92\xa5\xef\x92\xa6\xef\x92\xa7\xef\x92\xa8\xef\x92\xa9\xef\x92\xaa\xef\x92\xab\xef\x92\xac\xef\x92\xad\xef\x92\xae\xef\x92\xaf\xef\x92\xb0\xef\x92\xb1\xef\x92\xb2\xef\x92\xb3\xef\x92\xb4\xef\x92\xb5\xef\x92\xb6" + "\xef\x92\xb7\xef\x92\xb8\xef\x92\xb9\xef\x92\xba\xef\x92\xbb\xef\x92\xbc\xef\x92\xbd\xef\x92\xbe\xef\x92\xbf\xef\x93\x80\xef\x93\x81\xef\x93\x82\xef\x93\x83\xef\x93\x85\xef\x93\x86\xef\x93\x87\xef\x93\x88\xef\x93\x89\xef\x93\x8a\xef\x93\x8b\xef\x93\x8c\xef\x93\x8d\xef\x93\x8e\xef\x93\x8f\xef\x93\x90\xef\x93\x91\xef\x93\x92\xef\x93\x93\xef\x93\x94\xef\x93\x95\xef\x93\x96\xef\x93\x97" + "\xef\x93\x98\xef\x93\x99\xef\x93\x9a\xef\x93\x9b\xef\x93\x9c\xef\x93\x9d\xef\x93\x9e\xef\x93\x9f\xef\x93\xa0\xef\x93\xa1\xef\x93\xa2\xef\x93\xa3\xef\x93\xa4\xef\x93\xa5\xef\x93\xa6\xef\x93\xa7\xef\x93\xa8\xef\x93\xa9\xef\x93\xaa\xef\x93\xab\xef\x93\xac\xef\x93\xad\xef\x93\xae\xef\x93\xaf\xef\x93\xb0\xef\x93\xb1\xef\x93\xb2\xef\x93\xb3\xef\x93\xb4\xef\x93\xb5\xef\x93\xb6\xef\x93\xb7" + "\xef\x93\xb8\xef\x93\xb9\xef\x93\xba\xef\x93\xbb\xef\x93\xbc\xef\x93\xbd\xef\x93\xbe\xef\x93\xbf\xef\x94\x80\xef\x94\x81\xef\x94\x82\xef\x94\x83\xef\x94\x84\xef\x94\x85\xef\x94\x86\xef\x94\x87\xef\x94\x88\xef\x94\x89\xef\x94\x8a\xef\x94\x8b\xef\x94\x8c\xef\x94\x8d\xef\x94\x8e\xef\x94\x8f\xef\x94\x90\xef\x94\x91\xef\x94\x92\xef\x94\x93\xef\x94\x94\xef\x94\x95\xef\x94\x96\xef\x94\x97" + "\xef\x94\x98\xef\x94\x99\xef\x94\x9a\xef\x94\x9b\xef\x94\x9c\xef\x94\x9d\xef\x94\x9e\xef\x94\x9f\xef\x94\xa0\xef\x94\xa1\xef\x94\xa2\xef\x94\xa3\xef\x94\xa4\xef\x94\xa5\xef\x94\xa6\xef\x94\xa7\xef\x94\xa8\xef\x94\xa9\xef\x94\xaa\xef\x94\xab\xef\x94\xac\xef\x94\xad\xef\x94\xae\xef\x94\xaf\xef\x94\xb0\xef\x94\xb1\xef\x94\xb2\xef\x94\xb3\xef\x94\xb4\xef\x94\xb5\xef\x94\xb6\xef\x94\xb7" + "\xef\x94\xb8\xef\x94\xb9\xef\x94\xba\xef\x94\xbb\xef\x94\xbc\xef\x94\xbd\xef\x94\xbe\xef\x94\xbf\xef\x95\x80\xef\x95\x81\xef\x95\x82\xef\x95\x83\xef\x95\x84\xef\x95\x85\xef\x95\x86\xef\x95\x87\xef\x95\x88\xef\x95\x89\xef\x95\x8a\xef\x95\x8b\xef\x95\x8c\xef\x95\x8d\xef\x95\x8e\xef\x95\x8f\xef\x95\x90\xef\x95\x91\xef\x95\x92\xef\x95\x93\xef\x95\x94\xef\x95\x95\xef\x95\x96\xef\x95\x97" + "\xef\x95\x98\xef\x95\x99\xef\x95\x9a\xef\x95\x9b\xef\x95\x9c\xef\x95\x9d\xef\x95\x9e\xef\x95\x9f\xef\x95\xa0\xef\x95\xa2\xef\x95\xa3\xef\x95\xa4\xef\x95\xa5\xef\x95\xa6\xef\x95\xa7\xef\x95\xa8\xef\x95\xa9\xef\x95\xaa\xef\x95\xab\xef\x95\xac\xef\x95\xad\xef\x95\xae\xef\x95\xaf\xef\x95\xb0\xef\x95\xb1\xef\x95\xb2\xef\x95\xb3\xef\x95\xb4\xef\x95\xb5\xef\x95\xb6\xef\x95\xb7\xef\x95\xb8" + "\xef\x95\xb9\xef\x95\xba\xef\x95\xbb\xef\x95\xbc\xef\x95\xbd\xef\x95\xbe\xef\x95\xbf\xef\x96\x80\xef\x96\x81\xef\x96\x82\xef\x96\x83\xef\x96\x84\xef\x96\x85\xef\x96\x86\xef\x96\x87\xef\x96\x88\xef\x96\x89\xef\x96\x8a\xef\x96\x8b\xef\x96\x8c\xef\x96\x8d\xef\x96\x8e\xef\x96\x8f\xef\x96\x90\xef\x96\x91\xef\x96\x92\xef\x96\x93\xef\x96\x94\xef\x96\x95\xef\x96\x96\xef\x96\x97\xef\x96\x98" + "\xef\x96\x99\xef\x96\x9a\xef\x96\x9b\xef\x96\x9c\xef\x96\x9d\xef\x96\x9e\xef\x96\x9f\xef\x96\xa0\xef\x96\xa1\xef\x96\xa2\xef\x96\xa3\xef\x96\xa4\xef\x96\xa5\xef\x96\xa6\xef\x96\xa7\xef\x96\xa8\xef\x96\xa9\xef\x96\xaa\xef\x96\xab\xef\x96\xac\xef\x96\xad\xef\x96\xae\xef\x96\xaf\xef\x96\xb0\xef\x96\xb1\xef\x96\xb2\xef\x96\xb3\xef\x96\xb4\xef\x96\xb5\xef\x96\xb6\xef\x96\xb7\xef\x96\xb8" + "\xef\x96\xb9\xef\x96\xba\xef\x96\xbb\xef\x96\xbc\xef\x96\xbd\xef\x96\xbe\xef\x96\xbf\xef\x97\x80\xef\x97\x81\xef\x97\x82\xef\x97\x83\xef\x97\x84\xef\x97\x85\xef\x97\x86\xef\x97\x87\xef\x97\x88\xef\x97\x89\xef\x97\x8a\xef\x97\x8b\xef\x97\x8c\xef\x97\x8d\xef\x97\x8e\xef\x97\x8f\xef\x97\x90\xef\x97\x91\xef\x97\x92\xef\x97\x93\xef\x97\x94\xef\x97\x95\xef\x97\x96\xef\x97\x97\xef\x97\x98" + "\xef\x97\x99\xef\x97\x9a\xef\x97\x9b\xef\x97\x9c\xef\x97\x9d\xef\x97\x9e\xef\x97\x9f\xef\x97\xa0\xef\x97\xa1\xef\x97\xa2\xef\x97\xa3\xef\x97\xa4\xef\x97\xa5\xef\x97\xa6\xef\x97\xa7\xef\x97\xa8\xef\x97\xa9\xef\x97\xaa\xef\x97\xab\xef\x97\xac\xef\x97\xad\xef\x97\xae\xef\x97\xaf\xef\x97\xb0\xef\x97\xb1\xef\x97\xb2\xef\x97\xb3\xef\x97\xb4\xef\x97\xb5\xef\x97\xb6\xef\x97\xb7\xef\x97\xb8" + "\xef\x97\xb9\xef\x97\xba\xef\x97\xbb\xef\x97\xbc\xef\x97\xbd\xef\x97\xbe\xef\x97\xbf\xef\x98\x80\xef\x98\x81\xef\x98\x82\xef\x98\x83\xef\x98\x84\xef\x98\x85\xef\x98\x86\xef\x98\x87\xef\x98\x88\xef\x98\x89\xef\x98\x8a\xef\x98\x8b\xef\x98\x8c\xef\x98\x8d\xef\x98\x8e\xef\x98\x8f\xef\x98\x90\xef\x98\x91\xef\x98\x92\xef\x98\x93\xef\x98\x94\xef\x98\x95\xef\x98\x96\xef\x98\x97\xef\x98\x98" + "\xef\x98\x99\xef\x98\x9a\xef\x98\x9b\xef\x98\x9c\xef\x98\x9d\xef\x98\x9e\xef\x98\x9f\xef\x98\xa0\xef\x98\xa1\xef\x98\xa2\xef\x98\xa3\xef\x98\xa4\xef\x98\xa5\xef\x98\xa6\xef\x98\xa7\xef\x98\xa8\xef\x98\xa9\xef\x98\xaa\xef\x98\xab\xef\x98\xac\xef\x98\xad\xef\x98\xae\xef\x98\xaf\xef\x98\xb0\xef\x98\xb1\xef\x98\xb2\xef\x98\xb3\xef\x98\xb4\xef\x98\xb5\xef\x98\xb6\xef\x98\xb8\xef\x98\xb9" + "\xef\x98\xba\xef\x98\xbb\xef\x98\xbc\xef\x98\xbd\xef\x98\xbe\xef\x98\xbf\xef\x99\x80\xef\x99\x81\xef\x99\x82\xef\x99\x83\xef\x99\x84\xef\x99\x85\xef\x99\x86\xef\x99\x87\xef\x99\x88\xef\x99\x89\xef\x99\x8a\xef\x99\x8b\xef\x99\x8c\xef\x99\x8d\xef\x99\x8e\xef\x99\x8f\xef\x99\x90\xef\x99\x91\xef\x99\x92\xef\x99\x93\xef\x99\x94\xef\x99\x95\xef\x99\x96\xef\x99\x97\xef\x99\x98\xef\x99\x99" + "\xef\x99\x9a\xef\x99\x9b\xef\x99\x9c\xef\x99\x9d\xef\x99\x9e\xef\x99\x9f\xef\x99\xa0\xef\x99\xa1\xef\x99\xa2\xef\x99\xa3\xef\x99\xa4\xef\x99\xa5\xef\x99\xa6\xef\x9b\x92\xef\x9b\x93\xef\x9b\x94\xef\x9b\x95\xef\x9b\x96\xef\x9b\x97\xef\x9b\xb6\xef\x9b\xb8\xef\x9b\xb9\xef\x9b\xbb\xef\x9b\xbd\xef\x9c\x80\xef\x9c\x82\xef\x9c\x83\xef\x9e\x8b\xef\x9e\x8c\xef\x9e\x8d\xef\x9e\x8e\xef\x9e\x8f" + "\xef\x9e\x90\xef\x9e\x91\xef\x9e\x92\xef\x9e\x93\xef\x9e\x94\xef\x9e\x95\xef\x9e\x96\xef\x9e\x97\xef\x9e\x98\xef\x9e\x99\xef\x9e\x9a\xef\x9e\x9b\xef\x9e\x9c\xef\x9e\x9d\xef\x9e\x9e\xef\x9e\x9f\xef\x9e\xa0\xef\x9e\xa1\xef\x9e\xa2\xef\x9e\xa3\xef\x9e\xa4\xef\x9e\xa5\xef\x9e\xa6\xef\x9e\xa7\xef\x9e\xa8\xef\x9e\xa9\xef\x9e\xaa\xef\x9e\xab\xef\x9e\xac\xef\x9e\xad\xef\x9e\xae\xef\x9e\xaf" + "\xef\x9e\xb0\xef\x9e\xb1\xef\x9e\xb2\xef\x9e\xb3\xef\x9e\xb4\xef\x9e\xb5\xef\x9e\xb6\xef\x9e\xb7\xef\x9e\xb8\xef\x9e\xb9\xef\x9e\xba\xef\x9e\xbb\xef\x9e\xbc\xef\x9e\xbd\xef\x9e\xbe\xef\x9e\xbf\xef\x9f\x80\xef\x9f\x81\xef\x9f\x82\xef\x9f\x83\xef\x9f\x84\xef\x9f\x85\xef\x9f\x86\xef\x9f\x87\xef\x9f\x88\xef\x9f\x89\xef\x9f\x8a\xef\x9f\x8b\xef\x9f\x8c\xef\x9f\x8d\xef\x9f\x8e\xef\x9f\x8f" + "\xef\x9f\x90\xef\x9f\x91\xef\x9f\x92\xef\x9f\xa3\xef\x9f\xa8\xef\x9f\xac\xef\x9f\xad\xef\x9f\xae\xef\x9f\xaf\xef\x9f\xb0\xef\x9f\xb1\xef\x9f\xbb\xef\x9f\xbc\xef\x9f\xbd\xef\x9f\xbe\xef\x9f\xbf\xef\xa0\x80\xef\xa0\x81\xef\xa0\x82\xef\xa0\x83\xef\xa0\x84\xef\xa0\x85\xef\xa0\x86\xef\xa0\x87\xef\xa0\x88\xef\xa0\x89\xef\xa0\x8a\xef\xa0\x8b\xef\xa0\x8c\xef\xa0\x8d\xef\xa0\x8e\xef\xa0\x8f" + "\xef\xa0\x90\xef\xa0\x91\xef\xa0\x92\xef\xa0\x93\xef\xa0\x94\xef\xa0\x95\xef\xa0\x96\xef\xa0\x97\xef\xa0\x98\xef\xa0\x99\xef\xa0\x9a\xef\xa0\x9b\xef\xa0\x9c\xef\xa0\x9d\xef\xa0\x9e\xef\xa0\x9f\xef\xa0\xa0\xef\xa0\xa1\xef\xa0\xa2\xef\xa0\xa3\xef\xa0\xa4\xef\xa0\xa5\xef\xa0\xa6\xef\xa0\xa7\xef\xa0\xa8\xef\xa0\xa9\xef\xa0\xaa\xef\xa0\xab\xef\xa0\xac\xef\xa0\xad\xef\xa0\xae\xef\xa0\xaf" + "\xef\xa0\xb0\xef\xa0\xb1\xef\xa0\xb2\xef\xa0\xb3\xef\xa0\xb4\xef\xa0\xb5\xef\xa0\xb6\xef\xa0\xb7\xef\xa0\xb8\xef\xa0\xb9\xef\xa0\xba\xef\xa0\xbb\xef\xa0\xbc\xef\xa0\xbd\xef\xa0\xbe\xef\xa0\xbf\xef\xa1\x80\xef\xa1\x81\xef\xa1\x82\xef\xa1\x83\xef\xa1\x84\xef\xa1\x85\xef\xa1\x86\xef\xa1\x87\xef\xa1\x88\xef\xa1\x89\xef\xa1\x8a\xef\xa1\x8b\xef\xa1\x8c\xef\xa1\x8d\xef\xa1\x8e\xef\xa1\x8f" + "\xef\xa1\x90\xef\xa1\x91\xef\xa1\x92\xef\xa1\x93\xef\xa1\x94\xef\xa1\x95\xef\xa1\x96\xef\xa1\x97\xef\xa1\x98\xef\xa1\x99\xef\xa1\x9a\xef\xa1\x9b\xef\xa1\x9c\xef\xa1\x9d\xef\xa1\x9e\xef\xa1\x9f\xef\xa1\xa0\xef\xa1\xa1\xef\xa1\xa2\xef\xa1\xa3\xef\xa1\xa4\xef\xa1\xa5\xef\xa1\xa6\xef\xa1\xa7\xef\xa1\xa8\xef\xa1\xa9\xef\xa1\xaa\xef\xa1\xab\xef\xa1\xac\xef\xa1\xad\xef\xa1\xae\xef\xa1\xaf" + "\xef\xa1\xb0\xef\xa1\xb1\xef\xa1\xb2\xef\xa1\xb3\xef\xa1\xb4\xef\xa1\xb5\xef\xa1\xb6\xef\xa1\xb7\xef\xa1\xb8\xef\xa1\xb9\xef\xa1\xba\xef\xa1\xbb\xef\xa1\xbc\xef\xa1\xbd\xef\xa1\xbe\xef\xa1\xbf\xef\xa2\x80\xef\xa2\x81\xef\xa2\x82\xef\xa2\x83\xef\xa2\x84\xef\xa2\x85\xef\xa2\x86\xef\xa2\x87\xef\xa2\x88\xef\xa2\x89\xef\xa2\x8a\xef\xa2\x8b\xef\xa2\x8c\xef\xa2\x8d\xef\xa2\x8e\xef\xa2\x8f" + "\xef\xa2\x90\xef\xa2\x91\xef\xa2\x92\xef\xa2\x93\xef\xa2\x94\xef\xa2\x95\xef\xa2\x96\xef\xa2\x97\xef\xa2\x98\xef\xa2\x99\xef\xa2\x9a\xef\xa2\x9b\xef\xa2\x9c\xef\xa2\x9d\xef\xa2\x9e\xef\xa2\x9f\xef\xa2\xa0\xef\xa2\xa1\xef\xa2\xa2\xef\xa2\xa3\xef\xa2\xa4\xef\xa2\xa5\xef\xa2\xa6\xef\xa2\xa7\xef\xa2\xa8\xef\xa2\xa9\xef\xa2\xaa\xef\xa2\xab\xef\xa2\xac\xef\xa2\xad\xef\xa2\xae\xef\xa2\xaf" + "\xef\xa2\xb0\xef\xa2\xb1\xef\xa2\xb2\xef\xa2\xb3\xef\xa2\xb4\xef\xa2\xb5\xef\xa2\xb6\xef\xa2\xb7\xef\xa2\xb8\xef\xa2\xb9\xef\xa2\xba\xef\xa2\xbb\xef\xa2\xbc\xef\xa2\xbd\xef\xa2\xbe\xef\xa2\xbf\xef\xa3\x80\xef\xa3\x81\xef\xa3\x82\xef\xa3\x83\xef\xa3\x84\xef\xa3\x85\xef\xa3\x86\xef\xa3\x87\xef\xa3\x88\xef\xa3\x89\xef\xa3\x8a\xef\xa3\x8b\xef\xa3\x8c\xef\xa3\x8d\xef\xa3\x8e\xef\xa3\x8f" + "\xef\xa3\x90\xef\xa3\x91\xef\xa3\x92\xef\xa3\x93\xef\xa3\x94\xef\xa3\x95\xef\xa3\x96\xef\xa3\x97\xef\xa3\x98\xef\xa3\x99\xef\xa3\x9a\xef\xa3\x9b\xef\xa3\x9c\xef\xa3\x9d\xef\xa3\x9e\xef\xa3\x9f\xef\xa3\xa0\xef\xa3\xa1\xef\xa3\xa2\xef\xa3\xa3\xef\xa3\xa4\xef\xa3\xa5\xef\xa3\xa6\xef\xa3\xa7\xef\xa3\xa8\xef\xa3\xa9\xef\xa3\xaa\xef\xa3\xab\xef\xa3\xac\xef\xa3\xad\xef\xa3\xae\xef\xa3\xaf" + "\xef\xa3\xb0\xef\xa3\xb1\xef\xa3\xb2\xef\xa3\xb3\xef\xa3\xb4\xef\xa3\xb5\xef\xa3\xb6\xef\xa3\xb7\xef\xa3\xb8\xef\xa3\xb9\xef\xa3\xba\xef\xa3\xbb\xef\xa3\xbc\xef\xa3\xbd\xef\xa3\xbe\xef\xa3\xbf\xef\xa4\x80\xef\xa4\x81\xef\xa4\x82\xef\xa4\x83\xef\xa4\x84\xef\xa4\x85\xef\xa4\x86\xef\xa4\x87\xef\xa4\x88\xef\xa4\x89\xef\xa4\x8a\xef\xa4\x8b\xef\xa4\x8c\xef\xa4\x8d\xef\xa4\x8e\xef\xa4\x8f" + "\xef\xa4\x90\xef\xa4\x91\xef\xa4\x92\xef\xa4\x93\xef\xa4\x94\xef\xa4\x95\xef\xa4\x96\xef\xa4\x97\xef\xa4\x98\xef\xa4\x99\xef\xa4\x9a\xef\xa4\x9b\xef\xa4\x9c\xef\xa4\x9d\xef\xa4\x9e\xef\xa4\x9f\xef\xa4\xa0\xef\xa4\xa1\xef\xa4\xa2\xef\xa4\xa3\xef\xa4\xa4\xef\xa4\xa5\xef\xa4\xa6\xef\xa4\xa7\xef\xa4\xa8\xef\xa4\xa9\xef\xa4\xaa\xef\xa4\xab\xef\xa4\xac\xef\xa4\xad\xef\xa4\xae\xef\xa4\xaf" + "\xef\xa4\xb0\xef\xa4\xb1\xef\xa4\xb2\xef\xa4\xb3\xef\xa4\xb4\xef\xa4\xb5\xef\xa4\xb6\xef\xa4\xb7\xef\xa4\xb8\xef\xa4\xb9\xef\xa4\xba\xef\xa4\xbb\xef\xa4\xbc\xef\xa4\xbd\xef\xa4\xbe\xef\xa4\xbf\xef\xa5\x80\xef\xa5\x81\xef\xa5\x82\xef\xa5\x83\xef\xa5\x84\xef\xa5\x85\xef\xa5\x86\xef\xa5\x87\xef\xa5\x88\xef\xa5\x89\xef\xa5\x8a\xef\xa5\x8b\xef\xa5\x8c\xef\xa5\x8d\xef\xa5\x8e\xef\xa5\x8f" + "\xef\xa5\x90\xef\xa5\x91\xef\xa5\x92\xef\xa5\x93\xef\xa5\x94\xef\xa5\x95\xef\xa5\x96\xef\xa5\x97\xef\xa5\x98\xef\xa5\x99\xef\xa5\x9a\xef\xa5\x9b\xef\xa5\x9c\xef\xa5\x9d\xef\xa5\x9e\xef\xa5\x9f\xef\xa5\xa0\xef\xa5\xa1\xef\xa5\xa2\xef\xa5\xa3\xef\xa5\xa4\xef\xa5\xa5\xef\xa5\xa6\xef\xa5\xa7\xef\xa5\xa8\xef\xa5\xa9\xef\xa5\xaa\xef\xa5\xab\xef\xa5\xac\xef\xa5\xad\xef\xa5\xae\xef\xa5\xaf" + "\xef\xa5\xb0\xef\xa5\xb1\xef\xa5\xb2\xef\xa5\xb3\xef\xa5\xb4\xef\xa5\xb5\xef\xa5\xb6\xef\xa5\xb7\xef\xa5\xb8\xef\xa5\xb9\xef\xa5\xba\xef\xa5\xbb\xef\xa5\xbc\xef\xa5\xbd\xef\xa5\xbe\xef\xa5\xbf\xef\xa6\x80\xef\xa6\x81\xef\xa6\x82\xef\xa6\x83\xef\xa6\x84\xef\xa6\x85\xef\xa6\x86\xef\xa6\x87\xef\xa6\x88\xef\xa6\x89\xef\xa6\x8a\xef\xa6\x8b\xef\xa6\x8c\xef\xa6\x8d\xef\xa6\x8e\xef\xa6\x8f" + "\xef\xa6\x90\xef\xa6\x91\xef\xa6\x92\xef\xa6\x93\xef\xa6\x94\xef\xa6\x95\xef\xa6\x96\xef\xa6\x97\xef\xa6\x98\xef\xa6\x99\xef\xa6\x9a\xef\xa6\x9b\xef\xa6\x9c\xef\xa6\x9d\xef\xa6\x9e\xef\xa6\x9f\xef\xa6\xa0\xef\xa6\xa1\xef\xa6\xa2\xef\xa6\xa3\xef\xa6\xa4\xef\xa6\xa5\xef\xa6\xa6\xef\xa6\xa7\xef\xa6\xa8\xef\xa6\xa9\xef\xa6\xaa\xef\xa6\xab\xef\xa6\xac\xef\xa6\xad\xef\xa6\xae\xef\xa6\xaf" + "\xef\xa6\xb0\xef\xa6\xb1\xef\xa6\xb2\xef\xa6\xb3\xef\xa6\xb4\xef\xa6\xb5\xef\xa6\xb6\xef\xa6\xb7\xef\xa6\xb8\xef\xa6\xb9\xef\xa6\xba\xef\xa6\xbb\xef\xa6\xbc\xef\xa6\xbd\xef\xa6\xbe\xef\xa6\xbf\xef\xa7\x80\xef\xa7\x81\xef\xa7\x82\xef\xa7\x83\xef\xa7\x84\xef\xa7\x85\xef\xa7\x86\xef\xa7\x87\xef\xa7\x88\xef\xa7\x89\xef\xa7\x8a\xef\xa7\x8b\xef\xa7\x8c\xef\xa7\x8d\xef\xa7\x8e\xef\xa7\x8f" + "\xef\xa7\x90\xef\xa7\x91\xef\xa7\x92\xef\xa7\x93\xef\xa7\x94\xef\xa7\x95\xef\xa7\x96\xef\xa7\x97\xef\xa7\x98\xef\xa7\x99\xef\xa7\x9a\xef\xa7\x9b\xef\xa7\x9c\xef\xa7\x9d\xef\xa7\x9e\xef\xa7\x9f\xef\xa7\xa0\xef\xa7\xa1\xef\xa7\xa2\xef\xa7\xa3\xef\xa7\xa4\xef\xa7\xa5\xef\xa7\xa6\xef\xa7\xa7\xef\xa7\xa8\xef\xa7\xa9\xef\xa7\xaa\xef\xa7\xab\xef\xa7\xac\xef\xa7\xad\xef\xa7\xae\xef\xa7\xaf" + "\xef\xa7\xb0\xef\xa7\xb1\xef\xa7\xb2\xef\xa7\xb3\xef\xa7\xb4\xef\xa7\xb5\xef\xa7\xb6\xef\xa7\xb7\xef\xa7\xb8\xef\xa7\xb9\xef\xa7\xba\xef\xa7\xbb\xef\xa7\xbc\xef\xa7\xbd\xef\xa7\xbe\xef\xa7\xbf\xef\xa8\x80\xef\xa8\x81\xef\xa8\x82\xef\xa8\x83\xef\xa8\x84\xef\xa8\x85\xef\xa8\x86\xef\xa8\x87\xef\xa8\x88\xef\xa8\x89\xef\xa8\x8a\xef\xa8\x8b\xef\xa8\x8c\xef\xa8\x8d\xef\xa8\x8e\xef\xa8\x8f" + "\xef\xa8\x90\xef\xa8\x91\xef\xa8\x92\xef\xa8\x93\xef\xa8\x94\xef\xa8\x95\xef\xa8\x96\xef\xa8\x97\xef\xa8\x98\xef\xa8\x99\xef\xa8\x9a\xef\xa8\x9b\xef\xa8\x9c\xef\xa8\x9d\xef\xa8\x9e\xef\xa8\x9f\xef\xa8\xa0\xef\xa8\xa1\xef\xa8\xa2\xef\xa8\xa3\xef\xa8\xa4\xef\xa8\xa5\xef\xa8\xa6\xef\xa8\xa7\xef\xa8\xa8\xef\xa8\xa9\xef\xa8\xaa\xef\xa8\xab\xef\xa8\xac\xef\xa8\xad\xef\xa8\xae\xef\xa8\xaf" + "\xef\xa8\xb0\xef\xa8\xb1\xef\xa8\xb2\xef\xa8\xb3\xef\xa9\x8c\xef\xa9\x8d\xef\xa9\x8e\xef\xa9\x8f\xef\xa9\x90\xef\xa9\x91\xef\xa9\x92\xef\xa9\x93\xef\xa9\x94\xef\xa9\x95\xef\xa9\x96\xef\xa9\x97\xef\xa9\x98\xef\xa9\x99\xef\xa9\x9a\xef\xa9\x9b\xef\xa9\x9c\xef\xa9\x9d\xef\xa9\x9e\xef\xa9\x9f\xef\xa9\xa0\xef\xa9\xa1\xef\xa9\xa2\xef\xa9\xa3\xef\xa9\xa4\xef\xa9\xa5\xef\xa9\xa6\xef\xa9\xa7" + "\xef\xa9\xa8\xef\xa9\xa9\xef\xa9\xaa\xef\xa9\xab\xef\xa9\xac\xef\xa9\xad\xef\xa9\xae\xef\xa9\xaf\xef\xa9\xb0\xef\xa9\xb1\xef\xa9\xb2\xef\xa9\xb3\xef\xa9\xb4\xef\xa9\xb5\xef\xa9\xb6\xef\xa9\xb7\xef\xa9\xb8\xef\xa9\xb9\xef\xa9\xba\xef\xa9\xbb\xef\xa9\xbc\xef\xa9\xbd\xef\xa9\xbe\xef\xa9\xbf\xef\xaa\x80\xef\xaa\x81\xef\xaa\x94\xef\xaa\x95\xef\xaa\x96\xef\xaa\x97\xef\xaa\x98\xef\xaa\x99" + "\xef\xaa\x9a\xef\xaa\x9b\xef\xaa\x9c\xef\xaa\x9d\xef\xaa\x9e\xef\xaa\x9f\xef\xaa\xa0\xef\xaa\xa1\xef\xaa\xa2\xef\xaa\xa3\xef\xaa\xa4\xef\xaa\xa5\xef\xaa\xa6\xef\xaa\xa7\xef\xaa\xa8\xef\xaa\xa9\xef\xaa\xaa\xef\xaa\xab\xef\xaa\xac\xef\xaa\xad\xef\xaa\xae\xef\xaa\xaf\xef\xaa\xb0\xef\xaa\xb1\xef\xaa\xb2\xef\xaa\xb3\xef\xaa\xb4\xef\xaa\xb5\xef\xaa\xb6\xef\xaa\xb7\xef\xaa\xb8\xef\xaa\xb9" + "\xef\xaa\xba\xef\xaa\xbb\xef\xaa\xbc\xef\xaa\xbd\xef\xaa\xbe\xef\xaa\xbf\xef\xab\x80\xef\xab\x81\xef\xab\x82\xef\xab\x83\xef\xab\x84\xef\xab\x85\xef\xab\x86\xef\xab\x87\xef\xab\x88\xef\xab\x89\xef\xab\x8a\xef\xab\x8b\xef\xab\x8c\xef\xab\x8d\xef\xab\x8e\xef\xab\x8f\xef\xab\x90\xef\xab\x91\xef\xab\x92\xef\xab\x93\xef\xab\x94\xef\xab\x95\xef\xab\x96\xef\xab\x97\xef\xab\x98\xef\xab\x99" + "\xef\xab\x9a\xef\xab\x9b\xef\xab\x9c\xef\xab\x9d\xef\xab\x9e\xef\xab\x9f\xef\xab\xa0\xef\xab\xa1\xef\xab\xa2\xef\xab\xa3\xef\xab\xa4\xef\xab\xa5\xef\xab\xa6\xef\xab\xa7\xef\xab\xa8\xef\xab\xa9\xef\xab\xaa\xef\xab\xab\xef\xab\xac\xef\xab\xad\xef\xab\xae\xef\xab\xaf\xef\xab\xb0\xef\xab\xb1\xef\xab\xb2\xef\xab\xb3\xef\xab\xb4\xef\xab\xb5\xef\xab\xb6\xef\xab\xb7\xef\xab\xb8\xef\xab\xb9" + "\xef\xab\xba\xef\xab\xbb\xef\xab\xbc\xef\xab\xbd\xef\xab\xbe\xef\xab\xbf\xef\xac\x80\xef\xac\x81\xef\xac\x82\xef\xac\x83\xef\xac\x84\xef\xac\x85\xef\xac\x86\xef\xac\x87\xef\xac\x88\xef\xac\x89\xef\xac\x8a\xef\xac\x8b\xef\xac\x8c\xef\xac\x8d\xef\xac\x8e\xef\xac\x8f\xef\xac\x90\xef\xac\x91\xef\xac\x92\xef\xac\x93\xef\xac\x94\xef\xac\x95\xef\xac\x96\xef\xac\x97\xef\xac\x98\xef\xac\x99" + "\xef\xac\x9a\xef\xac\x9b\xef\xac\x9c\xef\xac\x9d\xef\xac\x9e\xef\xad\x83\xef\xad\x84\xef\xad\x85\xef\xad\x86\xef\xad\x87\xef\xad\x88\xef\xad\x89\xef\xad\x8a\xef\xad\x8b\xef\xad\x8c\xef\xad\x8d\xef\xad\x8e\xef\xad\x8f\xef\xad\x90\xef\xad\x91\xef\xad\x92\xef\xad\x93\xef\xad\x94\xef\xad\x95\xef\xad\x96\xef\xad\x97\xef\xad\x98\xef\xad\x99\xef\xad\x9a\xef\xad\x9b\xef\xad\x9c\xef\xad\x9d" + "\xef\xad\x9e\xef\xad\x9f\xef\xad\xa0\xef\xad\xa1\xef\xad\xa2\xef\xad\xa3\xef\xad\xa4\xef\xad\xa5\xef\xad\xa6\xef\xad\xa7\xef\xad\xa8\xef\xad\xa9\xef\xad\xaa\xef\xad\xab\xef\xad\xad\xef\xad\xae\xef\xad\xaf\xef\xad\xb0\xef\xad\xb1\xef\xad\xb2\xef\xad\xb3\xef\xad\xb4\xef\xad\xb5\xef\xad\xb6\xef\xad\xb7\xef\xad\xb8\xef\xad\xb9\xef\xad\xba\xef\xad\xbb\xef\xad\xbc\xef\xad\xbd\xef\xad\xbe" + "\xef\xad\xbf\xef\xae\x80\xef\xae\x81\xef\xae\x82\xef\xae\x83\xef\xae\x84\xef\xae\x85\xef\xae\x86\xef\xae\x87\xef\xae\x88\xef\xae\x89\xef\xae\x8a\xef\xae\x8b\xef\xae\x8c\xef\xae\x8d\xef\xae\x8e\xef\xae\x8f\xef\xae\x90\xef\xae\x91\xef\xae\x92\xef\xae\x93\xef\xae\x94\xef\xae\x95\xef\xae\x96\xef\xae\x97\xef\xae\x98\xef\xae\x99\xef\xae\x9a\xef\xae\x9b\xef\xae\x9c\xef\xae\x9d\xef\xae\x9e" + "\xef\xae\x9f\xef\xae\xa0\xef\xae\xa1\xef\xae\xa2\xef\xae\xa3\xef\xae\xa4\xef\xae\xa5\xef\xae\xa6\xef\xae\xa7\xef\xae\xa8\xef\xae\xa9\xef\xae\xaa\xef\xae\xab\xef\xae\xac\xef\xae\xad\xef\xae\xae\xef\xae\xaf\xef\xae\xb0\xef\xae\xb1\xef\xae\xb2\xef\xae\xb3\xef\xae\xb4\xef\xae\xb5\xef\xae\xb6\xef\xae\xb7\xef\xae\xb8\xef\xae\xb9\xef\xae\xba\xef\xae\xbb\xef\xae\xbc\xef\xae\xbd\xef\xae\xbe" + "\xef\xae\xbf\xef\xaf\x80\xef\xaf\x81\xef\xaf\x82\xef\xaf\x83\xef\xaf\x84\xef\xaf\x85\xef\xaf\x86\xef\xaf\x87\xef\xaf\x88\xef\xaf\x89\xef\xaf\x8a\xef\xaf\x8b\xef\xaf\x8c\xef\xaf\x8d\xef\xaf\x8e\xef\xaf\x8f\xef\xaf\x90\xef\xaf\x91\xef\xaf\x92\xef\xaf\x93\xef\xaf\x94\xef\xaf\x95\xef\xaf\x96\xef\xaf\x97\xef\xaf\x98\xef\xaf\x99\xef\xaf\x9a\xef\xaf\x9b\xef\xaf\x9c\xef\xaf\x9d\xef\xaf\x9e" + "\xef\xaf\x9f\xef\xaf\xa0\xef\xaf\xa1\xef\xaf\xa2\xef\xaf\xa3\xef\xaf\xa4\xef\xaf\xa5\xef\xaf\xa6\xef\xaf\xa7\xef\xaf\xa8\xef\xaf\xa9\xef\xaf\xaa\xef\xaf\xab\xef\xaf\xac\xef\xaf\xad\xef\xaf\xae\xef\xaf\xaf\xef\xaf\xb0\xef\xaf\xb1\xef\xaf\xb2\xef\xaf\xb3\xef\xaf\xb4\xef\xaf\xb5\xef\xaf\xb6\xef\xaf\xb7\xef\xaf\xb8\xef\xaf\xb9\xef\xaf\xba\xef\xaf\xbb\xef\xaf\xbc\xef\xaf\xbd\xef\xaf\xbe" + "\xef\xaf\xbf\xef\xb0\x80\xef\xb0\x81\xef\xb0\x82\xef\xb0\x83\xef\xb0\x84\xef\xb0\x85\xef\xb0\x86\xef\xb0\x87\xef\xb0\x88\xef\xb0\x89\xef\xb0\x8a\xef\xb0\x8b\xef\xb0\x8c\xef\xb0\x8d\xef\xb0\x8e\xef\xb0\x8f\xef\xb0\x90\xef\xb0\x91\xef\xb0\x92\xef\xb0\x93\xef\xb0\x94\xef\xb0\x95\xef\xb0\x96\xef\xb0\x97\xef\xb0\x98\xef\xb0\x99\xef\xb0\x9a\xef\xb0\x9b\xef\xb0\x9c\xef\xb0\x9d\xef\xb0\x9e" + "\xef\xb0\x9f\xef\xb0\xa0\xef\xb1\x81\xef\xb1\x82\xef\xb1\x83\xef\xb1\x84\xef\xb1\x85\xef\xb1\x86\xef\xb1\x87\xef\xb1\x88\xef\xb1\x89\xef\xb1\x8a\xef\xb1\x8b\xef\xb1\x8c\xef\xb1\x8d\xef\xb1\x8e\xef\xb1\x8f\xef\xb1\x90\xef\xb1\x91\xef\xb1\x92\xef\xb1\x93\xef\xb1\x94\xef\xb1\x95\xef\xb1\x96\xef\xb1\x97\xef\xb1\x98\xef\xb1\x99\xef\xb1\x9a\xef\xb1\x9b\xef\xb1\x9c\xef\xb1\x9d\xef\xb1\x9e" + "\xef\xb1\x9f\xef\xb1\xa0\xef\xb1\xa1\xef\xb1\xa2\xef\xb1\xa3\xef\xb1\xa4\xef\xb1\xa5\xef\xb1\xa6\xef\xb1\xa7\xef\xb1\xa8\xef\xb1\xa9\xef\xb1\xaa\xef\xb1\xab\xef\xb1\xac\xef\xb1\xad\xef\xb1\xae\xef\xb1\xaf\xef\xb1\xb0\xef\xb1\xb1\xef\xb1\xb2\xef\xb1\xb3\xef\xb1\xb4\xef\xb1\xb5\xef\xb1\xb6\xef\xb1\xb7\xef\xb1\xb8\xef\xb1\xb9\xef\xb1\xba\xef\xb1\xbb\xef\xb1\xbc\xef\xb1\xbd\xef\xb1\xbe" + "\xef\xb1\xbf\xef\xb2\x80\xef\xb2\x81\xef\xb2\x82\xef\xb2\x83\xef\xb2\x84\xef\xb2\x85\xef\xb2\x86\xef\xb2\x87\xef\xb2\x88\xef\xb2\x89\xef\xb2\x8a\xef\xb2\x8b\xef\xb2\x8c\xef\xb2\x8d\xef\xb2\x8e\xef\xb2\x8f\xef\xb2\x90\xef\xb2\x91\xef\xb2\x92\xef\xb2\x93\xef\xb2\x94\xef\xb2\x95\xef\xb2\x96\xef\xb2\x97\xef\xb2\x98\xef\xb2\x99\xef\xb2\x9a\xef\xb2\x9b\xef\xb2\x9c\xef\xb2\x9d\xef\xb2\x9e" + "\xef\xb2\x9f\xef\xb2\xa0\xef\xb2\xa1\xef\xb2\xa2\xef\xb2\xa3\xef\xb2\xa4\xef\xb2\xa5\xef\xb2\xa6\xef\xb2\xa7\xef\xb2\xa8\xef\xb2\xa9\xef\xb2\xaa\xef\xb2\xab\xef\xb2\xac\xef\xb2\xad\xef\xb2\xae\xef\xb2\xaf\xef\xb2\xb0\xef\xb2\xb1\xef\xb2\xb2\xef\xb2\xb3\xef\xb2\xb4\xef\xb2\xb5\xef\xb2\xb6\xef\xb2\xb7\xef\xb2\xb8\xef\xb2\xb9\xef\xb2\xba\xef\xb2\xbb\xef\xb2\xbc\xef\xb2\xbd\xef\xb2\xbe" + "\xef\xb2\xbf\xef\xb3\x80\xef\xb3\x81\xef\xb3\x82\xef\xb3\x83\xef\xb3\x84\xef\xb3\x85\xef\xb3\x86\xef\xb3\x87\xef\xb3\x88\xef\xb3\x89\xef\xb3\x8a\xef\xb3\x8b\xef\xb3\x8c\xef\xb3\x8d\xef\xb3\x8e\xef\xb3\x8f\xef\xb3\x90\xef\xb3\x91\xef\xb3\x92\xef\xb3\x93\xef\xb3\x94\xef\xb3\x95\xef\xb3\x96\xef\xb3\x97\xef\xb3\x98\xef\xb3\x99\xef\xb3\x9a\xef\xb3\x9b\xef\xb3\x9c\xef\xb3\x9d\xef\xb3\x9e" + "\xef\xb3\x9f\xef\xb3\xa0\xef\xb3\xa1\xef\xb3\xa2\xef\xb3\xa3\xef\xb3\xa4\xef\xb3\xa5\xef\xb3\xa6\xef\xb3\xa7\xef\xb3\xa8\xef\xb3\xa9\xef\xb3\xaa\xef\xb3\xab\xef\xb3\xac\xef\xb3\xad\xef\xb3\xae\xef\xb3\xaf\xef\xb3\xb0\xef\xb3\xb1\xef\xb3\xb2\xef\xb3\xb3\xef\xb3\xb4\xef\xb3\xb5\xef\xb3\xb6\xef\xb3\xb7\xef\xb3\xb8\xef\xb3\xb9\xef\xb3\xba\xef\xb3\xbb\xef\xb3\xbc\xef\xb3\xbd\xef\xb3\xbe" + "\xef\xb4\x8d\xef\xb4\x96\xef\xb4\x97\xef\xb4\x9b\xef\xb4\x9c\xef\xb4\x9d\xef\xb4\x9e\xef\xb4\x9f\xef\xb4\xa0\xef\xb4\xa1\xef\xb4\xa2\xef\xb4\xa3\xef\xb4\xa4\xef\xb4\xa5\xef\xb4\xa6\xef\xb4\xa7\xef\xb4\xa8\xef\xb4\xa9\xef\xb4\xaa\xef\xb4\xab\xef\xb4\xac\xef\xb4\xad\xef\xb4\xae\xef\xb4\xaf\xef\xb4\xb0\xef\xb4\xb1\xef\xb4\xb2\xef\xb4\xb3\xef\xb4\xb4\xef\xb4\xb5\xef\xb4\xb6\xef\xb4\xb7" + "\xef\xb4\xb8\xef\xb4\xb9\xef\xb4\xba\xef\xb4\xbb\xef\xb4\xbc\xef\xb4\xbd\xef\xb4\xbe\xef\xb5\x83\xef\xb5\x84\xef\xb5\x85\xef\xb5\x86\xef\xb5\x87\xef\xb5\x88\xef\xb5\x89\xef\xb5\x8a\xef\xb5\x8b\xef\xb5\x8c\xef\xb5\x8d\xef\xb5\x8e\xef\xb5\x8f\xef\xb5\x90\xef\xb5\x91\xef\xb5\x92\xef\xb5\x93\xef\xb5\x94\xef\xb5\x95\xef\xb5\x96\xef\xb5\x97\xef\xb5\x98\xef\xb5\x99\xef\xb5\x9a\xef\xb5\x9b" + "\xef\xb5\x9c\xef\xb5\x9d\xef\xb5\x9e\xef\xb5\x9f\xef\xb5\xa0\xef\xb5\xa1\xef\xb5\xa2\xef\xb5\xa3\xef\xb5\xa4\xef\xb5\xa5\xef\xb5\xa6\xef\xb5\xa7\xef\xb5\xa8\xef\xb5\xa9\xef\xb5\xaa\xef\xb5\xab\xef\xb5\xac\xef\xb5\xad\xef\xb5\xae\xef\xb5\xaf\xef\xb5\xb0\xef\xb5\xb1\xef\xb5\xb2\xef\xb5\xb3\xef\xb5\xb5\xef\xb5\xb6\xef\xb5\xb7\xef\xb5\xb8\xef\xb5\xb9\xef\xb5\xba\xef\xb5\xbb\xef\xb5\xbc" + "\xef\xb5\xbd\xef\xb5\xbe\xef\xb5\xbf\xef\xb6\x80\xef\xb6\x81\xef\xb6\x82\xef\xb6\x83\xef\xb6\x84\xef\xb6\x85\xef\xb6\x86\xef\xb6\x87\xef\xb6\x88\xef\xb6\x89\xef\xb6\x8a\xef\xb6\x8b\xef\xb6\x8c\xef\xb6\x8d\xef\xb6\x8e\xef\xb6\x8f\xef\xb6\x90\xef\xb6\x91\xef\xb6\x92\xef\xb6\x93\xef\xb6\x94\xef\xb6\x95\xef\xb6\x96\xef\xb6\x97\xef\xb6\x98\xef\xb6\x99\xef\xb6\x9a\xef\xb6\x9b\xef\xb6\x9c" + "\xef\xb6\x9d\xef\xb6\x9e\xef\xb6\x9f\xef\xb6\xa0\xef\xb6\xa1\xef\xb6\xa2\xef\xb6\xa3\xef\xb6\xa4\xef\xb6\xa5\xef\xb6\xa6\xef\xb6\xa7\xef\xb6\xa8\xef\xb6\xa9\xef\xb6\xaa\xef\xb6\xab\xef\xb6\xac\xef\xb6\xad\xef\xb6\xae\xef\xb6\xaf\xef\xb6\xb0\xef\xb6\xb1\xef\xb6\xb2\xef\xb6\xb3\xef\xb6\xb4\xef\xb6\xb5\xef\xb6\xb6\xef\xb6\xb7\xef\xb6\xb8\xef\xb6\xb9\xef\xb6\xba\xef\xb6\xbb\xef\xb6\xbc" + "\xef\xb6\xbd\xef\xb6\xbe\xef\xba\xa0\xef\xba\xa1\xef\xba\xa2\xef\xba\xa3\xef\xba\xa4\xef\xba\xa5\xef\xba\xa6\xef\xba\xa7\xef\xba\xa8\xef\xba\xa9\xef\xba\xaa\xef\xba\xab\xef\xba\xac\xef\xba\xad\xef\xba\xae\xef\xba\xaf\xef\xba\xb0\xef\xba\xb2\xef\xba\xb3\xef\xba\xb4\xef\xba\xb5\xef\xba\xb6\xef\xba\xb7\xef\xba\xb8\xef\xba\xb9\xef\xba\xba\xef\xba\xbb\xef\xba\xbc\xef\xba\xbd\xef\xba\xbe" + "\xef\xbb\x84\xef\xbb\x85\xef\xbb\x86\xef\xbb\x96\xef\xbb\x97\xef\xbb\x98\xef\xbb\x99\xef\xbb\x9a\xef\xbb\x9b\xef\xbb\x9c\xef\xbb\x9d\xef\xbb\x9e\xef\xbb\x9f\xef\xbb\xa0\xef\xbb\xa1\xef\xbb\xa2\xef\xbb\xa3\xef\xbb\xa4\xef\xbb\xa5\xef\xbb\xa6\xef\xbb\xa7\xef\xbb\xa8\xef\xbb\xa9\xef\xbb\xaa\xef\xbb\xab\xef\xbb\xac\xef\xbb\xad\xef\xbb\xae\xef\xbb\xaf\xef\xbb\xb0\xef\xbb\xb1\xef\xbb\xb2" + "\xef\xbb\xb3\xef\xbb\xb4\xef\xbb\xb5\xef\xbb\xb6\xef\xbb\xb7\xef\xbb\xb8\xef\xbb\xba\xef\xbb\xbb\xef\xbb\xbc\xef\xbb\xbd\xef\xbb\xbe\xef\xbb\xbf\xef\xbc\x80\xef\xbc\x8c\xef\xbc\x8d\xef\xbc\x8e\xef\xbc\x8f\xef\xbc\x90\xef\xbc\x91\xef\xbc\x92\xef\xbc\x93\xef\xbc\x94\xef\xbc\x95\xef\xbc\x96\xef\xbc\x97\xef\xbc\x98\xef\xbc\x99\xef\xbc\x9a\xef\xbc\x9b\xef\xbc\x9c\xef\xbc\x9d\xef\xbc\x9e" + "\xef\xbc\x9f\xef\xbc\xa0\xef\xbc\xa1\xef\xbc\xa2\xef\xbc\xa3\xef\xbc\xa4\xef\xbc\xa5\xef\xbc\xa6\xef\xbc\xa7\xef\xbc\xa8\xef\xbc\xa9\xef\xbc\xaa\xef\xbc\xab\xef\xbc\xac\xef\xbc\xad\xef\xbc\xae\xef\xbc\xaf\xef\xbc\xb0\xef\xbc\xb1\xef\xbc\xb2\xef\xbc\xb3\xef\xbc\xb4\xef\xbc\xb5\xef\xbc\xb6\xef\xbc\xb7\xef\xbc\xb8\xef\xbc\xb9\xef\xbc\xba\xef\xbc\xbb\xef\xbc\xbc\xef\xbc\xbd\xef\xbc\xbe" + "\xef\xbc\xbf\xef\xbd\x80\xef\xbd\x82\xef\xbd\x83\xef\xbd\x84\xef\xbd\x85\xef\xbd\x86\xef\xbd\x87\xef\xbd\x88\xef\xbd\x89\xef\xbd\x8a\xef\xbd\x8b\xef\xbd\x8c\xef\xbd\x8d\xef\xbd\x8e\xef\xbd\x8f\xef\xbd\x90\xef\xbd\x91\xef\xbd\x92\xef\xbd\xa6\xef\xbd\xa7\xef\xbd\xa8\xef\xbd\xa9\xef\xbd\xaa\xef\xbd\xab\xef\xbd\xac\xef\xbd\xad\xef\xbd\xae\xef\xbd\xaf\xef\xbd\xb0\xef\xbd\xb1\xef\xbd\xb2" + "\xef\xbd\xb3\xef\xbd\xb4\xef\xbd\xb5\xef\xbd\xb6\xef\xbd\xb7\xef\xbd\xb8\xef\xbd\xb9\xef\xbd\xba\xef\xbd\xbb\xef\xbd\xbc\xef\xbd\xbd\xef\xbd\xbe\xef\xbd\xbf\xef\xbe\x80\xef\xbe\x81\xef\xbe\x82\xef\xbe\x83\xef\xbe\x84\xef\xbe\x85\xef\xbe\x86\xef\xbe\x87\xef\xbe\x88\xef\xbe\x89\xef\xbe\x8a\xef\xbe\x8b\xef\xbe\x8c\xef\xbe\x8d\xef\xbe\x8f\xef\xbe\x90\xef\xbe\x91\xef\xbe\x92\xef\xbe\x93" + "\xef\xbe\x94\xef\xbe\x95\xef\xbe\x96\xef\xbe\x97\xef\xbe\x98\xef\xbe\x99\xef\xbe\x9a\xef\xbe\x9b\xef\xbe\x9c\xef\xbe\x9d\xef\xbe\x9e\xef\xbe\x9f\xef\xbe\xa0\xef\xbe\xa1\xef\xbe\xa2\xef\xbe\xa3\xef\xbe\xa4\xef\xbe\xa5\xef\xbe\xa6\xef\xbe\xa7\xef\xbe\xa8\xef\xbe\xa9\xef\xbe\xaa\xef\xbe\xab\xef\xbe\xac\xef\xbe\xad\xef\xbe\xae\xef\xbe\xaf\xef\xbe\xb0\xef\xbe\xb1\xef\xbe\xb2\xef\xbe\xb3" + "\xef\xbe\xb4\xef\xbe\xb5\xef\xbe\xb6\xef\xbe\xb7\xef\xbe\xb8\xef\xbe\xb9\xef\xbe\xba\xef\xbe\xbb\xef\xbe\xbc\xef\xbe\xbd\xef\xbe\xbe\xef\xbe\xbf\xef\xbf\x80\xef\xbf\x81\xef\xbf\x82\xef\xbf\x83\xef\xbf\x84\xef\xbf\x85\xef\xbf\x86\xef\xbf\x87\xef\xbf\x88\xef\xbf\x89\xef\xbf\x8a\xef\xbf\x8b\xef\xbf\x8c\xef\xbf\x8d\xef\xbf\x8e\xef\xbf\x8f\xef\xbf\x90\xef\xbf\x91\xef\xbf\x92\xef\xbf\x93" + "\xef\xbf\x94\xef\xbf\x95\xef\xbf\x96\xef\xbf\x97\xef\xbf\x98\xef\xbf\x99\xef\xbf\x9a\xef\xbf\x9b\xef\xbf\x9c\xef\xbf\x9d\xef\xbf\x9e\xef\xbf\x9f\xef\xbf\xa0\xef\xbf\xa1\xef\xbf\xa2\xef\xbf\xa3\xef\xbf\xa4\xef\xbf\xa5\xef\xbf\xa6\xef\xbf\xa7\xef\xbf\xa8\xef\xbf\xa9\xef\xbf\xaa\xef\xbf\xab\xef\xbf\xac\xef\xbf\xad\xef\xbf\xae\xef\xbf\xaf\xf0\x90\x80\x80\xf0\x90\x80\x81\xf0\x90\x80\x82\xf0\x90\x80\x83" + "\xf0\x90\x80\x84\xf0\x90\x80\x85\xf0\x90\x81\x8e\xf0\x90\x81\x8f\xf0\x90\x81\x90\xf0\x90\x81\x91\xf0\x90\x81\x92\xf0\x90\x81\x93\xf0\x90\x81\x94\xf0\x90\x81\x95\xf0\x90\x81\x96\xf0\x90\x81\x97\xf0\x90\x81\x98\xf0\x90\x81\x99\xf0\x90\x81\x9a\xf0\x90\x81\x9b\xf0\x90\x81\x9c\xf0\x90\x81\x9d\xf0\x90\x81\x9e\xf0\x90\x81\x9f\xf0\x90\x81\xa0\xf0\x90\x81\xa1\xf0\x90\x81\xa2\xf0\x90\x81\xa3\xf0\x90\x81\xa4\xf0\x90\x81\xa5\xf0\x90\x81\xa6\xf0\x90\x81\xa7\xf0\x90\x81\xa8\xf0\x90\x81\xa9\xf0\x90\x81\xaa\xf0\x90\x81\xb2" + "\xf0\x90\x81\xb3\xf0\x90\x81\xb4\xf0\x90\x82\x96\xf0\x90\x82\x97\xf0\x90\x82\x98\xf0\x90\x82\x99\xf0\x90\x82\xa8\xf0\x90\x82\xa9\xf0\x90\x82\xaa\xf0\x90\x82\xab\xf0\x90\x82\xac\xf0\x90\x82\xad\xf0\x90\x82\xae\xf0\x90\x82\xaf\xf0\x90\x82\xb0\xf0\x90\x82\xb1\xf0\x90\x82\xb2\xf0\x90\x82\xb3\xf0\x90\x82\xb4\xf0\x90\x82\xb5\xf0\x90\x82\xb6\xf0\x90\x82\xba\xf0\x90\x82\xbb\xf0\x90\x82\xbc\xf0\x90\x82\xbd\xf0\x90\x83\x9e\xf0\x90\x83\x9f\xf0\x90\x83\xa0\xf0\x90\x83\xa1\xf0\x90\x83\xa2\xf0\x90\x83\xa3\xf0\x90\x83\xa4" + "\xf0\x90\x83\xa5\xf0\x90\x83\xa6\xf0\x90\x83\xa7\xf0\x90\x83\xb0\xf0\x90\x83\xb1\xf0\x90\x83\xb2\xf0\x90\x84\xb8\xf0\x90\x84\xb9\xf0\x90\x84\xba\xf0\x90\x84\xbb\xf0\x90\x84\xbc\xf0\x90\x84\xbd\xf0\x90\x84\xbe\xf0\x90\x84\xbf\xf0\x90\x85\x80\xf0\x90\x85\x81\xf0\x90\x85\x82\xf0\x90\x85\x83\xf0\x90\x85\x84\xf0\x90\x85\x85\xf0\x90\x85\x86\xf0\x90\x85\x87\xf0\x90\x85\x88\xf0\x90\x85\x89\xf0\x90\x85\x8a\xf0\x90\x85\x8b\xf0\x90\x85\x8c\xf0\x90\x85\x8d\xf0\x90\x85\x8e\xf0\x90\x85\x8f\xf0\x90\x85\x90\xf0\x90\x85\x91" + "\xf0\x90\x85\x92\xf0\x90\x85\x93\xf0\x90\x85\x94\xf0\x90\x85\x95\xf0\x90\x85\x96\xf0\x90\x85\x97\xf0\x90\x85\x98\xf0\x90\x85\x99\xf0\x90\x85\x9a\xf0\x90\x85\x9b\xf0\x90\x85\x9c\xf0\x90\x85\x9d\xf0\x90\x85\x9e\xf0\x90\x85\x9f\xf0\x90\x85\xa0\xf0\x90\x85\xa1\xf0\x90\x85\xa2\xf0\x90\x85\xa3\xf0\x90\x85\xa4\xf0\x90\x86\x8a\xf0\x90\x86\x9d\xf0\x90\x86\x9e\xf0\x90\x86\x9f\xf0\x90\x86\xa0\xf0\x90\x86\xa1\xf0\x90\x86\xa2\xf0\x90\x86\xa3\xf0\x90\x86\xa4\xf0\x90\x86\xa5\xf0\x90\x86\xa6\xf0\x90\x86\xa7\xf0\x90\x86\xa8" + "\xf0\x90\x86\xa9\xf0\x90\x86\xaa\xf0\x90\x86\xab\xf0\x90\x86\xac\xf0\x90\x86\xad\xf0\x90\x86\xae\xf0\x90\x86\xaf\xf0\x90\x86\xb0\xf0\x90\x86\xb1\xf0\x90\x87\xa8\xf0\x90\x87\xa9\xf0\x90\x87\xaa\xf0\x90\x87\xab\xf0\x90\x87\xac\xf0\x90\x87\xad\xf0\x90\x87\xae\xf0\x90\x87\xaf\xf0\x90\x87\xb0\xf0\x90\x87\xb1\xf0\x90\x87\xb2\xf0\x90\x87\xb3\xf0\x90\x87\xb4\xf0\x90\x87\xb5\xf0\x90\x87\xb6\xf0\x90\x87\xb7\xf0\x90\x87\xb8\xf0\x90\x87\xb9\xf0\x90\x87\xba\xf0\x90\x87\xbb\xf0\x90\x87\xbc\xf0\x90\x87\xbd\xf0\x90\x87\xbe" + "\xf0\x90\x87\xbf\xf0\x90\x88\x80\xf0\x90\x88\x81\xf0\x90\x88\x82\xf0\x90\x88\x83\xf0\x90\x88\x84\xf0\x90\x88\x85\xf0\x90\x88\x86\xf0\x90\x88\x87\xf0\x90\x88\x88\xf0\x90\x88\x89\xf0\x90\x88\x8a\xf0\x90\x88\x8b\xf0\x90\x88\x90\xf0\x90\x88\x91\xf0\x90\x88\x92\xf0\x90\x88\x93\xf0\x90\x88\x94\xf0\x90\x88\x95\xf0\x90\x88\x96\xf0\x90\x88\x97\xf0\x90\x88\x98\xf0\x90\x88\x99\xf0\x90\x88\x9a\xf0\x90\x88\x9b\xf0\x90\x88\x9c\xf0\x90\x88\x9d\xf0\x90\x88\x9e\xf0\x90\x88\x9f\xf0\x90\x88\xa0\xf0\x90\x88\xa1\xf0\x90\x88\xa2" + "\xf0\x90\x88\xa3\xf0\x90\x88\xa4\xf0\x90\x88\xa5\xf0\x90\x88\xa6\xf0\x90\x88\xa7\xf0\x90\x88\xa8\xf0\x90\x88\xa9\xf0\x90\x88\xaa\xf0\x90\x88\xab\xf0\x90\x88\xac\xf0\x90\x88\xad\xf0\x90\x88\xae\xf0\x90\x88\xaf\xf0\x90\x88\xb0\xf0\x90\x88\xb1\xf0\x90\x88\xb2\xf0\x90\x88\xb3\xf0\x90\x88\xb4\xf0\x90\x88\xb5\xf0\x90\x88\xb6\xf0\x90\x88\xb7\xf0\x90\x88\xb8\xf0\x90\x88\xb9\xf0\x90\x88\xba\xf0\x90\x88\xbb\xf0\x90\x88\xbc\xf0\x90\x88\xbd\xf0\x90\x88\xbe\xf0\x90\x88\xbf\xf0\x90\x89\x80\xf0\x90\x89\x81\xf0\x90\x89\x82" + "\xf0\x90\x89\x83\xf0\x90\x89\x84\xf0\x90\x89\x85\xf0\x90\x89\x86\xf0\x90\x89\x87\xf0\x90\x89\x88\xf0\x90\x89\x89\xf0\x90\x89\x8a\xf0\x90\x89\x8b\xf0\x90\x89\x8c\xf0\x90\x89\x8d\xf0\x90\x89\x8e\xf0\x90\x89\x8f\xf0\x90\x89\x90\xf0\x90\x89\x91\xf0\x90\x89\x92\xf0\x90\x89\x93\xf0\x90\x89\x94\xf0\x90\x89\x95\xf0\x90\x89\x96\xf0\x90\x89\x97\xf0\x90\x89\x98\xf0\x90\x89\x99\xf0\x90\x89\x9a\xf0\x90\x89\x9b\xf0\x90\x89\x9c\xf0\x90\x89\x9d\xf0\x90\x89\x9e\xf0\x90\x89\x9f\xf0\x90\x89\xa0\xf0\x90\x89\xa1\xf0\x90\x89\xa2" + "\xf0\x90\x89\xa3\xf0\x90\x89\xa4\xf0\x90\x89\xa5\xf0\x90\x89\xa6\xf0\x90\x89\xa7\xf0\x90\x89\xa8\xf0\x90\x89\xa9\xf0\x90\x89\xaa\xf0\x90\x89\xab\xf0\x90\x89\xac\xf0\x90\x89\xad\xf0\x90\x89\xae\xf0\x90\x89\xaf\xf0\x90\x89\xb0\xf0\x90\x89\xb1\xf0\x90\x89\xb2\xf0\x90\x89\xb3\xf0\x90\x89\xb4\xf0\x90\x89\xb5\xf0\x90\x89\xb6\xf0\x90\x89\xb7\xf0\x90\x89\xb8\xf0\x90\x89\xb9\xf0\x90\x89\xba"; +} diff --git a/Editor/Resource/Icons/Tabler/LICENSE b/Editor/Resource/Icons/Tabler/LICENSE new file mode 100644 index 000000000..3e82379da --- /dev/null +++ b/Editor/Resource/Icons/Tabler/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020-2026 Paweł Kuna + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Editor/Resource/Icons/Tabler/README.md b/Editor/Resource/Icons/Tabler/README.md new file mode 100644 index 000000000..86df189f1 --- /dev/null +++ b/Editor/Resource/Icons/Tabler/README.md @@ -0,0 +1,12 @@ +# Tabler Icons + +This directory contains the official Tabler Icons v3.45.0 outline webfont from +[`@tabler/icons-webfont`](https://www.npmjs.com/package/@tabler/icons-webfont). + +`tabler-icons.ttf` is copied without modification from `dist/fonts/tabler-icons.ttf` in the upstream package. The editor loads +the complete icon set into the ImGui font atlas. + +`TablerIcons.h` is generated from the matching upstream CSS by +[`tabler.py`](../../../../Tool/Scripts/IconFontGenerator/tabler.py). + +Tabler Icons is distributed under the [MIT License](LICENSE). diff --git a/Editor/Resource/Icons/Tabler/tabler-icons.ttf b/Editor/Resource/Icons/Tabler/tabler-icons.ttf new file mode 100644 index 000000000..706053581 Binary files /dev/null and b/Editor/Resource/Icons/Tabler/tabler-icons.ttf differ diff --git a/Editor/Src/EditorApplication.cpp b/Editor/Src/EditorApplication.cpp index c7873ec28..19bda7bd9 100644 --- a/Editor/Src/EditorApplication.cpp +++ b/Editor/Src/EditorApplication.cpp @@ -10,11 +10,13 @@ #include #include +#include #include #include #include #include #include +#include #include namespace Editor::Internal { @@ -82,6 +84,24 @@ namespace Editor::Internal { style.TabRounding = 2.0f; } + static void LoadIconFonts(ImFontAtlas& inFontAtlas, float inSizePixels) + { + static ImVector glyphRanges; + if (glyphRanges.empty()) { + ImFontGlyphRangesBuilder builder; + builder.AddText(Icons::Tabler::allGlyphs); + builder.BuildRanges(&glyphRanges); + } + + const std::string fontPath = (Core::Paths::EngineResDir() / "Editor" / "Icons" / "Tabler" / "tabler-icons.ttf").String(); + ImFontConfig config; + config.MergeMode = true; + config.PixelSnapH = true; + config.GlyphMinAdvanceX = inSizePixels; + config.GlyphMaxAdvanceX = inSizePixels; + Assert(inFontAtlas.AddFontFromFileTTF(fontPath.c_str(), inSizePixels, &config, glyphRanges.Data) != nullptr); + } + static float CalculatePanelRatio(float inAvailableSize, float inDefaultRatio, float inMinSize, float inMaxSize) { if (inAvailableSize <= 0.0f) { @@ -223,6 +243,7 @@ namespace Editor { ImFontConfig defaultFontConfig; defaultFontConfig.SizePixels = Internal::defaultFontSize; io.FontDefault = io.Fonts->AddFontDefaultVector(&defaultFontConfig); + Internal::LoadIconFonts(*io.Fonts, Internal::defaultFontSize); Internal::SetDarkStyle(); } diff --git a/Editor/Src/Frame/EditorFrame.cpp b/Editor/Src/Frame/EditorFrame.cpp index f03449777..9c0844448 100644 --- a/Editor/Src/Frame/EditorFrame.cpp +++ b/Editor/Src/Frame/EditorFrame.cpp @@ -15,7 +15,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -101,22 +103,30 @@ namespace Editor { if (!ImGui::BeginMainMenuBar()) { return; } - if (ImGui::BeginMenu("File")) { - if (ImGui::MenuItem("Save Level", "Ctrl+S")) { + const std::string fileMenuLabel = Widgets::Label(Icons::Tabler::file, "File"); + if (ImGui::BeginMenu(fileMenuLabel.c_str())) { + const std::string saveLevelLabel = Widgets::Label(Icons::Tabler::deviceFloppy, "Save Level"); + if (ImGui::MenuItem(saveLevelLabel.c_str(), "Ctrl+S")) { inContext.GetSceneClient().SaveLevel(); } ImGui::Separator(); - if (ImGui::MenuItem("Exit")) { + const std::string exitLabel = Widgets::Label(Icons::Tabler::doorExit, "Exit"); + if (ImGui::MenuItem(exitLabel.c_str())) { outRequestQuit = true; } ImGui::EndMenu(); } - if (ImGui::BeginMenu("View")) { - ImGui::MenuItem(PanelNames::scene, nullptr, &tabVisibility.scene); - ImGui::MenuItem(PanelNames::outliner, nullptr, &tabVisibility.outliner); - ImGui::MenuItem(PanelNames::inspector, nullptr, &tabVisibility.inspector); + const std::string viewMenuLabel = Widgets::Label(Icons::Tabler::layoutDashboard, "View"); + if (ImGui::BeginMenu(viewMenuLabel.c_str())) { + const std::string sceneLabel = Widgets::Label(Icons::Tabler::viewportWide, PanelNames::scene); + ImGui::MenuItem(sceneLabel.c_str(), nullptr, &tabVisibility.scene); + const std::string outlinerLabel = Widgets::Label(Icons::Tabler::hierarchy2, PanelNames::outliner); + ImGui::MenuItem(outlinerLabel.c_str(), nullptr, &tabVisibility.outliner); + const std::string inspectorLabel = Widgets::Label(Icons::Tabler::adjustmentsHorizontal, PanelNames::inspector); + ImGui::MenuItem(inspectorLabel.c_str(), nullptr, &tabVisibility.inspector); panels.RenderViewMenuItems(); - ImGui::MenuItem(PanelNames::log, nullptr, &tabVisibility.log); + const std::string logLabel = Widgets::Label(Icons::Tabler::terminal2, PanelNames::log); + ImGui::MenuItem(logLabel.c_str(), nullptr, &tabVisibility.log); ImGui::EndMenu(); } ImGui::EndMainMenuBar(); @@ -124,9 +134,10 @@ namespace Editor { void EditorFrame::RenderSceneTab(EditorContext& inContext, Runtime::Canvas& inSceneRenderCanvas, bool& inOutOpen) { + static const std::string label = Widgets::Label(Icons::Tabler::viewportWide, PanelNames::scene, PanelNames::scene); ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f)); auto& sceneClient = inContext.GetSceneClient(); - if (ImGui::Begin(PanelNames::scene, &inOutOpen, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse)) { + if (ImGui::Begin(label.c_str(), &inOutOpen, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse)) { ImVec2 sceneSize = ImGui::GetContentRegionAvail(); sceneSize.x = std::max(sceneSize.x, 1.0f); sceneSize.y = std::max(sceneSize.y, 1.0f); @@ -148,18 +159,21 @@ namespace Editor { void EditorFrame::RenderOutlinerTab(EditorContext& inContext, Runtime::ECRegistry& inRegistry, bool& inOutOpen) { - if (!ImGui::Begin(PanelNames::outliner, &inOutOpen)) { + static const std::string label = Widgets::Label(Icons::Tabler::hierarchy2, PanelNames::outliner, PanelNames::outliner); + if (!ImGui::Begin(label.c_str(), &inOutOpen)) { ImGui::End(); return; } - if (ImGui::Button("New Entity")) { + const std::string newEntityLabel = Widgets::Label(Icons::Tabler::plus, "New Entity"); + if (ImGui::Button(newEntityLabel.c_str())) { ImGui::OpenPopup("NewEntityMenu"); } ImGui::SetNextWindowSize(ImVec2(260.0f, 0.0f), ImGuiCond_Appearing); if (ImGui::BeginPopup("NewEntityMenu")) { ImGui::SetNextItemWidth(-1.0f); ImGui::InputText("##EntityName", &createEntityName); - if (ImGui::Button("Create", ImVec2(ImGui::GetContentRegionAvail().x, 0.0f))) { + const std::string createLabel = Widgets::Label(Icons::Tabler::check, "Create"); + if (ImGui::Button(createLabel.c_str(), ImVec2(ImGui::GetContentRegionAvail().x, 0.0f))) { const auto entity = inContext.CreateEntity(inRegistry, createEntityName); inContext.SetSelectedEntity(entity); ImGui::CloseCurrentPopup(); @@ -173,7 +187,7 @@ namespace Editor { if (inRegistry.Has(entity)) { return; } - const std::string label = Internal::EntityDisplayName(inRegistry, entity); + const std::string label = Widgets::Label(Icons::Tabler::box, Internal::EntityDisplayName(inRegistry, entity)); const bool selected = inContext.GetSelectedEntity() == entity; ImGui::PushID(static_cast(entity)); if (ImGui::Selectable(label.c_str(), selected)) { @@ -181,7 +195,8 @@ namespace Editor { } if (ImGui::BeginPopupContextItem("EntityMenu")) { inContext.SetSelectedEntity(entity); - if (ImGui::MenuItem("Delete")) { + const std::string deleteLabel = Widgets::Label(Icons::Tabler::trash, "Delete"); + if (ImGui::MenuItem(deleteLabel.c_str())) { entityToDelete = entity; } ImGui::EndPopup(); @@ -196,7 +211,8 @@ namespace Editor { void EditorFrame::RenderInspectorTab(EditorContext& inContext, Runtime::ECRegistry& inRegistry, bool& inOutOpen) { - if (!ImGui::Begin(PanelNames::inspector, &inOutOpen)) { + static const std::string label = Widgets::Label(Icons::Tabler::adjustmentsHorizontal, PanelNames::inspector, PanelNames::inspector); + if (!ImGui::Begin(label.c_str(), &inOutOpen)) { ImGui::End(); return; } @@ -216,7 +232,8 @@ namespace Editor { } ImGui::BeginDisabled(addableComponents.empty()); - if (ImGui::Button("Add Component")) { + const std::string addComponentLabel = Widgets::Label(Icons::Tabler::plus, "Add Component"); + if (ImGui::Button(addComponentLabel.c_str())) { ImGui::OpenPopup("AddComponentMenu"); } ImGui::EndDisabled(); @@ -224,7 +241,8 @@ namespace Editor { for (const auto* clazz : addableComponents) { const std::string componentName = Internal::ComponentDisplayName(*clazz); ImGui::PushID(clazz->GetName().c_str()); - if (ImGui::MenuItem(componentName.c_str())) { + const std::string componentLabel = Widgets::Label(Icons::Tabler::boxMultiple, componentName); + if (ImGui::MenuItem(componentLabel.c_str())) { inContext.AddComponent(inRegistry, selectedEntity, clazz); } ImGui::PopID(); @@ -237,9 +255,11 @@ namespace Editor { inRegistry.CompEach(selectedEntity, [&](Runtime::CompClass compClass) -> void { ImGui::PushID(compClass->GetName().c_str()); const std::string componentName = Internal::ComponentDisplayName(*compClass); - const bool open = ImGui::CollapsingHeader(componentName.c_str(), ImGuiTreeNodeFlags_DefaultOpen); + const std::string componentLabel = Widgets::Label(Icons::Tabler::boxMultiple, componentName); + const bool open = ImGui::CollapsingHeader(componentLabel.c_str(), ImGuiTreeNodeFlags_DefaultOpen); if (inContext.CanRemoveComponent(inRegistry, selectedEntity, compClass) && ImGui::BeginPopupContextItem("ComponentMenu")) { - if (ImGui::MenuItem("Remove")) { + const std::string removeLabel = Widgets::Label(Icons::Tabler::trash, "Remove"); + if (ImGui::MenuItem(removeLabel.c_str())) { componentToRemove = compClass; } ImGui::EndPopup(); @@ -259,9 +279,11 @@ namespace Editor { inRegistry.TagEach(selectedEntity, [&](Runtime::TagClass tagClass) -> void { ImGui::PushID(tagClass->GetName().c_str()); const std::string tagName = Internal::ComponentDisplayName(*tagClass); - ImGui::TextUnformatted(tagName.c_str()); + const std::string tagLabel = Widgets::Label(Icons::Tabler::box, tagName); + ImGui::TextUnformatted(tagLabel.c_str()); if (inContext.CanRemoveComponent(inRegistry, selectedEntity, tagClass) && ImGui::BeginPopupContextItem("ComponentMenu")) { - if (ImGui::MenuItem("Remove")) { + const std::string removeLabel = Widgets::Label(Icons::Tabler::trash, "Remove"); + if (ImGui::MenuItem(removeLabel.c_str())) { componentToRemove = tagClass; } ImGui::EndPopup(); @@ -277,12 +299,14 @@ namespace Editor { void EditorFrame::RenderLogTab(bool& inOutOpen) { - if (!ImGui::Begin(PanelNames::log, &inOutOpen)) { + static const std::string label = Widgets::Label(Icons::Tabler::terminal2, PanelNames::log, PanelNames::log); + if (!ImGui::Begin(label.c_str(), &inOutOpen)) { ImGui::End(); return; } const auto entries = EditorLogStream::Get().Snapshot(); - if (ImGui::Button("Copy")) { + const std::string copyLabel = Widgets::Label(Icons::Tabler::copy, "Copy"); + if (ImGui::Button(copyLabel.c_str())) { std::string text; for (const auto& entry : entries) { text += std::format("[{}][{}][{}] {}\n", entry.time, Internal::LevelString(entry.level), entry.tag, entry.content); @@ -293,13 +317,16 @@ namespace Editor { ImGui::BeginChild("LogEntries", ImVec2(0.0f, 0.0f), false, ImGuiWindowFlags_HorizontalScrollbar); for (const auto& entry : entries) { ImVec4 color = ImGui::GetStyleColorVec4(ImGuiCol_Text); + const char* levelIcon = Icons::Tabler::infoCircle; if (entry.level == Core::LogLevel::warning) { color = ImVec4(1.0f, 0.78f, 0.25f, 1.0f); + levelIcon = Icons::Tabler::alertTriangle; } else if (entry.level == Core::LogLevel::error) { color = ImVec4(1.0f, 0.35f, 0.32f, 1.0f); + levelIcon = Icons::Tabler::circleX; } ImGui::PushStyleColor(ImGuiCol_Text, color); - ImGui::TextUnformatted(std::format("[{}][{}][{}] {}", entry.time, Internal::LevelString(entry.level), entry.tag, entry.content).c_str()); + ImGui::TextUnformatted(std::format("{} [{}][{}][{}] {}", levelIcon, entry.time, Internal::LevelString(entry.level), entry.tag, entry.content).c_str()); ImGui::PopStyleColor(); } if (ImGui::GetScrollY() >= ImGui::GetScrollMaxY()) { diff --git a/Editor/Src/Frame/ProjectHubFrame.cpp b/Editor/Src/Frame/ProjectHubFrame.cpp index 4f265575d..ff3d76890 100644 --- a/Editor/Src/Frame/ProjectHubFrame.cpp +++ b/Editor/Src/Frame/ProjectHubFrame.cpp @@ -19,6 +19,8 @@ #include #include #include +#include +#include namespace Editor::ProjectHub::Internal { constexpr std::string_view templateFileExtension = ".tpl"; @@ -56,11 +58,12 @@ namespace Editor::ProjectHub::Internal { ImDrawList* drawList = ImGui::GetWindowDrawList(); drawList->AddRectFilled(cardMin, cardMax, ImGui::GetColorU32(hovered ? cardHovered : cardBackground), 8.0f); - drawList->PushClipRect(ImVec2(cardMin.x + 16.0f, cardMin.y), ImVec2(cardMax.x - 38.0f, cardMax.y), true); - drawList->AddText(ImVec2(cardMin.x + 16.0f, cardMin.y + 13.0f), ImGui::GetColorU32(ImGuiCol_Text), inProject.name.c_str()); - drawList->AddText(ImVec2(cardMin.x + 16.0f, cardMin.y + 38.0f), ImGui::GetColorU32(ImGuiCol_TextDisabled), inProject.path.c_str()); + drawList->AddText(ImVec2(cardMin.x + 16.0f, cardMin.y + 26.0f), ImGui::GetColorU32(accent), Icons::Tabler::folder); + drawList->PushClipRect(ImVec2(cardMin.x + 46.0f, cardMin.y), ImVec2(cardMax.x - 38.0f, cardMax.y), true); + drawList->AddText(ImVec2(cardMin.x + 46.0f, cardMin.y + 13.0f), ImGui::GetColorU32(ImGuiCol_Text), inProject.name.c_str()); + drawList->AddText(ImVec2(cardMin.x + 46.0f, cardMin.y + 38.0f), ImGui::GetColorU32(ImGuiCol_TextDisabled), inProject.path.c_str()); drawList->PopClipRect(); - drawList->AddText(ImVec2(cardMax.x - 25.0f, cardMin.y + 25.0f), ImGui::GetColorU32(ImGuiCol_TextDisabled), ">"); + drawList->AddText(ImVec2(cardMax.x - 25.0f, cardMin.y + 26.0f), ImGui::GetColorU32(ImGuiCol_TextDisabled), Icons::Tabler::chevronRight); ImGui::PopID(); return ImGui::IsItemClicked(); @@ -171,14 +174,16 @@ namespace Editor { { const float spacing = ImGui::GetStyle().ItemSpacing.x; const float buttonWidth = (ImGui::GetContentRegionAvail().x - spacing) * 0.5f; - if (ProjectHub::Internal::RenderActionButton("Open", ImVec2(buttonWidth, ProjectHub::Internal::actionButtonHeight), ProjectHub::Internal::accent, ProjectHub::Internal::accentHovered)) { + const std::string openLabel = Widgets::Label(Icons::Tabler::folderOpen, "Open"); + if (ProjectHub::Internal::RenderActionButton(openLabel.c_str(), ImVec2(buttonWidth, ProjectHub::Internal::actionButtonHeight), ProjectHub::Internal::accent, ProjectHub::Internal::accentHovered)) { if (const auto selectedDirectory = PlatformUtils::SelectDirectory("Open Explosion Project")) { OpenProject(inWindow, *selectedDirectory, inRhiType); } } ImGui::SameLine(); - if (ProjectHub::Internal::RenderActionButton("Create", ImVec2(buttonWidth, ProjectHub::Internal::actionButtonHeight), ProjectHub::Internal::secondaryButton, ProjectHub::Internal::secondaryButtonHovered)) { + const std::string createLabel = Widgets::Label(Icons::Tabler::plus, "Create"); + if (ProjectHub::Internal::RenderActionButton(createLabel.c_str(), ImVec2(buttonWidth, ProjectHub::Internal::actionButtonHeight), ProjectHub::Internal::secondaryButton, ProjectHub::Internal::secondaryButtonHovered)) { statusMessage.clear(); ImGui::OpenPopup("##CreateProjectPopup"); } @@ -186,15 +191,17 @@ namespace Editor { void ProjectHubFrame::RenderRecentProjects(EditorWindow& inWindow, const std::string& inRhiType) { - ImGui::TextUnformatted("Recent projects"); + const std::string recentProjectsLabel = Widgets::Label(Icons::Tabler::folder, "Recent projects"); + ImGui::TextUnformatted(recentProjectsLabel.c_str()); const std::string projectCount = std::to_string(recentProjects.size()); ImGui::SameLine(ImGui::GetContentRegionMax().x - ImGui::CalcTextSize(projectCount.c_str()).x); ImGui::TextDisabled("%s", projectCount.c_str()); ImGui::Dummy(ImVec2(0.0f, 7.0f)); if (!statusMessage.empty()) { + const std::string statusLabel = Widgets::Label(Icons::Tabler::circleX, statusMessage); ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.42f, 0.42f, 1.0f)); - ImGui::TextWrapped("%s", statusMessage.c_str()); + ImGui::TextWrapped("%s", statusLabel.c_str()); ImGui::PopStyleColor(); ImGui::Dummy(ImVec2(0.0f, 7.0f)); } @@ -214,8 +221,9 @@ namespace Editor { ImGui::GetWindowDrawList()->AddRectFilled(emptyMin, emptyMax, ImGui::GetColorU32(ProjectHub::Internal::cardBackground), 8.0f); const char* title = "No recent projects"; const char* description = "Open an existing project or create a new one."; - ImGui::GetWindowDrawList()->AddText(ImVec2(emptyMin.x + 16.0f, emptyMin.y + 31.0f), ImGui::GetColorU32(ImGuiCol_Text), title); - ImGui::GetWindowDrawList()->AddText(ImVec2(emptyMin.x + 16.0f, emptyMin.y + 59.0f), ImGui::GetColorU32(ImGuiCol_TextDisabled), description); + ImGui::GetWindowDrawList()->AddText(ImVec2(emptyMin.x + 16.0f, emptyMin.y + 51.0f), ImGui::GetColorU32(ProjectHub::Internal::accent), Icons::Tabler::folderOff); + ImGui::GetWindowDrawList()->AddText(ImVec2(emptyMin.x + 46.0f, emptyMin.y + 31.0f), ImGui::GetColorU32(ImGuiCol_Text), title); + ImGui::GetWindowDrawList()->AddText(ImVec2(emptyMin.x + 46.0f, emptyMin.y + 59.0f), ImGui::GetColorU32(ImGuiCol_TextDisabled), description); ImGui::Dummy(ImVec2(0.0f, 118.0f)); } ImGui::EndChild(); @@ -236,7 +244,8 @@ namespace Editor { ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f); ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 6.0f); if (ImGui::BeginPopupModal("##CreateProjectPopup", nullptr, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings)) { - ImGui::TextUnformatted("Create project"); + const std::string createProjectLabel = Widgets::Label(Icons::Tabler::templateIcon, "Create project"); + ImGui::TextUnformatted(createProjectLabel.c_str()); ImGui::TextDisabled("Start from a template and open it right away."); ImGui::Dummy(ImVec2(0.0f, 13.0f)); @@ -250,7 +259,8 @@ namespace Editor { ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - browseButtonWidth - ImGui::GetStyle().ItemSpacing.x); ImGui::InputTextWithHint("##ProjectDirectory", "Choose a parent folder", &directory); ImGui::SameLine(); - if (ImGui::Button("Browse", ImVec2(browseButtonWidth, 0.0f))) { + const std::string browseLabel = Widgets::Label(Icons::Tabler::folderOpen, "Browse"); + if (ImGui::Button(browseLabel.c_str(), ImVec2(browseButtonWidth, 0.0f))) { if (const auto selectedDirectory = PlatformUtils::SelectDirectory("Choose Project Location", directory)) { directory = *selectedDirectory; } @@ -265,7 +275,8 @@ namespace Editor { if (ImGui::BeginCombo("##ProjectTemplate", selectedTemplate)) { for (int i = 0; i < static_cast(projectTemplates.size()); i++) { const bool selected = i == selectedTemplateIndex; - if (ImGui::Selectable(projectTemplates[i].name.c_str(), selected)) { + const std::string templateLabel = Widgets::Label(Icons::Tabler::templateIcon, projectTemplates[i].name); + if (ImGui::Selectable(templateLabel.c_str(), selected)) { selectedTemplateIndex = i; } if (selected) { @@ -277,20 +288,23 @@ namespace Editor { if (!statusMessage.empty()) { ImGui::Dummy(ImVec2(0.0f, 9.0f)); + const std::string statusLabel = Widgets::Label(Icons::Tabler::circleX, statusMessage); ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.42f, 0.42f, 1.0f)); - ImGui::TextWrapped("%s", statusMessage.c_str()); + ImGui::TextWrapped("%s", statusLabel.c_str()); ImGui::PopStyleColor(); } ImGui::Dummy(ImVec2(0.0f, 15.0f)); const float footerWidth = 178.0f; ImGui::SetCursorPosX(ImGui::GetContentRegionMax().x - footerWidth); - if (ImGui::Button("Cancel", ImVec2(82.0f, 36.0f))) { + const std::string cancelLabel = Widgets::Label(Icons::Tabler::x, "Cancel"); + if (ImGui::Button(cancelLabel.c_str(), ImVec2(82.0f, 36.0f))) { statusMessage.clear(); ImGui::CloseCurrentPopup(); } ImGui::SameLine(); - if (ProjectHub::Internal::RenderActionButton("Create##Confirm", ImVec2(88.0f, 36.0f), ProjectHub::Internal::accent, ProjectHub::Internal::accentHovered)) { + const std::string confirmLabel = Widgets::Label(Icons::Tabler::check, "Create##Confirm"); + if (ProjectHub::Internal::RenderActionButton(confirmLabel.c_str(), ImVec2(88.0f, 36.0f), ProjectHub::Internal::accent, ProjectHub::Internal::accentHovered)) { const CreateProjectResult result = CreateProject(); if (result.success) { statusMessage.clear(); diff --git a/Editor/Src/Panel/AssetsPanel.cpp b/Editor/Src/Panel/AssetsPanel.cpp index bb6021993..1578442a9 100644 --- a/Editor/Src/Panel/AssetsPanel.cpp +++ b/Editor/Src/Panel/AssetsPanel.cpp @@ -14,6 +14,8 @@ #include #include #include +#include +#include namespace Editor::Internal { constexpr float assetsFolderTreeWidth = 220.0f; @@ -65,7 +67,8 @@ namespace Editor { void AssetsPanel::Render(bool& inOutOpen) { - if (!ImGui::Begin(PanelNames::assets, &inOutOpen)) { + static const std::string label = Widgets::Label(Icons::Tabler::folder, PanelNames::assets, PanelNames::assets); + if (!ImGui::Begin(label.c_str(), &inOutOpen)) { ImGui::End(); return; } @@ -89,8 +92,9 @@ namespace Editor { const ImVec4 color = statusIsError ? ImVec4(1.0f, 0.35f, 0.32f, 1.0f) : ImGui::GetStyleColorVec4(ImGuiCol_TextDisabled); + const std::string statusLabel = Widgets::Label(statusIsError ? Icons::Tabler::circleX : Icons::Tabler::infoCircle, statusMessage); ImGui::PushStyleColor(ImGuiCol_Text, color); - ImGui::TextWrapped("%s", statusMessage.c_str()); + ImGui::TextWrapped("%s", statusLabel.c_str()); ImGui::PopStyleColor(); } ImGui::Separator(); @@ -111,42 +115,42 @@ namespace Editor { { const bool atRoot = currentDirectory == fileSystem.Root(); ImGui::BeginDisabled(atRoot); - if (ImGui::Button("Up")) { + if (Widgets::IconButton("Up", Icons::Tabler::arrowUp, "Up (Backspace)")) { NavigateTo(currentDirectory.parent_path()); } ImGui::EndDisabled(); ImGui::SameLine(); - if (ImGui::Button("New Folder")) { + if (Widgets::IconButton("New Folder", Icons::Tabler::folderPlus, "New Folder")) { OpenCreateFolderPopup(); } ImGui::SameLine(); - if (ImGui::Button("Import")) { + if (Widgets::IconButton("Import", Icons::Tabler::upload, "Import")) { ImportFiles(); } ImGui::SameLine(); const bool hasSelection = !selectedPath.empty(); ImGui::BeginDisabled(!hasSelection); - if (ImGui::Button("Cut")) { + if (Widgets::IconButton("Cut", Icons::Tabler::cut, "Cut (Ctrl+X)")) { SetClipboard(selectedPath, ClipboardMode::move); } ImGui::SameLine(); - if (ImGui::Button("Copy")) { + if (Widgets::IconButton("Copy", Icons::Tabler::copy, "Copy (Ctrl+C)")) { SetClipboard(selectedPath, ClipboardMode::copy); } ImGui::SameLine(); - if (ImGui::Button("Rename")) { + if (Widgets::IconButton("Rename", Icons::Tabler::edit, "Rename (F2)")) { OpenRenamePopup(selectedPath); } ImGui::SameLine(); - if (ImGui::Button("Delete")) { + if (Widgets::IconButton("Delete", Icons::Tabler::trash, "Delete")) { OpenDeletePopup(selectedPath); } ImGui::EndDisabled(); ImGui::SameLine(); ImGui::BeginDisabled(clipboardMode == ClipboardMode::none); - if (ImGui::Button("Paste")) { + if (Widgets::IconButton("Paste", Icons::Tabler::clipboard, "Paste (Ctrl+V)")) { PasteInto(currentDirectory); } ImGui::EndDisabled(); @@ -154,7 +158,7 @@ namespace Editor { void AssetsPanel::RenderBreadcrumbs() { - if (ImGui::Button(PanelNames::assets)) { + if (Widgets::IconButton("Asset Root", Icons::Tabler::home, PanelNames::assets)) { NavigateTo(fileSystem.Root()); } @@ -166,7 +170,7 @@ namespace Editor { } accumulated /= component; ImGui::SameLine(); - ImGui::TextUnformatted(">"); + ImGui::TextDisabled("%s", Icons::Tabler::chevronRight); ImGui::SameLine(); const std::string id = accumulated.string(); const std::string label = component.string(); @@ -189,8 +193,9 @@ namespace Editor { } const std::string id = inDirectory.string(); + const std::string label = Widgets::Label(Icons::Tabler::folder, inLabel); ImGui::PushID(id.c_str()); - const bool open = ImGui::TreeNodeEx(inLabel, flags); + const bool open = ImGui::TreeNodeEx(label.c_str(), flags); if (ImGui::IsItemClicked() && !ImGui::IsItemToggledOpen()) { NavigateTo(inDirectory); } @@ -236,12 +241,11 @@ namespace Editor { ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); const std::string pathId = inEntry.path.string(); - const std::string name = inEntry.directory - ? std::format("{}/", inEntry.path.filename().string()) - : inEntry.path.filename().string(); + const std::string name = inEntry.path.filename().string(); + const std::string label = Widgets::Label(inEntry.directory ? Icons::Tabler::folder : Icons::Tabler::file, name); ImGui::PushID(pathId.c_str()); const bool selected = selectedPath == inEntry.path; - if (ImGui::Selectable(name.c_str(), selected, ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowDoubleClick)) { + if (ImGui::Selectable(label.c_str(), selected, ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowDoubleClick)) { selectedPath = inEntry.path; if (inEntry.directory && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) { NavigateTo(inEntry.path); @@ -250,7 +254,7 @@ namespace Editor { if (ImGui::BeginDragDropSource()) { ImGui::SetDragDropPayload(Internal::assetPathPayload, pathId.c_str(), pathId.size() + 1); - ImGui::TextUnformatted(name.c_str()); + ImGui::TextUnformatted(label.c_str()); ImGui::EndDragDropSource(); } if (inEntry.directory) { @@ -258,20 +262,25 @@ namespace Editor { } if (ImGui::BeginPopupContextItem("AssetEntryMenu")) { selectedPath = inEntry.path; - if (ImGui::MenuItem("Open", nullptr, false, inEntry.directory)) { + const std::string openLabel = Widgets::Label(Icons::Tabler::externalLink, "Open"); + if (ImGui::MenuItem(openLabel.c_str(), nullptr, false, inEntry.directory)) { NavigateTo(inEntry.path); } ImGui::Separator(); - if (ImGui::MenuItem("Cut", "Ctrl+X")) { + const std::string cutLabel = Widgets::Label(Icons::Tabler::cut, "Cut"); + if (ImGui::MenuItem(cutLabel.c_str(), "Ctrl+X")) { SetClipboard(inEntry.path, ClipboardMode::move); } - if (ImGui::MenuItem("Copy", "Ctrl+C")) { + const std::string copyLabel = Widgets::Label(Icons::Tabler::copy, "Copy"); + if (ImGui::MenuItem(copyLabel.c_str(), "Ctrl+C")) { SetClipboard(inEntry.path, ClipboardMode::copy); } - if (ImGui::MenuItem("Rename", "F2")) { + const std::string renameLabel = Widgets::Label(Icons::Tabler::edit, "Rename"); + if (ImGui::MenuItem(renameLabel.c_str(), "F2")) { OpenRenamePopup(inEntry.path); } - if (ImGui::MenuItem("Delete", "Delete")) { + const std::string deleteLabel = Widgets::Label(Icons::Tabler::trash, "Delete"); + if (ImGui::MenuItem(deleteLabel.c_str(), "Delete")) { OpenDeletePopup(inEntry.path); } ImGui::EndPopup(); @@ -293,14 +302,17 @@ namespace Editor { if (!ImGui::BeginPopupContextWindow("AssetBackgroundMenu", ImGuiPopupFlags_MouseButtonRight | ImGuiPopupFlags_NoOpenOverItems)) { return; } - if (ImGui::MenuItem("New Folder")) { + const std::string newFolderLabel = Widgets::Label(Icons::Tabler::folderPlus, "New Folder"); + if (ImGui::MenuItem(newFolderLabel.c_str())) { OpenCreateFolderPopup(); } - if (ImGui::MenuItem("Import")) { + const std::string importLabel = Widgets::Label(Icons::Tabler::upload, "Import"); + if (ImGui::MenuItem(importLabel.c_str())) { ImportFiles(); } ImGui::Separator(); - if (ImGui::MenuItem("Paste", "Ctrl+V", false, clipboardMode != ClipboardMode::none)) { + const std::string pasteLabel = Widgets::Label(Icons::Tabler::clipboard, "Paste"); + if (ImGui::MenuItem(pasteLabel.c_str(), "Ctrl+V", false, clipboardMode != ClipboardMode::none)) { PasteInto(currentDirectory); } ImGui::EndPopup(); @@ -318,7 +330,8 @@ namespace Editor { } ImGui::SetNextItemWidth(320.0f); const bool submit = ImGui::InputText("Name", &createFolderName, ImGuiInputTextFlags_EnterReturnsTrue); - if (submit || ImGui::Button("Create")) { + const std::string createLabel = Widgets::Label(Icons::Tabler::check, "Create"); + if (submit || ImGui::Button(createLabel.c_str())) { std::filesystem::path created; std::string error; if (fileSystem.CreateFolder(currentDirectory, createFolderName, created, error)) { @@ -330,7 +343,8 @@ namespace Editor { } } ImGui::SameLine(); - if (ImGui::Button("Cancel")) { + const std::string cancelLabel = Widgets::Label(Icons::Tabler::x, "Cancel"); + if (ImGui::Button(cancelLabel.c_str())) { ImGui::CloseCurrentPopup(); } ImGui::EndPopup(); @@ -346,7 +360,8 @@ namespace Editor { } ImGui::SetNextItemWidth(320.0f); const bool submit = ImGui::InputText("Name", &renameName, ImGuiInputTextFlags_EnterReturnsTrue); - if (submit || ImGui::Button("Rename")) { + const std::string renameLabel = Widgets::Label(Icons::Tabler::edit, "Rename"); + if (submit || ImGui::Button(renameLabel.c_str())) { std::filesystem::path renamed; std::string error; if (fileSystem.Rename(renamePath, renameName, renamed, error)) { @@ -361,7 +376,8 @@ namespace Editor { } } ImGui::SameLine(); - if (ImGui::Button("Cancel")) { + const std::string cancelLabel = Widgets::Label(Icons::Tabler::x, "Cancel"); + if (ImGui::Button(cancelLabel.c_str())) { ImGui::CloseCurrentPopup(); } ImGui::EndPopup(); @@ -373,7 +389,8 @@ namespace Editor { } if (ImGui::BeginPopupModal("Delete Asset", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) { ImGui::TextWrapped("Delete '%s'? This cannot be undone.", deletePath.filename().string().c_str()); - if (ImGui::Button("Delete")) { + const std::string deleteLabel = Widgets::Label(Icons::Tabler::trash, "Delete"); + if (ImGui::Button(deleteLabel.c_str())) { std::string error; if (fileSystem.Remove(deletePath, error)) { if (clipboardPath == deletePath) { @@ -388,7 +405,8 @@ namespace Editor { } } ImGui::SameLine(); - if (ImGui::Button("Cancel")) { + const std::string cancelLabel = Widgets::Label(Icons::Tabler::x, "Cancel"); + if (ImGui::Button(cancelLabel.c_str())) { ImGui::CloseCurrentPopup(); } ImGui::EndPopup(); diff --git a/Editor/Src/Panel/EditorPanels.cpp b/Editor/Src/Panel/EditorPanels.cpp index 75f7a511e..6c895cb53 100644 --- a/Editor/Src/Panel/EditorPanels.cpp +++ b/Editor/Src/Panel/EditorPanels.cpp @@ -6,6 +6,8 @@ #include #include +#include +#include namespace Editor { EditorPanels::EditorPanels() @@ -27,6 +29,7 @@ namespace Editor { void EditorPanels::RenderViewMenuItems() { - ImGui::MenuItem(PanelNames::assets, nullptr, &assetsVisible); + const std::string label = Widgets::Label(Icons::Tabler::folder, PanelNames::assets); + ImGui::MenuItem(label.c_str(), nullptr, &assetsVisible); } } diff --git a/Editor/Src/Widget/IconWidgets.cpp b/Editor/Src/Widget/IconWidgets.cpp new file mode 100644 index 000000000..d4c3a36f5 --- /dev/null +++ b/Editor/Src/Widget/IconWidgets.cpp @@ -0,0 +1,29 @@ +#include + +#include + +#include + +namespace Editor::Widgets { + std::string Label(const char* inIcon, std::string_view inText) + { + return std::format("{} {}", inIcon, inText); + } + + std::string Label(const char* inIcon, std::string_view inText, std::string_view inId) + { + return std::format("{} {}###{}", inIcon, inText, inId); + } + + bool IconButton(const char* inId, const char* inIcon, const char* inTooltip) + { + ImGui::PushID(inId); + const float size = ImGui::GetFrameHeight(); + const bool clicked = ImGui::Button(inIcon, ImVec2(size, size)); + if (inTooltip != nullptr && ImGui::IsItemHovered(ImGuiHoveredFlags_DelayShort | ImGuiHoveredFlags_AllowWhenDisabled)) { + ImGui::SetTooltip("%s", inTooltip); + } + ImGui::PopID(); + return clicked; + } +} diff --git a/Engine/Source/Common/Benchmark/Math/MathBenchmark.cpp b/Engine/Source/Common/Benchmark/Math/MathBenchmark.cpp index 0e0fabb57..1d9ab28ab 100644 --- a/Engine/Source/Common/Benchmark/Math/MathBenchmark.cpp +++ b/Engine/Source/Common/Benchmark/Math/MathBenchmark.cpp @@ -10,6 +10,9 @@ #include #include #include +#include +#include +#include using namespace Common; @@ -96,6 +99,20 @@ namespace { } return result; } + + std::vector MakeRandomTransforms(const size_t count) + { + const auto raw = MakeRandomFloats(count * 9); + std::vector result(count); + for (size_t i = 0; i < count; i++) { + const float* p = &raw[i * 9]; + result[i] = FTransform( + FVec3(p[0], p[1], p[2]), + FQuat::FromEulerZYX(p[3] * 90.0f, p[4] * 90.0f, p[5] * 90.0f), + FVec3(p[6], p[7], p[8])); + } + return result; + } } template @@ -191,6 +208,23 @@ static void Mat4InverseBatch(benchmark::State& state) BENCHMARK(Mat4InverseBatch); BENCHMARK(Mat4InverseBatch); +template +static void Mat4InverseUncheckedBatch(benchmark::State& state) +{ + const auto a = MakeRandomMats(batchSize); + std::vector> c(batchSize); + for (auto _ : state) { + for (int i = 0; i < batchSize; i++) { + c[i] = a[i].InverseUnchecked(); + } + benchmark::DoNotOptimize(c.data()); + benchmark::ClobberMemory(); + } + state.SetItemsProcessed(state.iterations() * batchSize); +} +BENCHMARK(Mat4InverseUncheckedBatch); +BENCHMARK(Mat4InverseUncheckedBatch); + template static void Mat3MulBatch(benchmark::State& state) { @@ -226,3 +260,154 @@ static void Mat3MulVecBatch(benchmark::State& state) } BENCHMARK(Mat3MulVecBatch); BENCHMARK(Mat3MulVecBatch); + +template +static void VecNormalizeBatch(benchmark::State& state) +{ + const auto input = MakeRandomVecs(batchSize); + std::vector> output(batchSize); + for (auto _ : state) { + for (int i = 0; i < batchSize; i++) { + output[i] = input[i].Normalized(); + } + benchmark::DoNotOptimize(output.data()); + benchmark::ClobberMemory(); + } + state.SetItemsProcessed(state.iterations() * batchSize); +} +BENCHMARK(VecNormalizeBatch); +BENCHMARK(VecNormalizeBatch); + +static void TransformMatrixComposedBatch(benchmark::State& state) +{ + const auto input = MakeRandomTransforms(batchSize); + std::vector output(batchSize); + for (auto _ : state) { + for (int i = 0; i < batchSize; i++) { + output[i] = input[i].GetTranslationMatrix() * input[i].GetRotationMatrix() * input[i].GetScaleMatrix(); + } + benchmark::DoNotOptimize(output.data()); + benchmark::ClobberMemory(); + } + state.SetItemsProcessed(state.iterations() * batchSize); +} +BENCHMARK(TransformMatrixComposedBatch); + +static void TransformMatrixDirectBatch(benchmark::State& state) +{ + const auto input = MakeRandomTransforms(batchSize); + std::vector output(batchSize); + for (auto _ : state) { + for (int i = 0; i < batchSize; i++) { + output[i] = input[i].GetTransformMatrix(); + } + benchmark::DoNotOptimize(output.data()); + benchmark::ClobberMemory(); + } + state.SetItemsProcessed(state.iterations() * batchSize); +} +BENCHMARK(TransformMatrixDirectBatch); + +static void TransformPositionMatrixBatch(benchmark::State& state) +{ + const auto transforms = MakeRandomTransforms(batchSize); + const auto positions = MakeRandomVec3s(batchSize); + std::vector output(batchSize); + for (auto _ : state) { + for (int i = 0; i < batchSize; i++) { + output[i] = (transforms[i].GetTransformMatrix() * FVec4(positions[i].x, positions[i].y, positions[i].z, 1)).SubVec<0, 1, 2>(); + } + benchmark::DoNotOptimize(output.data()); + benchmark::ClobberMemory(); + } + state.SetItemsProcessed(state.iterations() * batchSize); +} +BENCHMARK(TransformPositionMatrixBatch); + +static void TransformPositionDirectBatch(benchmark::State& state) +{ + const auto transforms = MakeRandomTransforms(batchSize); + const auto positions = MakeRandomVec3s(batchSize); + std::vector output(batchSize); + for (auto _ : state) { + for (int i = 0; i < batchSize; i++) { + output[i] = transforms[i].TransformPosition(positions[i]); + } + benchmark::DoNotOptimize(output.data()); + benchmark::ClobberMemory(); + } + state.SetItemsProcessed(state.iterations() * batchSize); +} +BENCHMARK(TransformPositionDirectBatch); + +static void ViewMatrixGenericBatch(benchmark::State& state) +{ + const auto transforms = MakeRandomTransforms(batchSize); + const FMat4x4 axisTransform( + 0, 1, 0, 0, + 0, 0, 1, 0, + 1, 0, 0, 0, + 0, 0, 0, 1); + std::vector output(batchSize); + for (auto _ : state) { + for (int i = 0; i < batchSize; i++) { + const FViewTransform view(transforms[i]); + output[i] = axisTransform * view.GetTransformMatrixNoScale().InverseUnchecked(); + } + benchmark::DoNotOptimize(output.data()); + benchmark::ClobberMemory(); + } + state.SetItemsProcessed(state.iterations() * batchSize); +} +BENCHMARK(ViewMatrixGenericBatch); + +static void ViewMatrixDirectBatch(benchmark::State& state) +{ + const auto transforms = MakeRandomTransforms(batchSize); + std::vector output(batchSize); + for (auto _ : state) { + for (int i = 0; i < batchSize; i++) { + output[i] = FViewTransform(transforms[i]).GetViewMatrix(); + } + benchmark::DoNotOptimize(output.data()); + benchmark::ClobberMemory(); + } + state.SetItemsProcessed(state.iterations() * batchSize); +} +BENCHMARK(ViewMatrixDirectBatch); + +static void SphereInsideBatch(benchmark::State& state) +{ + const auto centers = MakeRandomVec3s(batchSize); + const auto points = MakeRandomVec3s(batchSize); + std::vector spheres(batchSize); + for (int i = 0; i < batchSize; i++) { + spheres[i] = FSphere(centers[i], 1.0f); + } + for (auto _ : state) { + size_t insideCount = 0; + for (int i = 0; i < batchSize; i++) { + insideCount += spheres[i].Inside(points[i]); + } + benchmark::DoNotOptimize(insideCount); + } + state.SetItemsProcessed(state.iterations() * batchSize); +} +BENCHMARK(SphereInsideBatch); + +static void HalfConvertBatch(benchmark::State& state) +{ + const auto input = MakeRandomFloats(batchSize); + std::vector half(batchSize); + std::vector output(batchSize); + for (auto _ : state) { + for (int i = 0; i < batchSize; i++) { + half[i] = input[i]; + output[i] = half[i].AsFloat(); + } + benchmark::DoNotOptimize(output.data()); + benchmark::ClobberMemory(); + } + state.SetItemsProcessed(state.iterations() * batchSize); +} +BENCHMARK(HalfConvertBatch); diff --git a/Engine/Source/Common/Include/Common/Math/Adapters.h b/Engine/Source/Common/Include/Common/Math/Adapters.h new file mode 100644 index 000000000..416ae1dac --- /dev/null +++ b/Engine/Source/Common/Include/Common/Math/Adapters.h @@ -0,0 +1,901 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Common { + template + struct Serializer> { + static constexpr size_t typeId = HashUtils::StrCrc32("Common::Internal::HalfFloat"); + + static size_t Serialize(BinarySerializeStream& stream, const HalfFloat& value) + { + return Serializer::Serialize(stream, value.value); + } + + static size_t Deserialize(BinaryDeserializeStream& stream, HalfFloat& value) + { + return Serializer::Deserialize(stream, value.value); + } + }; + + template + struct StringConverter> { + static std::string ToString(const HalfFloat& inValue) + { + return StringConverter::ToString(inValue.AsFloat()); + } + }; + + template + struct JsonSerializer> { + static void JsonSerialize(rapidjson::Value& outJsonValue, rapidjson::Document::AllocatorType& inAllocator, const HalfFloat& inValue) + { + JsonSerializer::JsonSerialize(outJsonValue, inAllocator, inValue.AsFloat()); + } + + static void JsonDeserialize(const rapidjson::Value& inJsonValue, HalfFloat& outValue) + { + float floatValue = 0.0f; + JsonSerializer::JsonDeserialize(inJsonValue, floatValue); + outValue = floatValue; + } + }; + + template + struct Serializer> { + static constexpr size_t typeId = HashUtils::StrCrc32("Common::Vector") + Serializer::typeId + L; + + static size_t Serialize(BinarySerializeStream& stream, const Vec& value) + { + size_t serialized = 0; + for (auto i = 0; i < L; i++) { + serialized += Serializer::Serialize(stream, value.data[i]); + } + return serialized; + } + + static size_t Deserialize(BinaryDeserializeStream& stream, Vec& value) + { + size_t deserialized = 0; + for (auto i = 0; i < L; i++) { + deserialized += Serializer::Deserialize(stream, value.data[i]); + } + return deserialized; + } + }; + + template + struct StringConverter> { + static std::string ToString(const Vec& inValue) + { + std::stringstream stream; + stream << "("; + for (auto i = 0; i < L; i++) { + stream << StringConverter::ToString(inValue.data[i]); + if (i != L - 1) { + stream << ", "; + } + } + stream << ")"; + return stream.str(); + } + }; + + template + struct JsonSerializer> { + static void JsonSerialize(rapidjson::Value& outJsonValue, rapidjson::Document::AllocatorType& inAllocator, const Vec& inValue) + { + outJsonValue.SetArray(); + outJsonValue.Reserve(L, inAllocator); + for (auto i = 0; i < L; i++) { + rapidjson::Value elementJson; + JsonSerializer::JsonSerialize(elementJson, inAllocator, inValue[i]); + outJsonValue.PushBack(elementJson, inAllocator); + } + } + + static void JsonDeserialize(const rapidjson::Value& inJsonValue, Vec& outValue) + { + if (!inJsonValue.IsArray() || inJsonValue.Size() != L) { + return; + } + for (auto i = 0; i < L; i++) { + JsonSerializer::JsonDeserialize(inJsonValue[i], outValue[i]); + } + } + }; + + template + struct Serializer> { + static constexpr size_t typeId = HashUtils::StrCrc32("Common::Matrix") + Serializer::typeId + (R << 8) + C; + + static size_t Serialize(BinarySerializeStream& stream, const Mat& value) + { + size_t serialized = 0; + for (auto i = 0; i < R * C; i++) { + serialized += Serializer::Serialize(stream, value.data[i]); + } + return serialized; + } + + static size_t Deserialize(BinaryDeserializeStream& stream, Mat& value) + { + size_t deserialized = 0; + for (auto i = 0; i < R * C; i++) { + deserialized += Serializer::Deserialize(stream, value.data[i]); + } + return deserialized; + } + }; + + template + struct StringConverter> { + static std::string ToString(const Mat& inValue) + { + std::stringstream stream; + stream << "("; + for (auto i = 0; i < R; i++) { + for (auto j = 0; j < C; j++) { + stream << StringConverter::ToString(inValue.At(i, j)); + if (i * C + j != R * C - 1) { + stream << ", "; + } + } + } + stream << ")"; + return stream.str(); + } + }; + + template + struct JsonSerializer> { + static void JsonSerialize(rapidjson::Value& outJsonValue, rapidjson::Document::AllocatorType& inAllocator, const Mat& inValue) + { + outJsonValue.SetArray(); + outJsonValue.Reserve(R * C, inAllocator); + for (auto i = 0; i < R; i++) { + for (auto j = 0; j < C; j++) { + rapidjson::Value jsonElement; + JsonSerializer::JsonSerialize(jsonElement, inAllocator, inValue.At(i, j)); + outJsonValue.PushBack(jsonElement, inAllocator); + } + } + } + + static void JsonDeserialize(const rapidjson::Value& inJsonValue, Mat& outValue) + { + if (!inJsonValue.IsArray() || inJsonValue.Size() != R * C) { + return; + } + for (auto i = 0; i < inJsonValue.Size(); i++) { + T element; + JsonSerializer::JsonDeserialize(inJsonValue[i], element); + outValue.At(i / C, i % C) = std::move(element); + } + } + }; + + template + struct Serializer> { + static constexpr size_t typeId = HashUtils::StrCrc32("Common::Angle") + Serializer::typeId; + + static size_t Serialize(BinarySerializeStream& stream, const Angle& value) + { + return Serializer::Serialize(stream, value.value); + } + + static size_t Deserialize(BinaryDeserializeStream& stream, Angle& value) + { + return Serializer::Deserialize(stream, value.value); + } + }; + + template + struct Serializer> { + static constexpr size_t typeId = HashUtils::StrCrc32("Common::Radian") + Serializer::typeId; + + static size_t Serialize(BinarySerializeStream& stream, const Radian& value) + { + return Serializer::Serialize(stream, value.value); + } + + static size_t Deserialize(BinaryDeserializeStream& stream, Radian& value) + { + return Serializer::Deserialize(stream, value.value); + } + }; + + template + struct Serializer> { + static constexpr size_t typeId = HashUtils::StrCrc32("Common::Quaternion") + Serializer::typeId; + + static size_t Serialize(BinarySerializeStream& stream, const Quaternion& value) + { + size_t serialized = 0; + serialized += Serializer::Serialize(stream, value.w); + serialized += Serializer::Serialize(stream, value.x); + serialized += Serializer::Serialize(stream, value.y); + serialized += Serializer::Serialize(stream, value.z); + return serialized; + } + + static size_t Deserialize(BinaryDeserializeStream& stream, Quaternion& value) + { + size_t deserialized = 0; + deserialized += Serializer::Deserialize(stream, value.w); + deserialized += Serializer::Deserialize(stream, value.x); + deserialized += Serializer::Deserialize(stream, value.y); + deserialized += Serializer::Deserialize(stream, value.z); + return deserialized; + } + }; + + template + struct StringConverter> { + static std::string ToString(const Angle& inValue) + { + return std::format("a{}", StringConverter::ToString(inValue.value)); + } + }; + + template + struct StringConverter> { + static std::string ToString(const Radian& inValue) + { + return StringConverter::ToString(inValue.value); + } + }; + + template + struct StringConverter> { + static std::string ToString(const Quaternion& inValue) + { + return std::format( + "({}, {}, {}, {})", + StringConverter::ToString(inValue.w), + StringConverter::ToString(inValue.x), + StringConverter::ToString(inValue.y), + StringConverter::ToString(inValue.z)); + } + }; + + template + struct JsonSerializer> { + static void JsonSerialize(rapidjson::Value& outJsonValue, rapidjson::Document::AllocatorType& inAllocator, const Angle& inValue) + { + JsonSerializer::JsonSerialize(outJsonValue, inAllocator, inValue.value); + } + + static void JsonDeserialize(const rapidjson::Value& inJsonValue, Angle& outValue) + { + JsonSerializer::JsonDeserialize(inJsonValue, outValue.value); + } + }; + + template + struct JsonSerializer> { + static void JsonSerialize(rapidjson::Value& outJsonValue, rapidjson::Document::AllocatorType& inAllocator, const Radian& inValue) + { + JsonSerializer::JsonSerialize(outJsonValue, inAllocator, inValue.value); + } + + static void JsonDeserialize(const rapidjson::Value& inJsonValue, Radian& outValue) + { + JsonSerializer::JsonDeserialize(inJsonValue, outValue.value); + } + }; + + template + struct JsonSerializer> { + static void JsonSerialize(rapidjson::Value& outJsonValue, rapidjson::Document::AllocatorType& inAllocator, const Quaternion& inValue) + { + outJsonValue.SetArray(); + rapidjson::Value wJson; + rapidjson::Value xJson; + rapidjson::Value yJson; + rapidjson::Value zJson; + JsonSerializer::JsonSerialize(wJson, inAllocator, inValue.w); + JsonSerializer::JsonSerialize(xJson, inAllocator, inValue.x); + JsonSerializer::JsonSerialize(yJson, inAllocator, inValue.y); + JsonSerializer::JsonSerialize(zJson, inAllocator, inValue.z); + outJsonValue.PushBack(wJson, inAllocator); + outJsonValue.PushBack(xJson, inAllocator); + outJsonValue.PushBack(yJson, inAllocator); + outJsonValue.PushBack(zJson, inAllocator); + } + + static void JsonDeserialize(const rapidjson::Value& inJsonValue, Quaternion& outValue) + { + if (!inJsonValue.IsArray() || inJsonValue.Size() != 4) { + return; + } + JsonSerializer::JsonDeserialize(inJsonValue[0], outValue.w); + JsonSerializer::JsonDeserialize(inJsonValue[1], outValue.x); + JsonSerializer::JsonDeserialize(inJsonValue[2], outValue.y); + JsonSerializer::JsonDeserialize(inJsonValue[3], outValue.z); + } + }; + + template + struct Serializer> { + static constexpr size_t typeId = HashUtils::StrCrc32("Common::Rect") + Serializer::typeId; + + static size_t Serialize(BinarySerializeStream& stream, const Rect& value) + { + size_t serialized = 0; + serialized += Serializer>::Serialize(stream, value.min); + serialized += Serializer>::Serialize(stream, value.max); + return serialized; + } + + static size_t Deserialize(BinaryDeserializeStream& stream, Rect& value) + { + size_t deserialized = 0; + deserialized += Serializer>::Deserialize(stream, value.min); + deserialized += Serializer>::Deserialize(stream, value.max); + return deserialized; + } + }; + + template + struct StringConverter> { + static std::string ToString(const Rect& inValue) + { + return std::format( + "{}min={}, max={}{}", "{", StringConverter>::ToString(inValue.min), + StringConverter>::ToString(inValue.max), "}"); + } + }; + + template + struct JsonSerializer> { + static void JsonSerialize(rapidjson::Value& outJsonValue, rapidjson::Document::AllocatorType& inAllocator, const Rect& inValue) + { + rapidjson::Value minJson; + rapidjson::Value maxJson; + JsonSerializer>::JsonSerialize(minJson, inAllocator, inValue.min); + JsonSerializer>::JsonSerialize(maxJson, inAllocator, inValue.max); + outJsonValue.SetObject(); + outJsonValue.AddMember("min", minJson, inAllocator); + outJsonValue.AddMember("max", maxJson, inAllocator); + } + + static void JsonDeserialize(const rapidjson::Value& inJsonValue, Rect& outValue) + { + if (!inJsonValue.IsObject()) { + return; + } + if (inJsonValue.HasMember("min")) { + JsonSerializer>::JsonDeserialize(inJsonValue["min"], outValue.min); + } + if (inJsonValue.HasMember("max")) { + JsonSerializer>::JsonDeserialize(inJsonValue["max"], outValue.max); + } + } + }; + + template + struct Serializer> { + static constexpr size_t typeId = HashUtils::StrCrc32("Common::Box") + Serializer::typeId; + + static size_t Serialize(BinarySerializeStream& stream, const Box& value) + { + size_t serialized = 0; + serialized += Serializer>::Serialize(stream, value.min); + serialized += Serializer>::Serialize(stream, value.max); + return serialized; + } + + static size_t Deserialize(BinaryDeserializeStream& stream, Box& value) + { + size_t deserialized = 0; + deserialized += Serializer>::Deserialize(stream, value.min); + deserialized += Serializer>::Deserialize(stream, value.max); + return deserialized; + } + }; + + template + struct StringConverter> { + static std::string ToString(const Box& inValue) + { + return std::format( + "{}min={}, max={}{}", "{", StringConverter>::ToString(inValue.min), + StringConverter>::ToString(inValue.max), "}"); + } + }; + + template + struct JsonSerializer> { + static void JsonSerialize(rapidjson::Value& outJsonValue, rapidjson::Document::AllocatorType& inAllocator, const Box& inValue) + { + rapidjson::Value minJson; + rapidjson::Value maxJson; + JsonSerializer>::JsonSerialize(minJson, inAllocator, inValue.min); + JsonSerializer>::JsonSerialize(maxJson, inAllocator, inValue.max); + outJsonValue.SetObject(); + outJsonValue.AddMember("min", minJson, inAllocator); + outJsonValue.AddMember("max", maxJson, inAllocator); + } + + static void JsonDeserialize(const rapidjson::Value& inJsonValue, Box& outValue) + { + if (!inJsonValue.IsObject()) { + return; + } + if (inJsonValue.HasMember("min")) { + JsonSerializer>::JsonDeserialize(inJsonValue["min"], outValue.min); + } + if (inJsonValue.HasMember("max")) { + JsonSerializer>::JsonDeserialize(inJsonValue["max"], outValue.max); + } + } + }; + + template + struct Serializer> { + static constexpr size_t typeId = HashUtils::StrCrc32("Common::Sphere") + Serializer::typeId; + + static size_t Serialize(BinarySerializeStream& stream, const Sphere& value) + { + size_t serialized = 0; + serialized += Serializer>::Serialize(stream, value.center); + serialized += Serializer::Serialize(stream, value.radius); + return serialized; + } + + static size_t Deserialize(BinaryDeserializeStream& stream, Sphere& value) + { + size_t deserialized = 0; + deserialized += Serializer>::Deserialize(stream, value.center); + deserialized += Serializer::Deserialize(stream, value.radius); + return deserialized; + } + }; + + template + struct StringConverter> { + static std::string ToString(const Sphere& inValue) + { + return std::format( + "{}center={}, radius={}{}", "{", StringConverter>::ToString(inValue.center), + StringConverter::ToString(inValue.radius), "}"); + } + }; + + template + struct JsonSerializer> { + static void JsonSerialize(rapidjson::Value& outJsonValue, rapidjson::Document::AllocatorType& inAllocator, const Sphere& inValue) + { + rapidjson::Value centerJson; + rapidjson::Value radiusJson; + JsonSerializer>::JsonSerialize(centerJson, inAllocator, inValue.center); + JsonSerializer::JsonSerialize(radiusJson, inAllocator, inValue.radius); + outJsonValue.SetObject(); + outJsonValue.AddMember("center", centerJson, inAllocator); + outJsonValue.AddMember("radius", radiusJson, inAllocator); + } + + static void JsonDeserialize(const rapidjson::Value& inJsonValue, Sphere& outValue) + { + if (!inJsonValue.IsObject()) { + return; + } + if (inJsonValue.HasMember("center")) { + JsonSerializer>::JsonDeserialize(inJsonValue["center"], outValue.center); + } + if (inJsonValue.HasMember("radius")) { + JsonSerializer::JsonDeserialize(inJsonValue["radius"], outValue.radius); + } + } + }; + + template <> + struct Serializer { + static constexpr size_t typeId = HashUtils::StrCrc32("Common::Color"); + + static size_t Serialize(BinarySerializeStream& stream, const Color& value) + { + size_t serialized = 0; + serialized += Serializer::Serialize(stream, value.r); + serialized += Serializer::Serialize(stream, value.g); + serialized += Serializer::Serialize(stream, value.b); + serialized += Serializer::Serialize(stream, value.a); + return serialized; + } + + static size_t Deserialize(BinaryDeserializeStream& stream, Color& value) + { + size_t deserialized = 0; + deserialized += Serializer::Deserialize(stream, value.r); + deserialized += Serializer::Deserialize(stream, value.g); + deserialized += Serializer::Deserialize(stream, value.b); + deserialized += Serializer::Deserialize(stream, value.a); + return deserialized; + } + }; + + template <> + struct Serializer { + static constexpr size_t typeId = HashUtils::StrCrc32("Common::LinearColor"); + + static size_t Serialize(BinarySerializeStream& stream, const LinearColor& value) + { + size_t serialized = 0; + serialized += Serializer::Serialize(stream, value.r); + serialized += Serializer::Serialize(stream, value.g); + serialized += Serializer::Serialize(stream, value.b); + serialized += Serializer::Serialize(stream, value.a); + return serialized; + } + + static size_t Deserialize(BinaryDeserializeStream& stream, LinearColor& value) + { + size_t deserialized = 0; + deserialized += Serializer::Deserialize(stream, value.r); + deserialized += Serializer::Deserialize(stream, value.g); + deserialized += Serializer::Deserialize(stream, value.b); + deserialized += Serializer::Deserialize(stream, value.a); + return deserialized; + } + }; + + template <> + struct StringConverter { + static std::string ToString(const Color& inValue) + { + return std::format( + "{}r={}, g={}, b={}, a={}{}", "{", StringConverter::ToString(inValue.r), + StringConverter::ToString(inValue.g), StringConverter::ToString(inValue.b), + StringConverter::ToString(inValue.a), "}"); + } + }; + + template <> + struct StringConverter { + static std::string ToString(const LinearColor& inValue) + { + return std::format( + "{}r={}, g={}, b={}, a={}{}", "{", StringConverter::ToString(inValue.r), + StringConverter::ToString(inValue.g), StringConverter::ToString(inValue.b), + StringConverter::ToString(inValue.a), "}"); + } + }; + + template <> + struct JsonSerializer { + static void JsonSerialize(rapidjson::Value& outJsonValue, rapidjson::Document::AllocatorType& inAllocator, const Color& inValue) + { + outJsonValue.SetObject(); + outJsonValue.AddMember("r", inValue.r, inAllocator); + outJsonValue.AddMember("g", inValue.g, inAllocator); + outJsonValue.AddMember("b", inValue.b, inAllocator); + outJsonValue.AddMember("a", inValue.a, inAllocator); + } + + static void JsonDeserialize(const rapidjson::Value& inJsonValue, Color& outValue) + { + if (!inJsonValue.IsObject()) { + return; + } + if (inJsonValue.HasMember("r") && inJsonValue["r"].IsUint()) { + outValue.r = static_cast(inJsonValue["r"].GetUint()); + } + if (inJsonValue.HasMember("g") && inJsonValue["g"].IsUint()) { + outValue.g = static_cast(inJsonValue["g"].GetUint()); + } + if (inJsonValue.HasMember("b") && inJsonValue["b"].IsUint()) { + outValue.b = static_cast(inJsonValue["b"].GetUint()); + } + if (inJsonValue.HasMember("a") && inJsonValue["a"].IsUint()) { + outValue.a = static_cast(inJsonValue["a"].GetUint()); + } + } + }; + + template <> + struct JsonSerializer { + static void JsonSerialize(rapidjson::Value& outJsonValue, rapidjson::Document::AllocatorType& inAllocator, const LinearColor& inValue) + { + outJsonValue.SetObject(); + outJsonValue.AddMember("r", inValue.r, inAllocator); + outJsonValue.AddMember("g", inValue.g, inAllocator); + outJsonValue.AddMember("b", inValue.b, inAllocator); + outJsonValue.AddMember("a", inValue.a, inAllocator); + } + + static void JsonDeserialize(const rapidjson::Value& inJsonValue, LinearColor& outValue) + { + if (!inJsonValue.IsObject()) { + return; + } + if (inJsonValue.HasMember("r") && inJsonValue["r"].IsFloat()) { + outValue.r = inJsonValue["r"].GetFloat(); + } + if (inJsonValue.HasMember("g") && inJsonValue["g"].IsFloat()) { + outValue.g = inJsonValue["g"].GetFloat(); + } + if (inJsonValue.HasMember("b") && inJsonValue["b"].IsFloat()) { + outValue.b = inJsonValue["b"].GetFloat(); + } + if (inJsonValue.HasMember("a") && inJsonValue["a"].IsFloat()) { + outValue.a = inJsonValue["a"].GetFloat(); + } + } + }; + + template + struct Serializer> { + static constexpr size_t typeId = HashUtils::StrCrc32("Common::Transform") + Serializer::typeId; + + static size_t Serialize(BinarySerializeStream& stream, const Transform& value) + { + size_t serialized = 0; + serialized += Serializer>::Serialize(stream, value.scale); + serialized += Serializer>::Serialize(stream, value.rotation); + serialized += Serializer>::Serialize(stream, value.translation); + return serialized; + } + + static size_t Deserialize(BinaryDeserializeStream& stream, Transform& value) + { + size_t deserialized = 0; + deserialized += Serializer>::Deserialize(stream, value.scale); + deserialized += Serializer>::Deserialize(stream, value.rotation); + deserialized += Serializer>::Deserialize(stream, value.translation); + return deserialized; + } + }; + + template + struct StringConverter> { + static std::string ToString(const Transform& inValue) + { + return std::format( + "{}scale={}, rotation={}, translation={}{}", "{", + StringConverter>::ToString(inValue.scale), + StringConverter>::ToString(inValue.rotation), + StringConverter>::ToString(inValue.translation), "}"); + } + }; + + template + struct JsonSerializer> { + static void JsonSerialize(rapidjson::Value& outJsonValue, rapidjson::Document::AllocatorType& inAllocator, const Transform& inValue) + { + rapidjson::Value scaleJson; + rapidjson::Value rotationJson; + rapidjson::Value translationJson; + JsonSerializer>::JsonSerialize(scaleJson, inAllocator, inValue.scale); + JsonSerializer>::JsonSerialize(rotationJson, inAllocator, inValue.rotation); + JsonSerializer>::JsonSerialize(translationJson, inAllocator, inValue.translation); + outJsonValue.SetObject(); + outJsonValue.AddMember("scale", scaleJson, inAllocator); + outJsonValue.AddMember("rotation", rotationJson, inAllocator); + outJsonValue.AddMember("translation", translationJson, inAllocator); + } + + static void JsonDeserialize(const rapidjson::Value& inJsonValue, Transform& outValue) + { + if (!inJsonValue.IsObject()) { + return; + } + if (inJsonValue.HasMember("scale")) { + JsonSerializer>::JsonDeserialize(inJsonValue["scale"], outValue.scale); + } + if (inJsonValue.HasMember("rotation")) { + JsonSerializer>::JsonDeserialize(inJsonValue["rotation"], outValue.rotation); + } + if (inJsonValue.HasMember("translation")) { + JsonSerializer>::JsonDeserialize(inJsonValue["translation"], outValue.translation); + } + } + }; + + template + struct Serializer> { + static constexpr size_t typeId = HashUtils::StrCrc32("Common::ViewTransform") + Serializer::typeId; + + static size_t Serialize(BinarySerializeStream& stream, const ViewTransform& value) + { + return Serializer>::Serialize(stream, value); + } + + static size_t Deserialize(BinaryDeserializeStream& stream, ViewTransform& value) + { + return Serializer>::Deserialize(stream, value); + } + }; + + template + struct StringConverter> { + static std::string ToString(const ViewTransform& inValue) + { + return StringConverter>::ToString(inValue); + } + }; + + template + struct JsonSerializer> { + static void JsonSerialize(rapidjson::Value& outJsonValue, rapidjson::Document::AllocatorType& inAllocator, const ViewTransform& inValue) + { + JsonSerializer>::JsonSerialize(outJsonValue, inAllocator, inValue); + } + + static void JsonDeserialize(const rapidjson::Value& inJsonValue, ViewTransform& outValue) + { + JsonSerializer>::JsonDeserialize(inJsonValue, outValue); + } + }; + + template + struct Serializer> { + static constexpr size_t typeId = HashUtils::StrCrc32("Common::ReversedZOrthogonalProjection") + Serializer::typeId; + + static size_t Serialize(BinarySerializeStream& stream, const ReversedZOrthogonalProjection& value) + { + size_t serialized = 0; + serialized += Serializer::Serialize(stream, value.width); + serialized += Serializer::Serialize(stream, value.height); + serialized += Serializer::Serialize(stream, value.nearPlane); + serialized += Serializer>::Serialize(stream, value.farPlane); + return serialized; + } + + static size_t Deserialize(BinaryDeserializeStream& stream, ReversedZOrthogonalProjection& value) + { + size_t deserialized = 0; + deserialized += Serializer::Deserialize(stream, value.width); + deserialized += Serializer::Deserialize(stream, value.height); + deserialized += Serializer::Deserialize(stream, value.nearPlane); + deserialized += Serializer>::Deserialize(stream, value.farPlane); + return deserialized; + } + }; + + template + struct Serializer> { + static constexpr size_t typeId = HashUtils::StrCrc32("Common::ReversedZPerspectiveProjection") + Serializer::typeId; + + static size_t Serialize(BinarySerializeStream& stream, const ReversedZPerspectiveProjection& value) + { + size_t serialized = 0; + serialized += Serializer::Serialize(stream, value.fov); + serialized += Serializer::Serialize(stream, value.width); + serialized += Serializer::Serialize(stream, value.height); + serialized += Serializer::Serialize(stream, value.nearPlane); + serialized += Serializer>::Serialize(stream, value.farPlane); + return serialized; + } + + static size_t Deserialize(BinaryDeserializeStream& stream, ReversedZPerspectiveProjection& value) + { + size_t deserialized = 0; + deserialized += Serializer::Deserialize(stream, value.fov); + deserialized += Serializer::Deserialize(stream, value.width); + deserialized += Serializer::Deserialize(stream, value.height); + deserialized += Serializer::Deserialize(stream, value.nearPlane); + deserialized += Serializer>::Deserialize(stream, value.farPlane); + return deserialized; + } + }; + + template + struct StringConverter> { + static std::string ToString(const ReversedZOrthogonalProjection& inValue) + { + return std::format( + "{}width={}, height={}, near={}, far={}{}", "{", StringConverter::ToString(inValue.width), + StringConverter::ToString(inValue.height), StringConverter::ToString(inValue.nearPlane), + StringConverter>::ToString(inValue.farPlane), "}"); + } + }; + + template + struct StringConverter> { + static std::string ToString(const ReversedZPerspectiveProjection& inValue) + { + return std::format( + "{}fov={}, width={}, height={}, near={}, far={}{}", "{", StringConverter::ToString(inValue.fov), + StringConverter::ToString(inValue.width), StringConverter::ToString(inValue.height), + StringConverter::ToString(inValue.nearPlane), + StringConverter>::ToString(inValue.farPlane), "}"); + } + }; + + template + struct JsonSerializer> { + static void JsonSerialize(rapidjson::Value& outJsonValue, rapidjson::Document::AllocatorType& inAllocator, const ReversedZOrthogonalProjection& inValue) + { + rapidjson::Value widthJson; + rapidjson::Value heightJson; + rapidjson::Value nearJson; + rapidjson::Value farJson; + JsonSerializer::JsonSerialize(widthJson, inAllocator, inValue.width); + JsonSerializer::JsonSerialize(heightJson, inAllocator, inValue.height); + JsonSerializer::JsonSerialize(nearJson, inAllocator, inValue.nearPlane); + JsonSerializer>::JsonSerialize(farJson, inAllocator, inValue.farPlane); + outJsonValue.SetObject(); + outJsonValue.AddMember("width", widthJson, inAllocator); + outJsonValue.AddMember("height", heightJson, inAllocator); + outJsonValue.AddMember("near", nearJson, inAllocator); + outJsonValue.AddMember("far", farJson, inAllocator); + } + + static void JsonDeserialize(const rapidjson::Value& inJsonValue, ReversedZOrthogonalProjection& outValue) + { + if (!inJsonValue.IsObject()) { + return; + } + if (inJsonValue.HasMember("width")) { + JsonSerializer::JsonDeserialize(inJsonValue["width"], outValue.width); + } + if (inJsonValue.HasMember("height")) { + JsonSerializer::JsonDeserialize(inJsonValue["height"], outValue.height); + } + if (inJsonValue.HasMember("near")) { + JsonSerializer::JsonDeserialize(inJsonValue["near"], outValue.nearPlane); + } + if (inJsonValue.HasMember("far")) { + JsonSerializer>::JsonDeserialize(inJsonValue["far"], outValue.farPlane); + } + } + }; + + template + struct JsonSerializer> { + static void JsonSerialize(rapidjson::Value& outJsonValue, rapidjson::Document::AllocatorType& inAllocator, const ReversedZPerspectiveProjection& inValue) + { + rapidjson::Value fovJson; + rapidjson::Value widthJson; + rapidjson::Value heightJson; + rapidjson::Value nearJson; + rapidjson::Value farJson; + JsonSerializer::JsonSerialize(fovJson, inAllocator, inValue.fov); + JsonSerializer::JsonSerialize(widthJson, inAllocator, inValue.width); + JsonSerializer::JsonSerialize(heightJson, inAllocator, inValue.height); + JsonSerializer::JsonSerialize(nearJson, inAllocator, inValue.nearPlane); + JsonSerializer>::JsonSerialize(farJson, inAllocator, inValue.farPlane); + outJsonValue.SetObject(); + outJsonValue.AddMember("fov", fovJson, inAllocator); + outJsonValue.AddMember("width", widthJson, inAllocator); + outJsonValue.AddMember("height", heightJson, inAllocator); + outJsonValue.AddMember("near", nearJson, inAllocator); + outJsonValue.AddMember("far", farJson, inAllocator); + } + + static void JsonDeserialize(const rapidjson::Value& inJsonValue, ReversedZPerspectiveProjection& outValue) + { + if (!inJsonValue.IsObject()) { + return; + } + if (inJsonValue.HasMember("fov")) { + JsonSerializer::JsonDeserialize(inJsonValue["fov"], outValue.fov); + } + if (inJsonValue.HasMember("width")) { + JsonSerializer::JsonDeserialize(inJsonValue["width"], outValue.width); + } + if (inJsonValue.HasMember("height")) { + JsonSerializer::JsonDeserialize(inJsonValue["height"], outValue.height); + } + if (inJsonValue.HasMember("near")) { + JsonSerializer::JsonDeserialize(inJsonValue["near"], outValue.nearPlane); + } + if (inJsonValue.HasMember("far")) { + JsonSerializer>::JsonDeserialize(inJsonValue["far"], outValue.farPlane); + } + } + }; +} diff --git a/Engine/Source/Common/Include/Common/Math/Box.h b/Engine/Source/Common/Include/Common/Math/Box.h index fc680a265..4d21e6d41 100644 --- a/Engine/Source/Common/Include/Common/Math/Box.h +++ b/Engine/Source/Common/Include/Common/Math/Box.h @@ -5,8 +5,6 @@ #pragma once #include -#include -#include namespace Common { template @@ -35,9 +33,9 @@ namespace Common { T CenterX() const; T CenterY() const; T CenterZ() const; - T Distance(const Box& inOther) const; + T Distance(const Box& inOther) const requires FloatingPoint; // half of diagonal - T Size() const; + T Size() const requires FloatingPoint; bool Inside(const Vec& inPoint) const; bool Intersect(const Box& inOther) const; bool operator==(const Box& inRhs) const; @@ -45,6 +43,8 @@ namespace Common { template Box CastTo() const; }; + template requires FloatingPoint bool AlmostEqual(const Box& lhs, const Box& rhs, T absoluteTolerance = DefaultTolerance(), T relativeTolerance = DefaultTolerance()); + using IBox = Box; using UBox = Box; using HBox = Box; @@ -52,73 +52,6 @@ namespace Common { using DBox = Box; } -namespace Common { // NOLINT - template - struct Serializer> { - static constexpr size_t typeId - = HashUtils::StrCrc32("Common::Box") - + Serializer::typeId; - - static size_t Serialize(BinarySerializeStream& stream, const Box& value) - { - size_t serialized = 0; - serialized += Serializer>::Serialize(stream, value.min); - serialized += Serializer>::Serialize(stream, value.max); - return serialized; - } - - static size_t Deserialize(BinaryDeserializeStream& stream, Box& value) - { - size_t deserialized = 0; - deserialized += Serializer>::Deserialize(stream, value.min); - deserialized += Serializer>::Deserialize(stream, value.max); - return deserialized; - } - }; - - template - struct StringConverter> { - static std::string ToString(const Box& inValue) - { - return std::format( - "{}min={}, max={}{}", - "{", - StringConverter>::ToString(inValue.min), - StringConverter>::ToString(inValue.max), - "}"); - } - }; - - template - struct JsonSerializer> { - static void JsonSerialize(rapidjson::Value& outJsonValue, rapidjson::Document::AllocatorType& inAllocator, const Box& inValue) - { - rapidjson::Value minJson; - JsonSerializer>::JsonSerialize(minJson, inAllocator, inValue.min); - - rapidjson::Value maxJson; - JsonSerializer>::JsonSerialize(maxJson, inAllocator, inValue.max); - - outJsonValue.SetObject(); - outJsonValue.AddMember("min", minJson, inAllocator); - outJsonValue.AddMember("max", maxJson, inAllocator); - } - - static void JsonDeserialize(const rapidjson::Value& inJsonValue, Box& outValue) - { - if (!inJsonValue.IsObject()) { - return; - } - if (inJsonValue.HasMember("min")) { - JsonSerializer>::JsonDeserialize(inJsonValue["min"], outValue.min); - } - if (inJsonValue.HasMember("max")) { - JsonSerializer>::JsonDeserialize(inJsonValue["max"], outValue.max); - } - } - }; -} - namespace Common { template Box Box::FromMinExtent(T inMinX, T inMinY, T inMinZ, T inExtentX, T inExtentY, T inExtentZ) @@ -154,26 +87,13 @@ namespace Common { } template - Box::Box(const Box& inOther) - { - this->min = inOther.min; - this->max = inOther.max; - } + Box::Box(const Box& inOther) = default; template - Box::Box(Box&& inOther) noexcept - { - this->min = std::move(inOther.min); - this->max = std::move(inOther.max); - } + Box::Box(Box&& inOther) noexcept = default; template - Box& Box::operator=(const Box& inOther) - { - this->min = inOther.min; - this->max = inOther.max; - return *this; - } + Box& Box::operator=(const Box& inOther) = default; template Vec Box::Extent() const @@ -224,14 +144,14 @@ namespace Common { } template - T Box::Distance(const Box& inOther) const + T Box::Distance(const Box& inOther) const requires FloatingPoint { Vec direction = Center() - inOther.Center(); return direction.Model(); } template - T Box::Size() const + T Box::Size() const requires FloatingPoint { Vec diagonal = this->max - this->min; return diagonal.Model() / T(2); @@ -272,4 +192,12 @@ namespace Common { this->max.template CastTo() ); } + + template + requires FloatingPoint + bool AlmostEqual(const Box& lhs, const Box& rhs, T absoluteTolerance, T relativeTolerance) + { + return AlmostEqual(lhs.min, rhs.min, absoluteTolerance, relativeTolerance) + && AlmostEqual(lhs.max, rhs.max, absoluteTolerance, relativeTolerance); + } } diff --git a/Engine/Source/Common/Include/Common/Math/Color.h b/Engine/Source/Common/Include/Common/Math/Color.h index ed5f943d6..580f49b26 100644 --- a/Engine/Source/Common/Include/Common/Math/Color.h +++ b/Engine/Source/Common/Include/Common/Math/Color.h @@ -5,9 +5,9 @@ #pragma once #include +#include -#include -#include +#include namespace Common { struct Color; @@ -66,148 +66,6 @@ namespace Common { static const LinearColor blue; static const LinearColor green; }; -} - -namespace Common { - template <> - struct Serializer { - static constexpr size_t typeId = HashUtils::StrCrc32("Common::Color"); - - static size_t Serialize(BinarySerializeStream& stream, const Color& value) - { - size_t serialized = 0; - serialized += Serializer::Serialize(stream, value.r); - serialized += Serializer::Serialize(stream, value.g); - serialized += Serializer::Serialize(stream, value.b); - serialized += Serializer::Serialize(stream, value.a); - return serialized; - } - - static size_t Deserialize(BinaryDeserializeStream& stream, Color& value) - { - size_t deserialized = 0; - deserialized += Serializer::Deserialize(stream, value.r); - deserialized += Serializer::Deserialize(stream, value.g); - deserialized += Serializer::Deserialize(stream, value.b); - deserialized += Serializer::Deserialize(stream, value.a); - return deserialized; - } - }; - - template <> - struct Serializer { - static constexpr size_t typeId = HashUtils::StrCrc32("Common::LinearColor"); - - static size_t Serialize(BinarySerializeStream& stream, const LinearColor& value) - { - size_t serialized = 0; - serialized += Serializer::Serialize(stream, value.r); - serialized += Serializer::Serialize(stream, value.g); - serialized += Serializer::Serialize(stream, value.b); - serialized += Serializer::Serialize(stream, value.a); - return serialized; - } - - static size_t Deserialize(BinaryDeserializeStream& stream, LinearColor& value) - { - size_t deserialized = 0; - deserialized += Serializer::Deserialize(stream, value.r); - deserialized += Serializer::Deserialize(stream, value.g); - deserialized += Serializer::Deserialize(stream, value.b); - deserialized += Serializer::Deserialize(stream, value.a); - return deserialized; - } - }; - template <> - struct StringConverter { - static std::string ToString(const Color& inValue) - { - return std::format( - "{}r={}, g={}, b={}, a={}{}", - "{", - StringConverter::ToString(inValue.r), - StringConverter::ToString(inValue.g), - StringConverter::ToString(inValue.b), - StringConverter::ToString(inValue.a), - "}"); - } - }; - - template <> - struct StringConverter { - static std::string ToString(const LinearColor& inValue) - { - return std::format( - "{}r={}, g={}, b={}, a={}{}", - "{", - StringConverter::ToString(inValue.r), - StringConverter::ToString(inValue.g), - StringConverter::ToString(inValue.b), - StringConverter::ToString(inValue.a), - "}"); - } - }; - - template <> - struct JsonSerializer { - static void JsonSerialize(rapidjson::Value& outJsonValue, rapidjson::Document::AllocatorType& inAllocator, const Color& inValue) - { - outJsonValue.SetObject(); - outJsonValue.AddMember("r", inValue.r, inAllocator); - outJsonValue.AddMember("g", inValue.g, inAllocator); - outJsonValue.AddMember("b", inValue.b, inAllocator); - outJsonValue.AddMember("a", inValue.a, inAllocator); - } - - static void JsonDeserialize(const rapidjson::Value& inJsonValue, Color& outValue) - { - if (!inJsonValue.IsObject()) { - return; - } - if (inJsonValue.HasMember("r") && inJsonValue["r"].IsUint()) { - outValue.r = static_cast(inJsonValue["r"].GetUint()); - } - if (inJsonValue.HasMember("g") && inJsonValue["g"].IsUint()) { - outValue.g = static_cast(inJsonValue["g"].GetUint()); - } - if (inJsonValue.HasMember("b") && inJsonValue["b"].IsUint()) { - outValue.b = static_cast(inJsonValue["b"].GetUint()); - } - if (inJsonValue.HasMember("a") && inJsonValue["a"].IsUint()) { - outValue.a = static_cast(inJsonValue["a"].GetUint()); - } - } - }; - - template <> - struct JsonSerializer { - static void JsonSerialize(rapidjson::Value& outJsonValue, rapidjson::Document::AllocatorType& inAllocator, const LinearColor& inValue) - { - outJsonValue.SetObject(); - outJsonValue.AddMember("r", inValue.r, inAllocator); - outJsonValue.AddMember("g", inValue.g, inAllocator); - outJsonValue.AddMember("b", inValue.b, inAllocator); - outJsonValue.AddMember("a", inValue.a, inAllocator); - } - - static void JsonDeserialize(const rapidjson::Value& inJsonValue, LinearColor& outValue) - { - if (!inJsonValue.IsObject()) { - return; - } - if (inJsonValue.HasMember("r") && inJsonValue["r"].IsFloat()) { - outValue.r = inJsonValue["r"].GetFloat(); - } - if (inJsonValue.HasMember("g") && inJsonValue["g"].IsFloat()) { - outValue.g = inJsonValue["g"].GetFloat(); - } - if (inJsonValue.HasMember("b") && inJsonValue["b"].IsFloat()) { - outValue.b = inJsonValue["b"].GetFloat(); - } - if (inJsonValue.HasMember("a") && inJsonValue["a"].IsFloat()) { - outValue.a = inJsonValue["a"].GetFloat(); - } - } - }; + bool AlmostEqual(const LinearColor& lhs, const LinearColor& rhs, float absoluteTolerance = DefaultTolerance(), float relativeTolerance = DefaultTolerance()); } diff --git a/Engine/Source/Common/Include/Common/Math/Common.h b/Engine/Source/Common/Include/Common/Math/Common.h index f65a85b63..9d6228863 100644 --- a/Engine/Source/Common/Include/Common/Math/Common.h +++ b/Engine/Source/Common/Include/Common/Math/Common.h @@ -4,6 +4,7 @@ #pragma once +#include #include #include @@ -16,16 +17,60 @@ namespace Common { } namespace Common { + template T DefaultTolerance(); + template T Pi(); + template requires std::is_floating_point_v bool AlmostEqual(T lhs, T rhs, T absoluteTolerance = DefaultTolerance(), T relativeTolerance = DefaultTolerance()); template bool CompareNumber(T lhs, T rhs); template T DivideAndRoundUp(T lhs, T rhs); } namespace Common { + template + T DefaultTolerance() + { + if constexpr (std::is_same_v) { + return static_cast(epsilon); + } else if constexpr (std::is_same_v) { + return static_cast(1e-12); + } else if constexpr (std::is_same_v) { + return static_cast(1e-15L); + } else { + return static_cast(halfEpsilon); + } + } + + template + T Pi() + { + if constexpr (std::is_floating_point_v) { + return std::numbers::pi_v; + } else { + return static_cast(std::numbers::pi_v); + } + } + + template + requires std::is_floating_point_v + bool AlmostEqual(T lhs, T rhs, T absoluteTolerance, T relativeTolerance) + { + if (lhs == rhs) { + return true; + } + if (!std::isfinite(lhs) || !std::isfinite(rhs)) { + return false; + } + + const T difference = std::abs(lhs - rhs); + const T scale = std::max(std::abs(lhs), std::abs(rhs)); + return difference <= std::max(absoluteTolerance, relativeTolerance * scale); + } + template bool CompareNumber(T lhs, T rhs) { if constexpr (std::is_floating_point_v) { - return std::abs(lhs - rhs) < epsilon; + const T tolerance = DefaultTolerance(); + return AlmostEqual(lhs, rhs, tolerance, tolerance); } else { return lhs == rhs; } diff --git a/Engine/Source/Common/Include/Common/Math/Half.h b/Engine/Source/Common/Include/Common/Math/Half.h index dd386343f..a7fd4dc8e 100644 --- a/Engine/Source/Common/Include/Common/Math/Half.h +++ b/Engine/Source/Common/Include/Common/Math/Half.h @@ -4,36 +4,21 @@ #pragma once -#include -#include #include +#include #include -#include -#include namespace Common { template concept ValidEndian = E == std::endian::little || E == std::endian::big; -} -namespace Common::Internal { template requires ValidEndian - struct FullFloatBase {}; + struct HalfFloatBase { + explicit HalfFloatBase(uint16_t inValue); - template - struct FullFloat : FullFloatBase { - FullFloat(); - FullFloat(float inValue); // NOLINT - FullFloat(const FullFloat& inValue); - FullFloat(FullFloat&& inValue) noexcept; + uint16_t value; }; -} - -namespace Common { - template - requires ValidEndian - struct HalfFloatBase {}; template struct HalfFloat : HalfFloatBase { @@ -78,184 +63,99 @@ namespace Common { using HFloat = HalfFloat; template concept HalfFloatingPoint = std::is_same_v; - template concept FloatingPoint = std::is_floating_point_v || std::is_same_v; -} - -namespace Common { - template - struct Serializer> { - static constexpr size_t typeId = HashUtils::StrCrc32("Common::Internal::FullFloat"); - - static size_t Serialize(BinarySerializeStream& stream, const Internal::FullFloat& value) - { - return Serializer::Serialize(stream, value.value); - } - - static size_t Deserialize(BinaryDeserializeStream& stream, Internal::FullFloat& value) - { - return Serializer::Deserialize(stream, value.value); - } - }; + template concept FloatingPoint = std::is_floating_point_v || HalfFloatingPoint; template - struct Serializer> { - static constexpr size_t typeId = HashUtils::StrCrc32("Common::Internal::HalfFloat"); - - static size_t Serialize(BinarySerializeStream& stream, const HalfFloat& value) - { - return Serializer::Serialize(stream, value.value); - } + bool AlmostEqual(HalfFloat lhs, HalfFloat rhs, HalfFloat absoluteTolerance = DefaultTolerance>(), HalfFloat relativeTolerance = DefaultTolerance>()); +} - static size_t Deserialize(BinaryDeserializeStream& stream, HalfFloat& value) - { - return Serializer::Deserialize(stream, value.value); - } - }; +namespace Common::Internal { + inline uint16_t FloatToHalfBits(float inValue) + { + const uint32_t floatBits = std::bit_cast(inValue); + const uint16_t sign = static_cast((floatBits >> 16) & 0x8000u); + const uint32_t exponent = (floatBits >> 23) & 0xffu; + const uint32_t mantissa = floatBits & 0x7fffffu; - template - struct StringConverter> { - static std::string ToString(const Internal::FullFloat& inValue) - { - return StringConverter::ToString(inValue.value); - } - }; + if (exponent == 0xffu) { + if (mantissa == 0) { + return static_cast(sign | 0x7c00u); + } - template - struct StringConverter> { - static std::string ToString(const HalfFloat& inValue) - { - return StringConverter::ToString(inValue.AsFloat()); + uint16_t payload = static_cast(mantissa >> 13); + if (payload == 0) { + payload = 1; + } + return static_cast(sign | 0x7c00u | payload); } - }; - template - struct JsonSerializer> { - static void JsonSerialize(rapidjson::Value& outJsonValue, rapidjson::Document::AllocatorType& inAllocator, const Internal::FullFloat& inValue) - { - JsonSerializer::JsonSerialize(outJsonValue, inAllocator, inValue.value); + const int32_t halfExponent = static_cast(exponent) - 127 + 15; + if (halfExponent >= 31) { + return static_cast(sign | 0x7c00u); } - static void JsonDeserialize(const rapidjson::Value& inJsonValue, Internal::FullFloat& outValue) - { - JsonSerializer::JsonDeserialize(inJsonValue, outValue.value); - } - }; + if (halfExponent <= 0) { + if (halfExponent < -10) { + return sign; + } - template - struct JsonSerializer> { - static void JsonSerialize(rapidjson::Value& outJsonValue, rapidjson::Document::AllocatorType& inAllocator, const HalfFloat& inValue) - { - JsonSerializer::JsonSerialize(outJsonValue, inAllocator, inValue.AsFloat()); + const uint32_t significand = mantissa | 0x800000u; + const uint32_t shift = static_cast(14 - halfExponent); + uint16_t halfMantissa = static_cast(significand >> shift); + const uint32_t remainderMask = (uint32_t(1) << shift) - 1; + const uint32_t remainder = significand & remainderMask; + const uint32_t halfway = uint32_t(1) << (shift - 1); + if (remainder > halfway || (remainder == halfway && (halfMantissa & 1u) != 0)) { + ++halfMantissa; + } + return static_cast(sign | halfMantissa); } - static void JsonDeserialize(const rapidjson::Value& inJsonValue, HalfFloat& outValue) - { - float fltValue; - JsonSerializer::JsonDeserialize(inJsonValue, fltValue); - outValue = fltValue; + uint16_t result = static_cast(sign | (static_cast(halfExponent) << 10) | static_cast(mantissa >> 13)); + const uint32_t remainder = mantissa & 0x1fffu; + if (remainder > 0x1000u || (remainder == 0x1000u && (result & 1u) != 0)) { + ++result; } - }; -} - -namespace Common::Internal { - template <> - struct FullFloatBase { - union { - float value; - struct { - uint32_t mantissa : 23; - uint32_t exponent : 8; - uint32_t sign : 1; - }; - }; - - inline explicit FullFloatBase(float inValue); - }; - - template <> - struct FullFloatBase { - union { - float value; - struct { - uint32_t sign : 1; - uint32_t exponent : 8; - uint32_t mantissa : 23; - }; - }; - - inline explicit FullFloatBase(float inValue); - }; - - FullFloatBase::FullFloatBase(const float inValue) - : value(inValue) - { - } - - FullFloatBase::FullFloatBase(const float inValue) - : value(inValue) - { + return result; } - template - FullFloat::FullFloat() - : FullFloatBase(0) - { - } - - template - FullFloat::FullFloat(float inValue) - : FullFloatBase(inValue) + inline float HalfBitsToFloat(uint16_t inValue) { - } + const uint32_t sign = static_cast(inValue & 0x8000u) << 16; + const uint32_t exponent = (inValue >> 10) & 0x1fu; + uint32_t mantissa = inValue & 0x03ffu; + uint32_t floatBits; - template - FullFloat::FullFloat(const FullFloat& inValue) - : FullFloatBase(inValue.value) - { - } + if (exponent == 0) { + if (mantissa == 0) { + floatBits = sign; + } else { + const uint32_t shift = std::countl_zero(mantissa) - 21; + mantissa = (mantissa << shift) & 0x03ffu; + const uint32_t floatExponent = 127 - 14 - shift; + floatBits = sign | (floatExponent << 23) | (mantissa << 13); + } + } else if (exponent == 0x1fu) { + floatBits = sign | 0x7f800000u | (mantissa << 13); + } else { + const uint32_t floatExponent = exponent - 15 + 127; + floatBits = sign | (floatExponent << 23) | (mantissa << 13); + } - template - FullFloat::FullFloat(FullFloat&& inValue) noexcept - : FullFloatBase(inValue.value) - { + return std::bit_cast(floatBits); } } namespace Common { - template <> - struct HalfFloatBase { - union { - uint16_t value; - struct { - uint16_t mantissa : 10; - uint16_t exponent : 5; - uint16_t sign : 1; - }; - }; - - inline explicit HalfFloatBase(uint16_t inValue); - }; - - template <> - struct HalfFloatBase { - union { - uint16_t value; - struct { - uint16_t sign : 1; - uint16_t exponent : 5; - uint16_t mantissa : 10; - }; - }; - - inline explicit HalfFloatBase(uint16_t inValue); - }; - - HalfFloatBase::HalfFloatBase(const uint16_t inValue) - : value(inValue) + template + bool AlmostEqual(HalfFloat lhs, HalfFloat rhs, HalfFloat absoluteTolerance, HalfFloat relativeTolerance) { + return AlmostEqual(lhs.AsFloat(), rhs.AsFloat(), absoluteTolerance.AsFloat(), relativeTolerance.AsFloat()); } - HalfFloatBase::HalfFloatBase(const uint16_t inValue) + template + requires ValidEndian + HalfFloatBase::HalfFloatBase(uint16_t inValue) : value(inValue) { } @@ -267,104 +167,37 @@ namespace Common { } template - HalfFloat::HalfFloat(const HalfFloat& inValue) - : HalfFloatBase(inValue.value) - { - } + HalfFloat::HalfFloat(const HalfFloat& inValue) = default; template - HalfFloat::HalfFloat(HalfFloat&& inValue) noexcept - : HalfFloatBase(inValue.value) - { - } + HalfFloat::HalfFloat(HalfFloat&& inValue) noexcept = default; template - HalfFloat::HalfFloat(const float inValue) - : HalfFloatBase(0) + HalfFloat::HalfFloat(float inValue) + : HalfFloatBase(Internal::FloatToHalfBits(inValue)) { - Set(inValue); } template - HalfFloat& HalfFloat::operator=(const float inValue) + HalfFloat& HalfFloat::operator=(float inValue) { Set(inValue); return *this; } template - HalfFloat& HalfFloat::operator=(const HalfFloat& inValue) - { - this->value = inValue.value; - return *this; - } + HalfFloat& HalfFloat::operator=(const HalfFloat& inValue) = default; template void HalfFloat::Set(float inValue) { - Internal::FullFloat full(inValue); - - this->sign = full.sign; - if (full.exponent <= 112) - { - this->exponent = 0; - this->mantissa = 0; - - if (const int32_t newExp = full.exponent - 127 + 15; - 14 - newExp <= 24) - { - const uint32_t tMantissa = full.mantissa | 0x800000; - this->mantissa = static_cast(tMantissa >> (14 - newExp)); - if (((this->mantissa >> (13 - newExp)) & 1) != 0u) - { - ++this->value; - } - } - } - else if (full.exponent >= 143) - { - this->exponent = 30; - this->mantissa = 1023; - } - else - { - this->exponent = static_cast(static_cast(full.exponent) - 127 + 15); - this->mantissa = static_cast(full.mantissa >> 13); - } + this->value = Internal::FloatToHalfBits(inValue); } template float HalfFloat::AsFloat() const { - Internal::FullFloat result; - - result.sign = this->sign; - if (this->exponent == 0) - { - if (const uint32_t tMantissa = this->mantissa; - tMantissa == 0) - { - result.exponent = 0; - result.mantissa = 0; - } - else - { - const uint32_t mantissaShift = 10 - static_cast(std::trunc(std::log2(static_cast(tMantissa)))); - result.exponent = 127 - (15 - 1) - mantissaShift; - result.mantissa = tMantissa << (mantissaShift + 23 - 10); - } - } - else if (this->exponent == 31) - { - result.exponent = 142; - result.mantissa = 8380416; - } - else - { - result.exponent = static_cast(this->exponent) - 15 + 127; - result.mantissa = static_cast(this->mantissa) << 13; - } - return result.value; + return Internal::HalfBitsToFloat(this->value); } template @@ -374,27 +207,27 @@ namespace Common { } template - bool HalfFloat::operator==(const float rhs) const + bool HalfFloat::operator==(float rhs) const { - return std::abs(AsFloat() - rhs) < halfEpsilon; + return AsFloat() == rhs; } template - bool HalfFloat::operator!=(const float rhs) const + bool HalfFloat::operator!=(float rhs) const { - return std::abs(AsFloat() - rhs) >= halfEpsilon; + return !this->operator==(rhs); } template bool HalfFloat::operator==(const HalfFloat& rhs) const { - return std::abs(AsFloat() - rhs.AsFloat()) < halfEpsilon; + return AsFloat() == rhs.AsFloat(); } template bool HalfFloat::operator!=(const HalfFloat& rhs) const { - return std::abs(AsFloat() - rhs.AsFloat()) >= halfEpsilon; + return !this->operator==(rhs); } template @@ -422,25 +255,25 @@ namespace Common { } template - HalfFloat HalfFloat::operator+(const float rhs) const + HalfFloat HalfFloat::operator+(float rhs) const { return { AsFloat() + rhs }; } template - HalfFloat HalfFloat::operator-(const float rhs) const + HalfFloat HalfFloat::operator-(float rhs) const { return { AsFloat() - rhs }; } template - HalfFloat HalfFloat::operator*(const float rhs) const + HalfFloat HalfFloat::operator*(float rhs) const { return { AsFloat() * rhs }; } template - HalfFloat HalfFloat::operator/(const float rhs) const + HalfFloat HalfFloat::operator/(float rhs) const { return { AsFloat() / rhs }; } @@ -470,28 +303,28 @@ namespace Common { } template - HalfFloat& HalfFloat::operator+=(const float rhs) + HalfFloat& HalfFloat::operator+=(float rhs) { Set(AsFloat() + rhs); return *this; } template - HalfFloat& HalfFloat::operator-=(const float rhs) + HalfFloat& HalfFloat::operator-=(float rhs) { Set(AsFloat() - rhs); return *this; } template - HalfFloat& HalfFloat::operator*=(const float rhs) + HalfFloat& HalfFloat::operator*=(float rhs) { Set(AsFloat() * rhs); return *this; } template - HalfFloat& HalfFloat::operator/=(const float rhs) + HalfFloat& HalfFloat::operator/=(float rhs) { Set(AsFloat() / rhs); return *this; diff --git a/Engine/Source/Common/Include/Common/Math/Math.h b/Engine/Source/Common/Include/Common/Math/Math.h index fc68f8f7f..911ac3e3b 100644 --- a/Engine/Source/Common/Include/Common/Math/Math.h +++ b/Engine/Source/Common/Include/Common/Math/Math.h @@ -16,3 +16,4 @@ #include #include #include +#include diff --git a/Engine/Source/Common/Include/Common/Math/Matrix.h b/Engine/Source/Common/Include/Common/Math/Matrix.h index 9d5b7493d..a995584c7 100644 --- a/Engine/Source/Common/Include/Common/Math/Matrix.h +++ b/Engine/Source/Common/Include/Common/Math/Matrix.h @@ -6,8 +6,6 @@ #include #include -#include -#include #include #include @@ -117,15 +115,20 @@ namespace Common { requires ValidSubMatDims Mat SubMatrix() const; - bool CanInverse() const; - Mat Inverse() const; - T Determinant() const; + bool CanInverse(T tolerance = DefaultTolerance()) const requires (R == C && R > 1 && FloatingPoint); + bool TryInverse(Mat& outResult, T tolerance = DefaultTolerance()) const requires (R == C && R > 1 && FloatingPoint); + Mat Inverse(T tolerance = DefaultTolerance()) const requires (R == C && R > 1 && FloatingPoint); + Mat InverseUnchecked() const requires (R == C && R > 1 && FloatingPoint); + T Determinant() const requires (R == C && R > 1); - Vec ExtractTranslation() const; - Vec ExtractScale() const; - Quaternion ExtractRotation() const; + bool TryDecomposeAffine(Vec& outTranslation, Quaternion& outRotation, Vec& outScale, T tolerance = DefaultTolerance()) const requires (R == 4 && C == 4 && FloatingPoint); + Vec ExtractTranslation() const requires (R == 4 && C == 4); + Vec ExtractScale(T tolerance = DefaultTolerance()) const requires (R == 4 && C == 4 && FloatingPoint); + Quaternion ExtractRotation(T tolerance = DefaultTolerance()) const requires (R == 4 && C == 4 && FloatingPoint); }; + template requires FloatingPoint bool AlmostEqual(const Mat& lhs, const Mat& rhs, T absoluteTolerance = DefaultTolerance(), T relativeTolerance = DefaultTolerance()); + template requires ValidMatDims struct MatConsts { @@ -310,83 +313,6 @@ namespace Common { using DMat4x4Consts = MatConsts; } -namespace Common { // NOLINT - template - struct Serializer> { - static constexpr size_t typeId - = HashUtils::StrCrc32("Common::Matrix") - + Serializer::typeId + (R << 8) + C; - - static size_t Serialize(BinarySerializeStream& stream, const Mat& value) - { - auto serialized = 0; - for (auto i = 0; i < R * C; i++) { - serialized += Serializer::Serialize(stream, value.data[i]); - } - return serialized; - } - - static size_t Deserialize(BinaryDeserializeStream& stream, Mat& value) - { - auto deserialized = 0; - for (auto i = 0; i < R * C; i++) { - deserialized += Serializer::Deserialize(stream, value.data[i]); - } - return deserialized; - } - }; - - template - struct StringConverter> { - static std::string ToString(const Mat& inValue) - { - std::stringstream stream; - stream << "("; - for (auto i = 0; i < R; i++) { - for (auto j = 0; j < C; j++) { - stream << StringConverter::ToString(inValue.At(i, j)); - if (i * C + j != R * C - 1) { - stream << ", "; - } - } - } - stream << ")"; - return stream.str(); - } - }; - - template - struct JsonSerializer> { - static void JsonSerialize(rapidjson::Value& outJsonValue, rapidjson::Document::AllocatorType& inAllocator, const Mat& inValue) - { - outJsonValue.SetArray(); - outJsonValue.Reserve(R * C, inAllocator); - for (auto i = 0; i < R; i++) { - for (auto j = 0; j < C; j++) { - rapidjson::Value jsonElement; - JsonSerializer::JsonSerialize(jsonElement, inAllocator, inValue.At(i, j)); - outJsonValue.PushBack(jsonElement, inAllocator); - } - } - } - - static void JsonDeserialize(const rapidjson::Value& inJsonValue, Mat& outValue) - { - if (!inJsonValue.IsArray() || inJsonValue.Size() != R * C) { - return; - } - for (auto i = 0; i < inJsonValue.Size(); i++) { - auto row = i / C; - auto col = i % C; - - T element; - JsonSerializer::JsonDeserialize(inJsonValue[i], element); - outValue.At(row, col) = std::move(element); - } - } - }; -} - namespace Common::Internal { template static void CopyValuesToMatrix(Mat& matrix, VT&&... inValue, std::index_sequence) @@ -438,7 +364,7 @@ namespace Common::Internal { { static_assert(R == sizeof...(VT) && sizeof...(VT) == sizeof...(VI)); (void) std::initializer_list { ([&]() -> void { - static_assert(std::is_same_v>); + static_assert(std::is_same_v, Vec>); CopyVectorToMatrixRow(matrix, VI, inVectors, std::make_index_sequence {}); }(), 0)... }; } @@ -448,7 +374,7 @@ namespace Common::Internal { { static_assert(C == sizeof...(VT) && sizeof...(VT) == sizeof...(VI)); (void) std::initializer_list { ([&]() -> void { - static_assert(std::is_same_v>); + static_assert(std::is_same_v, Vec>); CopyVectorToMatrixCol(matrix, VI, inVectors, std::make_index_sequence {}); }(), 0)... }; } @@ -493,7 +419,12 @@ namespace Common::Internal { { Vec result; for (auto i = 0; i < R; i++) { - result[i] = mat.Row(i).Dot(vec); + const T* row = &mat.data[i * C]; + T value = row[0] * vec.data[0]; + for (auto j = 1; j < C; j++) { + value += row[j] * vec.data[j]; + } + result.data[i] = value; } return result; } @@ -533,11 +464,39 @@ namespace Common::Internal { return result; } + template + bool ScaledDeterminantIsInvertible(T determinant, T scale, T tolerance) + { + const T determinantValue = std::abs(determinant); + const T toleranceValue = std::abs(tolerance); + if (!std::isfinite(scale) || !std::isfinite(determinantValue) || scale == static_cast(0)) { + return false; + } + + T threshold = toleranceValue; + for (auto i = 0; i < R; i++) { + threshold *= scale; + } + return determinantValue > threshold; + } + template - Mat MatInverseScalar(const Mat& m) + bool MatDeterminantIsInvertible(const Mat& m, T determinant, T tolerance) + { + using EvaluationT = std::conditional_t, float, T>; + EvaluationT scale = 0; + for (auto i = 0; i < R * C; i++) { + scale = std::max(scale, std::abs(static_cast(m.data[i]))); + } + return ScaledDeterminantIsInvertible( + static_cast(determinant), scale, static_cast(tolerance)); + } + + template + Mat MatInverseScalar(const Mat& m, T determinant) { static_assert(R == C && R > 1 && R < 5); - T oneOverDet = static_cast(1) / MatDeterminantScalar(m); + T oneOverDet = static_cast(1) / determinant; Mat result; if constexpr (R == 2) { @@ -670,7 +629,19 @@ namespace Common::Internal { static Mat Transpose(const Mat& m) { return MatTransposeScalar(m); } static Vec MulVec(const Mat& m, const Vec& v) { return MatMulVecScalar(m, v); } static T Determinant(const Mat& m) { return MatDeterminantScalar(m); } - static Mat Inverse(const Mat& m) { return MatInverseScalar(m); } + static bool TryInverse(const Mat& m, Mat& outResult, T tolerance) + { + const T determinant = MatDeterminantScalar(m); + if (!MatDeterminantIsInvertible(m, determinant, tolerance)) { + return false; + } + outResult = MatInverseScalar(m, determinant); + return true; + } + static Mat InverseUnchecked(const Mat& m) + { + return MatInverseScalar(m, MatDeterminantScalar(m)); + } }; // Row-major 4x4 float matrix, backed by float[16] (four contiguous rows of 16 bytes each), so each row maps to an @@ -747,7 +718,20 @@ namespace Common::Internal { // (p, q) is (p2*q3 - p3*q2, same, p1*q3 - p3*q1, p1*q2 - p2*q1). The cofactor columns are transposed into rows, // and the determinant is recovered as row0 . (first row of the cofactor matrix), so there is no second // Determinant pass. - static M Inverse(const M& m) + static bool TryInverse(const M& m, M& outResult, float tolerance) + { + return InverseImpl(m, outResult, tolerance, true); + } + + static M InverseUnchecked(const M& m) + { + M result; + InverseImpl(m, result, 0.0f, false); + return result; + } + + private: + static bool InverseImpl(const M& m, M& outResult, float tolerance, bool validate) { const Simd::F32x4 r0 = Simd::LoadU(&m.data[0]); const Simd::F32x4 r1 = Simd::LoadU(&m.data[4]); @@ -788,18 +772,24 @@ namespace Common::Internal { // det = row0 . (column 0 of the cofactor matrix). That column is the col0 register as-is, so compute the // determinant before Transpose4 turns col0 into the cofactor matrix's first row. const float det = Simd::Sum(Simd::Mul(r0, col0)); + if (validate) { + const float scale = Simd::MaxValue(Simd::Max(Simd::Max(Simd::Abs(r0), Simd::Abs(r1)), Simd::Max(Simd::Abs(r2), Simd::Abs(r3)))); + if (!ScaledDeterminantIsInvertible(det, scale, tolerance)) { + return false; + } + } const Simd::F32x4 oneOverDet = Simd::Set1(1.0f / det); Simd::Transpose4(col0, col1, col2, col3); - M result; - Simd::StoreU(&result.data[0], Simd::Mul(col0, oneOverDet)); - Simd::StoreU(&result.data[4], Simd::Mul(col1, oneOverDet)); - Simd::StoreU(&result.data[8], Simd::Mul(col2, oneOverDet)); - Simd::StoreU(&result.data[12], Simd::Mul(col3, oneOverDet)); - return result; + Simd::StoreU(&outResult.data[0], Simd::Mul(col0, oneOverDet)); + Simd::StoreU(&outResult.data[4], Simd::Mul(col1, oneOverDet)); + Simd::StoreU(&outResult.data[8], Simd::Mul(col2, oneOverDet)); + Simd::StoreU(&outResult.data[12], Simd::Mul(col3, oneOverDet)); + return true; } + public: static float Determinant(const M& m) { return MatDeterminantScalar(m); } }; @@ -871,7 +861,16 @@ namespace Common::Internal { return result; } - static M Inverse(const M& m) { return MatInverseScalar(m); } + static bool TryInverse(const M& m, M& outResult, float tolerance) + { + const float determinant = MatDeterminantScalar(m); + if (!MatDeterminantIsInvertible(m, determinant, tolerance)) { + return false; + } + outResult = MatInverseScalar(m, determinant); + return true; + } + static M InverseUnchecked(const M& m) { return MatInverseScalar(m, MatDeterminantScalar(m)); } static float Determinant(const M& m) { return MatDeterminantScalar(m); } }; } @@ -959,7 +958,7 @@ namespace Common { { bool result = true; for (auto i = 0; i < R * C; i++) { - result = result && CompareNumber(this->data[i], rhs); + result = result && this->data[i] == rhs; } return result; } @@ -969,7 +968,7 @@ namespace Common { { bool result = true; for (auto i = 0; i < R * C; i++) { - result = result && CompareNumber(this->data[i], rhs.data[i]); + result = result && this->data[i] == rhs.data[i]; } return result; } @@ -1180,80 +1179,142 @@ namespace Common { return Internal::MatOps::Transpose(*this); } - template - Vec Mat::ExtractTranslation() const + template + bool Mat::TryDecomposeAffine(Vec& outTranslation, Quaternion& outRotation, Vec& outScale, T tolerance) const requires (R == 4 && C == 4 && FloatingPoint) { - static_assert( R == 4 && C == 4); - Vec ret = Vec(this->data[3], this->data[7], this->data[11]); - return ret; - } + using EvaluationT = std::conditional_t, float, T>; + + const EvaluationT toleranceValue = std::abs(static_cast(tolerance)); + const EvaluationT m30 = static_cast(this->data[12]); + const EvaluationT m31 = static_cast(this->data[13]); + const EvaluationT m32 = static_cast(this->data[14]); + const EvaluationT m33 = static_cast(this->data[15]); + const EvaluationT tx = static_cast(this->data[3]); + const EvaluationT ty = static_cast(this->data[7]); + const EvaluationT tz = static_cast(this->data[11]); + if (!std::isfinite(tx) || !std::isfinite(ty) || !std::isfinite(tz) + || !std::isfinite(m30) || !std::isfinite(m31) || !std::isfinite(m32) || !std::isfinite(m33) + || std::abs(m30) > toleranceValue || std::abs(m31) > toleranceValue || std::abs(m32) > toleranceValue + || std::abs(m33 - static_cast(1)) > toleranceValue) { + return false; + } - template - Quaternion Mat::ExtractRotation() const - { - static_assert( R == 4 && C == 4); - Quaternion ret = Quaternion(1, 0, 0, 0); - - T sx = Vec(this->data[0], this->data[4], this->data[8]).Model(); - T sy = Vec(this->data[1], this->data[5], this->data[9]).Model(); - T sz = Vec(this->data[2], this->data[6], this->data[10]).Model(); - T det = this->Determinant(); - if (det < 0) { + const EvaluationT c00 = static_cast(this->data[0]); + const EvaluationT c01 = static_cast(this->data[4]); + const EvaluationT c02 = static_cast(this->data[8]); + const EvaluationT c10 = static_cast(this->data[1]); + const EvaluationT c11 = static_cast(this->data[5]); + const EvaluationT c12 = static_cast(this->data[9]); + const EvaluationT c20 = static_cast(this->data[2]); + const EvaluationT c21 = static_cast(this->data[6]); + const EvaluationT c22 = static_cast(this->data[10]); + + EvaluationT sx = std::sqrt(c00 * c00 + c01 * c01 + c02 * c02); + const EvaluationT sy = std::sqrt(c10 * c10 + c11 * c11 + c12 * c12); + const EvaluationT sz = std::sqrt(c20 * c20 + c21 * c21 + c22 * c22); + const EvaluationT maxScale = std::max(sx, std::max(sy, sz)); + const EvaluationT scaleThreshold = toleranceValue * maxScale; + if (!std::isfinite(maxScale) || maxScale == static_cast(0) + || sx <= scaleThreshold || sy <= scaleThreshold || sz <= scaleThreshold) { + return false; + } + + const EvaluationT determinant = c00 * (c11 * c22 - c12 * c21) + - c10 * (c01 * c22 - c02 * c21) + + c20 * (c01 * c12 - c02 * c11); + if (!std::isfinite(determinant) || std::abs(determinant) <= toleranceValue * sx * sy * sz) { + return false; + } + if (determinant < static_cast(0)) { sx = -sx; } - T m11 = this->data[0] / sx, m21 = this->data[4] / sx, m31 = this->data[8] / sx; - T m12 = this->data[1] / sy, m22 = this->data[5] / sy, m32 = this->data[9] / sy; - T m13 = this->data[2] / sz, m23 = this->data[6] / sz, m33 = this->data[10] / sz; - - // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm - // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) - T trace = m11 + m22 + m33; - if (trace > 0) { - T s = 0.5 / std::sqrt(trace + 1.0); - ret.w = 0.25 / s; - ret.x = (m32 - m23) * s; - ret.y = (m13 - m31) * s; - ret.z = (m21 - m12) * s; - } else if (m11 > m22 && m11 > m33) { - T s = 2.0 * std::sqrt(1.0 + m11 - m22 - m33); - ret.w = ( m32 - m23 ) / s; - ret.x = 0.25 * s; - ret.y = ( m12 + m21 ) / s; - ret.z = ( m13 + m31 ) / s; - } else if (m22 > m33) { - T s = 2.0 * std::sqrt( 1.0 + m22 - m11 - m33 ); - ret.w = ( m13 - m31 ) / s; - ret.x = ( m12 + m21 ) / s; - ret.y = 0.25 * s; - ret.z = ( m23 + m32 ) / s; + const EvaluationT m11 = c00 / sx, m21 = c01 / sx, m31n = c02 / sx; + const EvaluationT m12 = c10 / sy, m22 = c11 / sy, m32n = c12 / sy; + const EvaluationT m13 = c20 / sz, m23 = c21 / sz, m33n = c22 / sz; + if (std::abs(m11 * m12 + m21 * m22 + m31n * m32n) > toleranceValue + || std::abs(m11 * m13 + m21 * m23 + m31n * m33n) > toleranceValue + || std::abs(m12 * m13 + m22 * m23 + m32n * m33n) > toleranceValue) { + return false; + } + + EvaluationT qw; + EvaluationT qx; + EvaluationT qy; + EvaluationT qz; + const EvaluationT trace = m11 + m22 + m33n; + if (trace > static_cast(0)) { + const EvaluationT s = static_cast(0.5) / std::sqrt(trace + static_cast(1)); + qw = static_cast(0.25) / s; + qx = (m32n - m23) * s; + qy = (m13 - m31n) * s; + qz = (m21 - m12) * s; + } else if (m11 > m22 && m11 > m33n) { + const EvaluationT s = static_cast(2) * std::sqrt(std::max(static_cast(0), static_cast(1) + m11 - m22 - m33n)); + if (s <= toleranceValue) { + return false; + } + qw = (m32n - m23) / s; + qx = static_cast(0.25) * s; + qy = (m12 + m21) / s; + qz = (m13 + m31n) / s; + } else if (m22 > m33n) { + const EvaluationT s = static_cast(2) * std::sqrt(std::max(static_cast(0), static_cast(1) + m22 - m11 - m33n)); + if (s <= toleranceValue) { + return false; + } + qw = (m13 - m31n) / s; + qx = (m12 + m21) / s; + qy = static_cast(0.25) * s; + qz = (m23 + m32n) / s; } else { - T s = 2.0 * std::sqrt( 1.0 + m33 - m11 - m22 ); - ret.w = ( m21 - m12 ) / s; - ret.x = ( m13 + m31 ) / s; - ret.y = ( m23 + m32 ) / s; - ret.z = 0.25 * s; + const EvaluationT s = static_cast(2) * std::sqrt(std::max(static_cast(0), static_cast(1) + m33n - m11 - m22)); + if (s <= toleranceValue) { + return false; + } + qw = (m21 - m12) / s; + qx = (m13 + m31n) / s; + qy = (m23 + m32n) / s; + qz = static_cast(0.25) * s; + } + + Quaternion rotation(static_cast(qw), static_cast(qx), static_cast(qy), static_cast(qz)); + if (!rotation.TryNormalize(tolerance)) { + return false; } - return ret; + outTranslation = Vec(this->data[3], this->data[7], this->data[11]); + outRotation = rotation; + outScale = Vec(static_cast(sx), static_cast(sy), static_cast(sz)); + return true; } - template - Vec Mat::ExtractScale() const + template + Vec Mat::ExtractTranslation() const requires (R == 4 && C == 4) { - static_assert( R == 4 && C == 4); - - T sx = Vec(this->data[0], this->data[4], this->data[8]).Model(); - T sy = Vec(this->data[1], this->data[5], this->data[9]).Model(); - T sz = Vec(this->data[2], this->data[6], this->data[10]).Model(); + return Vec(this->data[3], this->data[7], this->data[11]); + } - T det = this->Determinant(); - if (det < 0) { - sx = -sx; - } - Vec ret = Vec(sx, sy, sz); + template + Quaternion Mat::ExtractRotation(T tolerance) const requires (R == 4 && C == 4 && FloatingPoint) + { + Vec translation; + Quaternion rotation; + Vec scale; + const bool decomposed = TryDecomposeAffine(translation, rotation, scale, tolerance); + Assert(decomposed); + return rotation; + } - return ret; + template + Vec Mat::ExtractScale(T tolerance) const requires (R == 4 && C == 4 && FloatingPoint) + { + Vec translation; + Quaternion rotation; + Vec scale; + const bool decomposed = TryDecomposeAffine(translation, rotation, scale, tolerance); + Assert(decomposed); + return scale; } template @@ -1272,23 +1333,51 @@ namespace Common { template - bool Mat::CanInverse() const + bool Mat::CanInverse(T tolerance) const requires (R == C && R > 1 && FloatingPoint) + { + const T determinant = this->Determinant(); + return Internal::MatDeterminantIsInvertible(*this, determinant, tolerance); + } + + template + bool Mat::TryInverse(Mat& outResult, T tolerance) const requires (R == C && R > 1 && FloatingPoint) + { + return Internal::MatOps::TryInverse(*this, outResult, tolerance); + } + + template + Mat Mat::Inverse(T tolerance) const requires (R == C && R > 1 && FloatingPoint) { - return this->Determinant() != static_cast(0); + Mat result; + const bool invertible = TryInverse(result, tolerance); + Assert(invertible); + return result; } template - Mat Mat::Inverse() const + Mat Mat::InverseUnchecked() const requires (R == C && R > 1 && FloatingPoint) { - return Internal::MatOps::Inverse(*this); + return Internal::MatOps::InverseUnchecked(*this); } template - T Mat::Determinant() const + T Mat::Determinant() const requires (R == C && R > 1) { return Internal::MatOps::Determinant(*this); } + template + requires FloatingPoint + bool AlmostEqual(const Mat& lhs, const Mat& rhs, T absoluteTolerance, T relativeTolerance) + { + for (auto i = 0; i < R * C; i++) { + if (!AlmostEqual(lhs.data[i], rhs.data[i], absoluteTolerance, relativeTolerance)) { + return false; + } + } + return true; + } + template requires ValidMatDims const Mat MatConsts::zero = Mat(0); diff --git a/Engine/Source/Common/Include/Common/Math/Projection.h b/Engine/Source/Common/Include/Common/Math/Projection.h index 1fcc63b0c..fbae87e58 100644 --- a/Engine/Source/Common/Include/Common/Math/Projection.h +++ b/Engine/Source/Common/Include/Common/Math/Projection.h @@ -8,8 +8,6 @@ #include #include -#include -#include namespace Common { template @@ -47,6 +45,10 @@ namespace Common { bool operator==(const ReversedZPerspectiveProjection& inRhs) const; }; + template requires FloatingPoint bool AlmostEqual(const ReversedZOrthogonalProjection& lhs, const ReversedZOrthogonalProjection& rhs, T absoluteTolerance = DefaultTolerance(), T relativeTolerance = DefaultTolerance()); + + template requires FloatingPoint bool AlmostEqual(const ReversedZPerspectiveProjection& lhs, const ReversedZPerspectiveProjection& rhs, T absoluteTolerance = DefaultTolerance(), T relativeTolerance = DefaultTolerance()); + using HReversedZOrthoProjection = ReversedZOrthogonalProjection; using FReversedZOrthoProjection = ReversedZOrthogonalProjection; using DReversedZOrthoProjection = ReversedZOrthogonalProjection; @@ -56,188 +58,6 @@ namespace Common { using DReversedZPerspectiveProjection = ReversedZPerspectiveProjection; } -namespace Common { - template - struct Serializer> { - static constexpr size_t typeId - = HashUtils::StrCrc32("Common::ReversedZOrthogonalProjection") - + Serializer::typeId; - - static size_t Serialize(BinarySerializeStream& stream, const ReversedZOrthogonalProjection& value) - { - size_t serialized = 0; - serialized += Serializer::Serialize(stream, value.width); - serialized += Serializer::Serialize(stream, value.height); - serialized += Serializer::Serialize(stream, value.nearPlane); - serialized += Serializer>::Serialize(stream, value.farPlane); - return serialized; - } - - static size_t Deserialize(BinaryDeserializeStream& stream, ReversedZOrthogonalProjection& value) - { - size_t deserialized = 0; - deserialized += Serializer::Deserialize(stream, value.width); - deserialized += Serializer::Deserialize(stream, value.height); - deserialized += Serializer::Deserialize(stream, value.nearPlane); - deserialized += Serializer>::Deserialize(stream, value.farPlane); - return deserialized; - } - }; - - template - struct Serializer> { - static constexpr size_t typeId - = HashUtils::StrCrc32("Common::ReversedZPerspectiveProjection") - + Serializer::typeId; - - static size_t Serialize(BinarySerializeStream& stream, const ReversedZPerspectiveProjection& value) - { - size_t serialized = 0; - serialized += Serializer::Serialize(stream, value.fov); - serialized += Serializer::Serialize(stream, value.width); - serialized += Serializer::Serialize(stream, value.height); - serialized += Serializer::Serialize(stream, value.nearPlane); - serialized += Serializer>::Serialize(stream, value.farPlane); - return serialized; - } - - static size_t Deserialize(BinaryDeserializeStream& stream, ReversedZPerspectiveProjection& value) - { - size_t deserialized = 0; - deserialized += Serializer::Deserialize(stream, value.fov); - deserialized += Serializer::Deserialize(stream, value.width); - deserialized += Serializer::Deserialize(stream, value.height); - deserialized += Serializer::Deserialize(stream, value.nearPlane); - deserialized += Serializer>::Deserialize(stream, value.farPlane); - return deserialized; - } - }; - - template - struct StringConverter> { - static std::string ToString(const ReversedZOrthogonalProjection& inValue) - { - return std::format( - "{}width={}, height={}, near={}, far={}{}", - "{", - StringConverter::ToString(inValue.width), - StringConverter::ToString(inValue.height), - StringConverter::ToString(inValue.nearPlane), - StringConverter>::ToString(inValue.farPlane), - "}"); - } - }; - - template - struct StringConverter> { - static std::string ToString(const ReversedZPerspectiveProjection& inValue) - { - return std::format( - "{}fov={}, width={}, height={}, near={}, far={}{}", - "{", - StringConverter::ToString(inValue.fov), - StringConverter::ToString(inValue.width), - StringConverter::ToString(inValue.height), - StringConverter::ToString(inValue.nearPlane), - StringConverter>::ToString(inValue.farPlane), - "}"); - } - }; - - template - struct JsonSerializer> { - static void JsonSerialize(rapidjson::Value& outJsonValue, rapidjson::Document::AllocatorType& inAllocator, const ReversedZOrthogonalProjection& inValue) - { - rapidjson::Value widthJson; - JsonSerializer::JsonSerialize(widthJson, inAllocator, inValue.width); - - rapidjson::Value heightJson; - JsonSerializer::JsonSerialize(heightJson, inAllocator, inValue.height); - - rapidjson::Value nearJson; - JsonSerializer::JsonSerialize(nearJson, inAllocator, inValue.nearPlane); - - rapidjson::Value farJson; - JsonSerializer>::JsonSerialize(farJson, inAllocator, inValue.farPlane); - - outJsonValue.SetObject(); - outJsonValue.AddMember("width", widthJson, inAllocator); - outJsonValue.AddMember("height", heightJson, inAllocator); - outJsonValue.AddMember("near", nearJson, inAllocator); - outJsonValue.AddMember("far", farJson, inAllocator); - } - - static void JsonDeserialize(const rapidjson::Value& inJsonValue, ReversedZOrthogonalProjection& outValue) - { - if (!inJsonValue.IsObject()) { - return; - } - if (inJsonValue.HasMember("width")) { - JsonSerializer::JsonDeserialize(inJsonValue["width"], outValue.width); - } - if (inJsonValue.HasMember("height")) { - JsonSerializer::JsonDeserialize(inJsonValue["height"], outValue.height); - } - if (inJsonValue.HasMember("near")) { - JsonSerializer::JsonDeserialize(inJsonValue["near"], outValue.nearPlane); - } - if (inJsonValue.HasMember("far")) { - JsonSerializer>::JsonDeserialize(inJsonValue["far"], outValue.farPlane); - } - } - }; - - template - struct JsonSerializer> { - static void JsonSerialize(rapidjson::Value& outJsonValue, rapidjson::Document::AllocatorType& inAllocator, const ReversedZPerspectiveProjection& inValue) - { - rapidjson::Value fovJson; - JsonSerializer::JsonSerialize(fovJson, inAllocator, inValue.fov); - - rapidjson::Value widthJson; - JsonSerializer::JsonSerialize(widthJson, inAllocator, inValue.width); - - rapidjson::Value heightJson; - JsonSerializer::JsonSerialize(heightJson, inAllocator, inValue.height); - - rapidjson::Value nearJson; - JsonSerializer::JsonSerialize(nearJson, inAllocator, inValue.nearPlane); - - rapidjson::Value farJson; - JsonSerializer>::JsonSerialize(farJson, inAllocator, inValue.farPlane); - - outJsonValue.SetObject(); - outJsonValue.AddMember("fov", fovJson, inAllocator); - outJsonValue.AddMember("width", widthJson, inAllocator); - outJsonValue.AddMember("height", heightJson, inAllocator); - outJsonValue.AddMember("near", nearJson, inAllocator); - outJsonValue.AddMember("far", farJson, inAllocator); - } - - static void JsonDeserialize(const rapidjson::Value& inJsonValue, ReversedZPerspectiveProjection& outValue) - { - if (!inJsonValue.IsObject()) { - return; - } - if (inJsonValue.HasMember("fov")) { - JsonSerializer::JsonDeserialize(inJsonValue["fov"], outValue.fov); - } - if (inJsonValue.HasMember("width")) { - JsonSerializer::JsonDeserialize(inJsonValue["width"], outValue.width); - } - if (inJsonValue.HasMember("height")) { - JsonSerializer::JsonDeserialize(inJsonValue["height"], outValue.height); - } - if (inJsonValue.HasMember("near")) { - JsonSerializer::JsonDeserialize(inJsonValue["near"], outValue.nearPlane); - } - if (inJsonValue.HasMember("far")) { - JsonSerializer>::JsonDeserialize(inJsonValue["far"], outValue.farPlane); - } - } - }; -} - namespace Common { template ReversedZOrthogonalProjection::ReversedZOrthogonalProjection() @@ -286,13 +106,13 @@ namespace Common { if (thisHasFar && !rhsHasFar || !thisHasFar && rhsHasFar) { return false; } - if (thisHasFar && !CompareNumber(this->farPlane.value(), inRhs.farPlane.value())) { + if (thisHasFar && this->farPlane.value() != inRhs.farPlane.value()) { return false; } - return CompareNumber(this->width, inRhs.width) - && CompareNumber(this->height, inRhs.height) - && CompareNumber(this->nearPlane, inRhs.nearPlane); + return this->width == inRhs.width + && this->height == inRhs.height + && this->nearPlane == inRhs.nearPlane; } template @@ -347,13 +167,40 @@ namespace Common { if (thisHasFar && !rhsHasFar || !thisHasFar && rhsHasFar) { return false; } - if (thisHasFar && !CompareNumber(this->farPlane.value(), inRhs.farPlane.value())) { + if (thisHasFar && this->farPlane.value() != inRhs.farPlane.value()) { return false; } - return CompareNumber(this->fov, inRhs.fov) - && CompareNumber(this->width, inRhs.width) - && CompareNumber(this->height, inRhs.height) - && CompareNumber(this->nearPlane, inRhs.nearPlane); + return this->fov == inRhs.fov + && this->width == inRhs.width + && this->height == inRhs.height + && this->nearPlane == inRhs.nearPlane; + } + + template + requires FloatingPoint + bool AlmostEqual(const ReversedZOrthogonalProjection& lhs, const ReversedZOrthogonalProjection& rhs, T absoluteTolerance, T relativeTolerance) + { + if (lhs.farPlane.has_value() != rhs.farPlane.has_value()) { + return false; + } + return (!lhs.farPlane.has_value() || AlmostEqual(lhs.farPlane.value(), rhs.farPlane.value(), absoluteTolerance, relativeTolerance)) + && AlmostEqual(lhs.width, rhs.width, absoluteTolerance, relativeTolerance) + && AlmostEqual(lhs.height, rhs.height, absoluteTolerance, relativeTolerance) + && AlmostEqual(lhs.nearPlane, rhs.nearPlane, absoluteTolerance, relativeTolerance); + } + + template + requires FloatingPoint + bool AlmostEqual(const ReversedZPerspectiveProjection& lhs, const ReversedZPerspectiveProjection& rhs, T absoluteTolerance, T relativeTolerance) + { + if (lhs.farPlane.has_value() != rhs.farPlane.has_value()) { + return false; + } + return (!lhs.farPlane.has_value() || AlmostEqual(lhs.farPlane.value(), rhs.farPlane.value(), absoluteTolerance, relativeTolerance)) + && AlmostEqual(lhs.fov, rhs.fov, absoluteTolerance, relativeTolerance) + && AlmostEqual(lhs.width, rhs.width, absoluteTolerance, relativeTolerance) + && AlmostEqual(lhs.height, rhs.height, absoluteTolerance, relativeTolerance) + && AlmostEqual(lhs.nearPlane, rhs.nearPlane, absoluteTolerance, relativeTolerance); } } diff --git a/Engine/Source/Common/Include/Common/Math/Quaternion.h b/Engine/Source/Common/Include/Common/Math/Quaternion.h index 605cc194d..f72f8dbd6 100644 --- a/Engine/Source/Common/Include/Common/Math/Quaternion.h +++ b/Engine/Source/Common/Include/Common/Math/Quaternion.h @@ -9,8 +9,6 @@ #include #include #include -#include -#include namespace Common { template struct Angle; @@ -71,7 +69,7 @@ namespace Common { Quaternion(); Quaternion(T inW, T inX, T inY, T inZ); - Quaternion(const Vec& inAxis, float inAngle); + Quaternion(const Vec& inAxis, T inAngle); Quaternion(const Vec& inAxis, const Radian& inRadian); Quaternion(const Quaternion& inValue) = default; Quaternion(Quaternion&& inValue) noexcept = default; @@ -92,10 +90,14 @@ namespace Common { Quaternion& operator/=(T rhs); Vec ImaginaryPart() const; + T ModelSquared() const; T Model() const; + bool IsNormalized(T tolerance = DefaultTolerance()) const; Quaternion Negatived() const; Quaternion Conjugated() const; Quaternion Normalized() const; + bool TryNormalize(T tolerance = DefaultTolerance()); + void Normalize(); T Dot(const Quaternion& rhs) const; // when axis faced to us, ccw as positive direction Vec RotateVector(const Vec& inVector) const; @@ -106,6 +108,12 @@ namespace Common { Quaternion CastTo() const; }; + template requires FloatingPoint bool AlmostEqual(const Angle& lhs, const Angle& rhs, T absoluteTolerance = DefaultTolerance(), T relativeTolerance = DefaultTolerance()); + + template requires FloatingPoint bool AlmostEqual(const Radian& lhs, const Radian& rhs, T absoluteTolerance = DefaultTolerance(), T relativeTolerance = DefaultTolerance()); + + template requires FloatingPoint bool AlmostEqual(const Quaternion& lhs, const Quaternion& rhs, T absoluteTolerance = DefaultTolerance(), T relativeTolerance = DefaultTolerance()); + template struct QuatConsts { static const Quaternion zero; @@ -129,159 +137,6 @@ namespace Common { using DQuatConsts = QuatConsts; } -namespace Common { - template - struct Serializer> { - static constexpr size_t typeId - = HashUtils::StrCrc32("Common::Angle") - + Serializer::typeId; - - static size_t Serialize(BinarySerializeStream& stream, const Angle& value) - { - return Serializer::Serialize(stream, value.value); - } - - static size_t Deserialize(BinaryDeserializeStream& stream, Angle& value) - { - return Serializer::Deserialize(stream, value.value); - } - }; - - template - struct Serializer> { - static constexpr size_t typeId - = HashUtils::StrCrc32("Common::Radian") - + Serializer::typeId; - - static size_t Serialize(BinarySerializeStream& stream, const Radian& value) - { - return Serializer::Serialize(stream, value.value); - } - - static size_t Deserialize(BinaryDeserializeStream& stream, Radian& value) - { - return Serializer::Deserialize(stream, value.value); - } - }; - - template - struct Serializer> { - static constexpr size_t typeId - = HashUtils::StrCrc32("Common::Quaternion") - + Serializer::typeId; - - static size_t Serialize(BinarySerializeStream& stream, const Quaternion& value) - { - size_t serialized = 0; - serialized += Serializer::Serialize(stream, value.w); - serialized += Serializer::Serialize(stream, value.x); - serialized += Serializer::Serialize(stream, value.y); - serialized += Serializer::Serialize(stream, value.z); - return serialized; - } - - static size_t Deserialize(BinaryDeserializeStream& stream, Quaternion& value) - { - size_t deserialized = 0; - deserialized += Serializer::Deserialize(stream, value.w); - deserialized += Serializer::Deserialize(stream, value.x); - deserialized += Serializer::Deserialize(stream, value.y); - deserialized += Serializer::Deserialize(stream, value.z); - return deserialized; - } - }; - - template - struct StringConverter> { - static std::string ToString(const Angle& inValue) - { - return std::format("a{}", StringConverter::ToString(inValue.value)); - } - }; - - template - struct StringConverter> { - static std::string ToString(const Radian& inValue) - { - return StringConverter::ToString(inValue.value); - } - }; - - template - struct StringConverter> { - static std::string ToString(const Quaternion& inValue) - { - return std::format( - "({}, {}, {}, {})", - StringConverter::ToString(inValue.w), - StringConverter::ToString(inValue.x), - StringConverter::ToString(inValue.y), - StringConverter::ToString(inValue.z)); - } - }; - - template - struct JsonSerializer> { - static void JsonSerialize(rapidjson::Value& outJsonValue, rapidjson::Document::AllocatorType& inAllocator, const Angle& inValue) - { - JsonSerializer::JsonSerialize(outJsonValue, inAllocator, inValue.value); - } - - static void JsonDeserialize(const rapidjson::Value& inJsonValue, Angle& outValue) - { - JsonSerializer::JsonDeserialize(inJsonValue, outValue.value); - } - }; - - template - struct JsonSerializer> { - static void JsonSerialize(rapidjson::Value& outJsonValue, rapidjson::Document::AllocatorType& inAllocator, const Radian& inValue) - { - JsonSerializer::JsonSerialize(outJsonValue, inAllocator, inValue.value); - } - - static void JsonDeserialize(const rapidjson::Value& inJsonValue, Radian& outValue) - { - JsonSerializer::JsonDeserialize(inJsonValue, outValue.value); - } - }; - - template - struct JsonSerializer> { - static void JsonSerialize(rapidjson::Value& outJsonValue, rapidjson::Document::AllocatorType& inAllocator, const Quaternion& inValue) - { - rapidjson::Value xJson; - JsonSerializer::JsonSerialize(xJson, inAllocator, inValue.w); - - rapidjson::Value yJson; - JsonSerializer::JsonSerialize(yJson, inAllocator, inValue.x); - - rapidjson::Value zJson; - JsonSerializer::JsonSerialize(zJson, inAllocator, inValue.y); - - rapidjson::Value wJson; - JsonSerializer::JsonSerialize(wJson, inAllocator, inValue.z); - - outJsonValue.SetArray(); - outJsonValue.PushBack(xJson, inAllocator); - outJsonValue.PushBack(yJson, inAllocator); - outJsonValue.PushBack(zJson, inAllocator); - outJsonValue.PushBack(wJson, inAllocator); - } - - static void JsonDeserialize(const rapidjson::Value& inJsonValue, Quaternion& outValue) - { - if (!inJsonValue.IsArray() || inJsonValue.Size() != 4) { - return; - } - JsonSerializer::JsonDeserialize(inJsonValue[0], outValue.w); - JsonSerializer::JsonDeserialize(inJsonValue[1], outValue.x); - JsonSerializer::JsonDeserialize(inJsonValue[2], outValue.y); - JsonSerializer::JsonDeserialize(inJsonValue[3], outValue.z); - } - }; -} - namespace Common::Internal { // Per-backend dispatch for quaternion arithmetic. The primary template is the scalar implementation, so any // (T, B) without a specialization degrades gracefully to scalar; the SIMD specialization follows immediately after. @@ -405,35 +260,31 @@ namespace Common { Angle::Angle(const Radian& inValue) : Angle(inValue.ToAngle()) {} template - Angle::Angle(const Angle& inValue) : Angle(inValue.value) {} + Angle::Angle(const Angle& inValue) = default; template - Angle::Angle(Angle&& inValue) noexcept : Angle(inValue.value) {} + Angle::Angle(Angle&& inValue) noexcept = default; template - Angle& Angle::operator=(const Angle& inValue) - { - this->value = inValue.value; - return *this; - } + Angle& Angle::operator=(const Angle& inValue) = default; template Angle& Angle::operator=(const Radian& inValue) { - this->value = inValue.value; + this->value = inValue.ToAngle(); return *this; } template bool Angle::operator==(const Angle& inRhs) const { - return CompareNumber(this->value, inRhs.value); + return this->value == inRhs.value; } template T Angle::ToRadian() const { - return this->value / 180.0f * pi; + return this->value / static_cast(180) * Pi(); } template @@ -452,35 +303,31 @@ namespace Common { Radian::Radian(const Angle& inValue) : Radian(inValue.ToRadian()) {} template - Radian::Radian(const Radian& inValue) : Radian(inValue.value) {} + Radian::Radian(const Radian& inValue) = default; template - Radian::Radian(Radian&& inValue) noexcept : Radian(inValue.value) {} + Radian::Radian(Radian&& inValue) noexcept = default; template - Radian& Radian::operator=(const Radian& inValue) - { - this->value = inValue.value; - return *this; - } + Radian& Radian::operator=(const Radian& inValue) = default; template Radian& Radian::operator=(const Angle& inValue) { - this->value = inValue.value; + this->value = inValue.ToRadian(); return *this; } template bool Radian::operator==(const Radian& inRhs) const { - return CompareNumber(this->value, inRhs.value); + return this->value == inRhs.value; } template T Radian::ToAngle() const { - return this->value * 180.0f / pi; + return this->value * static_cast(180) / Pi(); } template @@ -522,12 +369,20 @@ namespace Common { } template - Quaternion::Quaternion(const Vec& inAxis, float inAngle) - { - Vec axis = inAxis.Normalized(); - T halfRadian = Angle(inAngle).ToRadian() / 2.0f; - T halfRadianSin = std::sin(halfRadian); - T halfRadianCos = std::cos(halfRadian); + Quaternion::Quaternion(const Vec& inAxis, T inAngle) + { + Vec axis = inAxis; + if (!axis.TryNormalize()) { + Assert(false); + this->w = 1; + this->x = 0; + this->y = 0; + this->z = 0; + return; + } + const T halfRadian = Angle(inAngle).ToRadian() / static_cast(2); + const T halfRadianSin = std::sin(halfRadian); + const T halfRadianCos = std::cos(halfRadian); this->w = halfRadianCos; this->x = axis.x * halfRadianSin; @@ -544,10 +399,10 @@ namespace Common { template bool Quaternion::operator==(const Quaternion& rhs) const { - return CompareNumber(this->w, rhs.w) - && CompareNumber(this->x, rhs.x) - && CompareNumber(this->y, rhs.y) - && CompareNumber(this->z, rhs.z); + return this->w == rhs.w + && this->x == rhs.x + && this->y == rhs.y + && this->z == rhs.z; } template @@ -630,7 +485,22 @@ namespace Common { template T Quaternion::Model() const { - return std::sqrt(Internal::QuatOps::Dot(*this, *this)); + return std::sqrt(ModelSquared()); + } + + template + T Quaternion::ModelSquared() const + { + return Internal::QuatOps::Dot(*this, *this); + } + + template + bool Quaternion::IsNormalized(T tolerance) const + { + using EvaluationT = std::conditional_t, float, T>; + const EvaluationT modelSquared = static_cast(ModelSquared()); + const EvaluationT toleranceValue = std::abs(static_cast(tolerance)); + return std::isfinite(modelSquared) && std::abs(modelSquared - static_cast(1)) <= toleranceValue; } template @@ -658,7 +528,31 @@ namespace Common { template Quaternion Quaternion::Normalized() const { - return this->operator/(Model()); + Quaternion result(*this); + result.Normalize(); + return result; + } + + template + bool Quaternion::TryNormalize(T tolerance) + { + const T modelSquared = ModelSquared(); + const double modelSquaredValue = static_cast(modelSquared); + const double toleranceValue = static_cast(tolerance); + if (!std::isfinite(modelSquaredValue) || modelSquaredValue <= toleranceValue * toleranceValue) { + return false; + } + + const T oneOverModel = static_cast(1) / static_cast(std::sqrt(modelSquared)); + *this = Internal::QuatOps::MulScalar(*this, oneOverModel); + return true; + } + + template + void Quaternion::Normalize() + { + const bool normalized = TryNormalize(); + Assert(normalized); } template @@ -670,16 +564,16 @@ namespace Common { template Vec Quaternion::RotateVector(const Vec& inVector) const { - Quaternion v = Quaternion(0, inVector.x, inVector.y, inVector.z); - Quaternion v2 = Conjugated() * v * (*this); - return Vec(v2.x, v2.y, v2.z); + const Vec imaginary = ImaginaryPart(); + const Vec twiceCross = inVector.Cross(imaginary) * static_cast(2); + return inVector + twiceCross * this->w + twiceCross.Cross(imaginary); } template Vec Quaternion::ToEulerZYX() const { const T normSquared = Dot(*this); - if (CompareNumber(normSquared, T(0.0f))) { + if (normSquared == static_cast(0)) { return VecConsts::zero; } @@ -727,4 +621,28 @@ namespace Common { result.z = static_cast(this->z); return result; } + + template + requires FloatingPoint + bool AlmostEqual(const Angle& lhs, const Angle& rhs, T absoluteTolerance, T relativeTolerance) + { + return AlmostEqual(lhs.value, rhs.value, absoluteTolerance, relativeTolerance); + } + + template + requires FloatingPoint + bool AlmostEqual(const Radian& lhs, const Radian& rhs, T absoluteTolerance, T relativeTolerance) + { + return AlmostEqual(lhs.value, rhs.value, absoluteTolerance, relativeTolerance); + } + + template + requires FloatingPoint + bool AlmostEqual(const Quaternion& lhs, const Quaternion& rhs, T absoluteTolerance, T relativeTolerance) + { + return AlmostEqual(lhs.w, rhs.w, absoluteTolerance, relativeTolerance) + && AlmostEqual(lhs.x, rhs.x, absoluteTolerance, relativeTolerance) + && AlmostEqual(lhs.y, rhs.y, absoluteTolerance, relativeTolerance) + && AlmostEqual(lhs.z, rhs.z, absoluteTolerance, relativeTolerance); + } } diff --git a/Engine/Source/Common/Include/Common/Math/Rect.h b/Engine/Source/Common/Include/Common/Math/Rect.h index 4974b0dd7..d17fa0909 100644 --- a/Engine/Source/Common/Include/Common/Math/Rect.h +++ b/Engine/Source/Common/Include/Common/Math/Rect.h @@ -5,8 +5,6 @@ #pragma once #include -#include -#include namespace Common { template @@ -33,9 +31,9 @@ namespace Common { Vec Center() const; T CenterX() const; T CenterY() const; - T Distance(const Rect& inOther) const; + T Distance(const Rect& inOther) const requires FloatingPoint; // half of diagonal - T Size() const; + T Size() const requires FloatingPoint; bool Inside(const Vec& inPoint) const; bool Intersect(const Rect& inOther) const; bool operator==(const Rect& inRhs) const; @@ -43,6 +41,8 @@ namespace Common { template Rect CastTo() const; }; + template requires FloatingPoint bool AlmostEqual(const Rect& lhs, const Rect& rhs, T absoluteTolerance = DefaultTolerance(), T relativeTolerance = DefaultTolerance()); + using IRect = Rect; using URect = Rect; using HRect = Rect; @@ -50,73 +50,6 @@ namespace Common { using DRect = Rect; } -namespace Common { - template - struct Serializer> { - static constexpr size_t typeId - = HashUtils::StrCrc32("Common::Rect") - + Serializer::typeId; - - static size_t Serialize(BinarySerializeStream& stream, const Rect& value) - { - size_t serialized = 0; - serialized += Serializer>::Serialize(stream, value.min); - serialized += Serializer>::Serialize(stream, value.max); - return serialized; - } - - static size_t Deserialize(BinaryDeserializeStream& stream, Rect& value) - { - size_t deserialized = 0; - deserialized += Serializer>::Deserialize(stream, value.min); - deserialized += Serializer>::Deserialize(stream, value.max); - return deserialized; - } - }; - - template - struct StringConverter> { - static std::string ToString(const Rect& inValue) - { - return std::format( - "{}min={}, max={}{}", - "{", - StringConverter>::ToString(inValue.min), - StringConverter>::ToString(inValue.max), - "}"); - } - }; - - template - struct JsonSerializer> { - static void JsonSerialize(rapidjson::Value& outJsonValue, rapidjson::Document::AllocatorType& inAllocator, const Rect& inValue) - { - rapidjson::Value minJson; - JsonSerializer>::JsonSerialize(minJson, inAllocator, inValue.min); - - rapidjson::Value maxJson; - JsonSerializer>::JsonSerialize(maxJson, inAllocator, inValue.max); - - outJsonValue.SetObject(); - outJsonValue.AddMember("min", minJson, inAllocator); - outJsonValue.AddMember("max", maxJson, inAllocator); - } - - static void JsonDeserialize(const rapidjson::Value& inJsonValue, Rect& outValue) - { - if (!inJsonValue.IsObject()) { - return; - } - if (inJsonValue.HasMember("min")) { - JsonSerializer>::JsonDeserialize(inJsonValue["min"], outValue.min); - } - if (inJsonValue.HasMember("max")) { - JsonSerializer>::JsonDeserialize(inJsonValue["max"], outValue.max); - } - } - }; -} - namespace Common { template Rect Rect::FromMinExtent(T inMinX, T inMinY, T inExtentX, T inExtentY) @@ -152,26 +85,13 @@ namespace Common { } template - Rect::Rect(const Rect& inOther) - { - this->min = inOther.min; - this->max = inOther.max; - } + Rect::Rect(const Rect& inOther) = default; template - Rect::Rect(Rect&& inOther) noexcept - { - this->min = std::move(inOther.min); - this->max = std::move(inOther.max); - } + Rect::Rect(Rect&& inOther) noexcept = default; template - Rect& Rect::operator=(const Rect& inOther) - { - this->min = inOther.min; - this->max = inOther.max; - return *this; - } + Rect& Rect::operator=(const Rect& inOther) = default; template Vec Rect::Extent() const @@ -210,14 +130,14 @@ namespace Common { } template - T Rect::Distance(const Rect& inOther) const + T Rect::Distance(const Rect& inOther) const requires FloatingPoint { Vec direction = Center() - inOther.Center(); return direction.Model(); } template - T Rect::Size() const + T Rect::Size() const requires FloatingPoint { Vec diagonal = this->max - this->min; return diagonal.Model() / T(2); @@ -255,4 +175,12 @@ namespace Common { this->max.template CastTo() ); } + + template + requires FloatingPoint + bool AlmostEqual(const Rect& lhs, const Rect& rhs, T absoluteTolerance, T relativeTolerance) + { + return AlmostEqual(lhs.min, rhs.min, absoluteTolerance, relativeTolerance) + && AlmostEqual(lhs.max, rhs.max, absoluteTolerance, relativeTolerance); + } } diff --git a/Engine/Source/Common/Include/Common/Math/Simd.h b/Engine/Source/Common/Include/Common/Math/Simd.h index 2f8d6f92b..05b7653ca 100644 --- a/Engine/Source/Common/Include/Common/Math/Simd.h +++ b/Engine/Source/Common/Include/Common/Math/Simd.h @@ -4,11 +4,13 @@ #pragma once +#include +#include #include #include -// MirrorTool parses these headers only to harvest reflection metadata, and its libclang has no usable SSE2/NEON +// MirrorSourceGenerator parses these headers only to harvest reflection metadata, and its libclang has no usable SSE2/NEON // intrinsic header (no clang resource headers on Linux, a version-mismatched arm_neon.h on macOS). Reflection needs the // declarations below but never the vectorized bodies, so under the parser we skip the intrinsic include and stand in a // scalar F32x4 instead; every real translation unit still takes the intrinsic backend. @@ -47,7 +49,10 @@ namespace Common::Simd { inline F32x4 Sub(F32x4 a, F32x4 b) { return { a.lanes[0] - b.lanes[0], a.lanes[1] - b.lanes[1], a.lanes[2] - b.lanes[2], a.lanes[3] - b.lanes[3] }; } inline F32x4 Mul(F32x4 a, F32x4 b) { return { a.lanes[0] * b.lanes[0], a.lanes[1] * b.lanes[1], a.lanes[2] * b.lanes[2], a.lanes[3] * b.lanes[3] }; } inline F32x4 Div(F32x4 a, F32x4 b) { return { a.lanes[0] / b.lanes[0], a.lanes[1] / b.lanes[1], a.lanes[2] / b.lanes[2], a.lanes[3] / b.lanes[3] }; } + inline F32x4 Abs(F32x4 v) { return { std::abs(v.lanes[0]), std::abs(v.lanes[1]), std::abs(v.lanes[2]), std::abs(v.lanes[3]) }; } + inline F32x4 Max(F32x4 a, F32x4 b) { return { std::max(a.lanes[0], b.lanes[0]), std::max(a.lanes[1], b.lanes[1]), std::max(a.lanes[2], b.lanes[2]), std::max(a.lanes[3], b.lanes[3]) }; } inline float Sum(F32x4 v) { return v.lanes[0] + v.lanes[1] + v.lanes[2] + v.lanes[3]; } + inline float MaxValue(F32x4 v) { return std::max(std::max(v.lanes[0], v.lanes[1]), std::max(v.lanes[2], v.lanes[3])); } inline F32x4 Set(float x, float y, float z, float w) { return { x, y, z, w }; } template @@ -74,6 +79,8 @@ namespace Common::Simd { inline F32x4 Sub(F32x4 a, F32x4 b) { return _mm_sub_ps(a, b); } inline F32x4 Mul(F32x4 a, F32x4 b) { return _mm_mul_ps(a, b); } inline F32x4 Div(F32x4 a, F32x4 b) { return _mm_div_ps(a, b); } + inline F32x4 Abs(F32x4 v) { return _mm_andnot_ps(_mm_set1_ps(-0.0f), v); } + inline F32x4 Max(F32x4 a, F32x4 b) { return _mm_max_ps(a, b); } inline float Sum(F32x4 v) { @@ -84,6 +91,12 @@ namespace Common::Simd { return _mm_cvtss_f32(sums); } + inline float MaxValue(F32x4 v) + { + const F32x4 pairMax = _mm_max_ps(v, _mm_movehl_ps(v, v)); + return _mm_cvtss_f32(_mm_max_ss(pairMax, _mm_shuffle_ps(pairMax, pairMax, _MM_SHUFFLE(1, 1, 1, 1)))); + } + inline F32x4 Set(float x, float y, float z, float w) { return _mm_set_ps(w, z, y, x); } template @@ -107,7 +120,10 @@ namespace Common::Simd { inline F32x4 Sub(F32x4 a, F32x4 b) { return vsubq_f32(a, b); } inline F32x4 Mul(F32x4 a, F32x4 b) { return vmulq_f32(a, b); } inline F32x4 Div(F32x4 a, F32x4 b) { return vdivq_f32(a, b); } + inline F32x4 Abs(F32x4 v) { return vabsq_f32(v); } + inline F32x4 Max(F32x4 a, F32x4 b) { return vmaxq_f32(a, b); } inline float Sum(F32x4 v) { return vaddvq_f32(v); } + inline float MaxValue(F32x4 v) { return vmaxvq_f32(v); } inline F32x4 Set(float x, float y, float z, float w) { @@ -118,15 +134,17 @@ namespace Common::Simd { template inline F32x4 Splat(F32x4 v) { return vdupq_n_f32(vgetq_lane_f32(v, L)); } - // NEON has no single arbitrary 4-lane float shuffle, so go through memory; for a compile-time permutation the - // compiler routinely folds the store/reload back into register moves. template inline F32x4 Shuffle(F32x4 v) { - float tmp[4]; - vst1q_f32(tmp, v); - const float out[4] = { tmp[I0], tmp[I1], tmp[I2], tmp[I3] }; - return vld1q_f32(out); + static_assert(I0 >= 0 && I0 < 4 && I1 >= 0 && I1 < 4 && I2 >= 0 && I2 < 4 && I3 >= 0 && I3 < 4); + static constexpr uint8_t indices[16] = { + I0 * 4 + 0, I0 * 4 + 1, I0 * 4 + 2, I0 * 4 + 3, + I1 * 4 + 0, I1 * 4 + 1, I1 * 4 + 2, I1 * 4 + 3, + I2 * 4 + 0, I2 * 4 + 1, I2 * 4 + 2, I2 * 4 + 3, + I3 * 4 + 0, I3 * 4 + 1, I3 * 4 + 2, I3 * 4 + 3 + }; + return vreinterpretq_f32_u8(vqtbl1q_u8(vreinterpretq_u8_f32(v), vld1q_u8(indices))); } // In-place transpose of the 4x4 matrix whose rows are r0..r3. diff --git a/Engine/Source/Common/Include/Common/Math/Sphere.h b/Engine/Source/Common/Include/Common/Math/Sphere.h index a02d8c13a..e9c7c4dee 100644 --- a/Engine/Source/Common/Include/Common/Math/Sphere.h +++ b/Engine/Source/Common/Include/Common/Math/Sphere.h @@ -5,8 +5,6 @@ #pragma once #include -#include -#include namespace Common { template @@ -24,7 +22,7 @@ namespace Common { Sphere(Sphere&& inOther) noexcept; Sphere& operator=(const Sphere& inOther); - T Distance(const Sphere& inOther) const; + T Distance(const Sphere& inOther) const requires FloatingPoint; bool Inside(const Vec& inPoint) const; bool Intersect(const Sphere& inOther) const; bool operator==(const Sphere& inRhs) const; @@ -32,79 +30,14 @@ namespace Common { template Sphere CastTo() const; }; + template requires FloatingPoint bool AlmostEqual(const Sphere& lhs, const Sphere& rhs, T absoluteTolerance = DefaultTolerance(), T relativeTolerance = DefaultTolerance()); + using ISphere = Sphere; using HSphere = Sphere; using FSphere = Sphere; using DSphere = Sphere; } -namespace Common { - template - struct Serializer> { - static constexpr size_t typeId - = HashUtils::StrCrc32("Common::Sphere") - + Serializer::typeId; - - static size_t Serialize(BinarySerializeStream& stream, const Sphere& value) - { - size_t serialized = 0; - serialized += Serializer>::Serialize(stream, value.center); - serialized += Serializer::Serialize(stream, value.radius); - return serialized; - } - - static size_t Deserialize(BinaryDeserializeStream& stream, Sphere& value) - { - size_t deserialized = 0; - deserialized += Serializer>::Deserialize(stream, value.center); - deserialized += Serializer::Deserialize(stream, value.radius); - return deserialized; - } - }; - - template - struct StringConverter> { - static std::string ToString(const Sphere& inValue) - { - return std::format( - "{}center={}, radius={}{}", - "{", - StringConverter>::ToString(inValue.center), - StringConverter::ToString(inValue.radius), - "}"); - } - }; - - template - struct JsonSerializer> { - static void JsonSerialize(rapidjson::Value& outJsonValue, rapidjson::Document::AllocatorType& inAllocator, const Sphere& inValue) - { - rapidjson::Value centerJson; - JsonSerializer>::JsonSerialize(centerJson, inAllocator, inValue.center); - - rapidjson::Value radiusJson; - JsonSerializer::JsonSerialize(radiusJson, inAllocator, inValue.radius); - - outJsonValue.SetObject(); - outJsonValue.AddMember("center", centerJson, inAllocator); - outJsonValue.AddMember("radius", radiusJson, inAllocator); - } - - static void JsonDeserialize(const rapidjson::Value& inJsonValue, Sphere& outValue) - { - if (!inJsonValue.IsObject()) { - return; - } - if (inJsonValue.HasMember("center")) { - JsonSerializer>::JsonDeserialize(inJsonValue["center"], outValue.center); - } - if (inJsonValue.HasMember("radius")) { - JsonSerializer::JsonDeserialize(inJsonValue["radius"], outValue.radius); - } - } - }; -} - namespace Common { template Sphere::Sphere() @@ -128,29 +61,16 @@ namespace Common { } template - Sphere::Sphere(const Sphere& inOther) - { - this->center = inOther.center; - this->radius = inOther.radius; - } + Sphere::Sphere(const Sphere& inOther) = default; template - Sphere::Sphere(Sphere&& inOther) noexcept - { - this->center = std::move(inOther.center); - this->radius = inOther.radius; - } + Sphere::Sphere(Sphere&& inOther) noexcept = default; template - Sphere& Sphere::operator=(const Sphere& inOther) - { - this->center = inOther.center; - this->radius = inOther.radius; - return *this; - } + Sphere& Sphere::operator=(const Sphere& inOther) = default; template - T Sphere::Distance(const Sphere& inOther) const + T Sphere::Distance(const Sphere& inOther) const requires FloatingPoint { Vec direction = this->center - inOther.center; return direction.Model(); @@ -159,22 +79,29 @@ namespace Common { template bool Sphere::Inside(const Vec& inPoint) const { - Vec direction = this->center - inPoint; - return direction.Model() <= this->radius; + if (this->radius < static_cast(0)) { + return false; + } + const Vec direction = this->center - inPoint; + return direction.ModelSquared() <= this->radius * this->radius; } template bool Sphere::Intersect(const Sphere& inOther) const { - Vec direction = this->center - inOther.center; - return direction.Model() <= (this->radius + inOther.radius); + const T combinedRadius = this->radius + inOther.radius; + if (combinedRadius < static_cast(0)) { + return false; + } + const Vec direction = this->center - inOther.center; + return direction.ModelSquared() <= combinedRadius * combinedRadius; } template bool Sphere::operator==(const Sphere& inRhs) const { return this->center == inRhs.center - && CompareNumber(this->radius, inRhs.radius); + && this->radius == inRhs.radius; } template @@ -186,4 +113,12 @@ namespace Common { static_cast(this->radius) ); } + + template + requires FloatingPoint + bool AlmostEqual(const Sphere& lhs, const Sphere& rhs, T absoluteTolerance, T relativeTolerance) + { + return AlmostEqual(lhs.center, rhs.center, absoluteTolerance, relativeTolerance) + && AlmostEqual(lhs.radius, rhs.radius, absoluteTolerance, relativeTolerance); + } } diff --git a/Engine/Source/Common/Include/Common/Math/Transform.h b/Engine/Source/Common/Include/Common/Math/Transform.h index de2884ccd..61c1c892f 100644 --- a/Engine/Source/Common/Include/Common/Math/Transform.h +++ b/Engine/Source/Common/Include/Common/Math/Transform.h @@ -7,8 +7,6 @@ #include #include #include -#include -#include namespace Common { template @@ -21,6 +19,7 @@ namespace Common { template struct Transform : TransformBase { static Transform LookAt(const Vec& inPosition, const Vec& inTargetPosition, const Vec& inUpDirection = VecConsts::unitZ); + static bool TryFromMatrix(const Mat& inMatrix, Transform& outTransform, T tolerance = DefaultTolerance()); Transform(); Transform(const Mat& inMatrix); @@ -44,7 +43,10 @@ namespace Common { Transform& Translate(const Vec& inTranslation); Transform& Rotate(const Quaternion& inRotation); Transform& Scale(const Vec& inScale); + bool TrySetFromMatrix(const Mat& inMatrix, T tolerance = DefaultTolerance()); Transform& UpdateRotation(const Vec& forward, const Vec& side, const Vec& up); + bool TryLookTo(const Vec& inTargetPosition, const Vec& inUpDirection = VecConsts::unitZ, T tolerance = DefaultTolerance()); + bool TryMoveAndLookTo(const Vec& inPosition, const Vec& inTargetPosition, const Vec& inUpDirection = VecConsts::unitZ, T tolerance = DefaultTolerance()); Transform& LookTo(const Vec& inTargetPosition, const Vec& inUpDirection = VecConsts::unitZ); Transform& MoveAndLookTo(const Vec& inPosition, const Vec& inTargetPosition, const Vec& inUpDirection = VecConsts::unitZ); @@ -62,88 +64,13 @@ namespace Common { Transform CastTo() const; }; + template requires FloatingPoint bool AlmostEqual(const Transform& lhs, const Transform& rhs, T absoluteTolerance = DefaultTolerance(), T relativeTolerance = DefaultTolerance()); + using HTransform = Transform; using FTransform = Transform; using DTransform = Transform; } -namespace Common { - template - struct Serializer> { - static constexpr size_t typeId - = HashUtils::StrCrc32("Common::Transform") - + Serializer::typeId; - - static size_t Serialize(BinarySerializeStream& stream, const Transform& value) - { - size_t serialized = 0; - serialized += Serializer>::Serialize(stream, value.scale); - serialized += Serializer>::Serialize(stream, value.rotation); - serialized += Serializer>::Serialize(stream, value.translation); - return serialized; - } - - static size_t Deserialize(BinaryDeserializeStream& stream, Transform& value) - { - size_t deserialized = 0; - deserialized += Serializer>::Deserialize(stream, value.scale); - deserialized += Serializer>::Deserialize(stream, value.rotation); - deserialized += Serializer>::Deserialize(stream, value.translation); - return deserialized; - } - }; - - template - struct StringConverter> { - static std::string ToString(const Transform& inValue) - { - return std::format( - "{}scale={}, rotation={}, translation={}{}", - "{", - StringConverter>::ToString(inValue.scale), - StringConverter>::ToString(inValue.rotation), - StringConverter>::ToString(inValue.translation), - "}"); - } - }; - - template - struct JsonSerializer> { - static void JsonSerialize(rapidjson::Value& outJsonValue, rapidjson::Document::AllocatorType& inAllocator, const Transform& inValue) - { - rapidjson::Value scaleJson; - JsonSerializer>::JsonSerialize(scaleJson, inAllocator, inValue.scale); - - rapidjson::Value rotationJson; - JsonSerializer>::JsonSerialize(rotationJson, inAllocator, inValue.rotation); - - rapidjson::Value translationJson; - JsonSerializer>::JsonSerialize(translationJson, inAllocator, inValue.translation); - - outJsonValue.SetObject(); - outJsonValue.AddMember("scale", scaleJson, inAllocator); - outJsonValue.AddMember("rotation", rotationJson, inAllocator); - outJsonValue.AddMember("translation", translationJson, inAllocator); - } - - static void JsonDeserialize(const rapidjson::Value& inJsonValue, Transform& outValue) - { - if (!inJsonValue.IsObject()) { - return; - } - if (inJsonValue.HasMember("scale")) { - JsonSerializer>::JsonDeserialize(inJsonValue["scale"], outValue.scale); - } - if (inJsonValue.HasMember("rotation")) { - JsonSerializer>::JsonDeserialize(inJsonValue["rotation"], outValue.rotation); - } - if (inJsonValue.HasMember("translation")) { - JsonSerializer>::JsonDeserialize(inJsonValue["translation"], outValue.translation); - } - } - }; -} - namespace Common { template Transform Transform::LookAt(const Vec& inPosition, const Vec& inTargetPosition, const Vec& inUpDirection) @@ -153,6 +80,17 @@ namespace Common { return result; } + template + bool Transform::TryFromMatrix(const Mat& inMatrix, Transform& outTransform, T tolerance) + { + Transform result; + if (!result.TrySetFromMatrix(inMatrix, tolerance)) { + return false; + } + outTransform = result; + return true; + } + template Transform::Transform() { @@ -163,10 +101,10 @@ namespace Common { template Transform::Transform(const Mat& inMatrix) + : Transform() { - this->translation = inMatrix.ExtractTranslation(); - this->rotation = inMatrix.ExtractRotation(); - this->scale = inMatrix.ExtractScale(); + const bool decomposed = TrySetFromMatrix(inMatrix); + Assert(decomposed); } template @@ -186,29 +124,13 @@ namespace Common { } template - Transform::Transform(const Transform& other) - { - this->scale = other.scale; - this->rotation = other.rotation; - this->translation = other.translation; - } + Transform::Transform(const Transform& other) = default; template - Transform::Transform(Transform&& other) noexcept - { - this->scale = std::move(other.scale); - this->rotation = std::move(other.rotation); - this->translation = std::move(other.translation); - } + Transform::Transform(Transform&& other) noexcept = default; template - Transform& Transform::operator=(const Transform& other) - { - this->scale = other.scale; - this->rotation = other.rotation; - this->translation = other.translation; - return *this; - } + Transform& Transform::operator=(const Transform& other) = default; template bool Transform::operator==(const Transform& rhs) const @@ -348,38 +270,71 @@ namespace Common { } template - Transform& Transform::LookTo(const Vec& inTargetPosition, const Vec& inUpDirection) + bool Transform::TryLookTo(const Vec& inTargetPosition, const Vec& inUpDirection, T tolerance) { Vec f(inTargetPosition - this->translation); - f.Normalize(); + if (!f.TryNormalize(tolerance)) { + return false; + } Vec s = inUpDirection.Cross(f); - s.Normalize(); + if (!s.TryNormalize(tolerance)) { + const Vec& fallbackUp = std::abs(static_cast(f.z)) < 0.999 + ? VecConsts::unitZ + : VecConsts::unitY; + s = fallbackUp.Cross(f); + if (!s.TryNormalize(tolerance)) { + return false; + } + } Vec u = f.Cross(s); this->UpdateRotation(f, s, u); - - return *this; + return true; } template - Transform& Transform::MoveAndLookTo(const Vec& inPosition, const Vec& inTargetPosition, const Vec& inUpDirection) + bool Transform::TryMoveAndLookTo(const Vec& inPosition, const Vec& inTargetPosition, const Vec& inUpDirection, T tolerance) { - // Translation of LookAtMatrix ([s.Dot(inPosition), u.Dot(inPosition), f.Dot(inPosition)]) applying to visible objects is in camera space, whose coordinate system consists of s u and f - // The translation we need is in world space, exactly inPosition - this->translation = inPosition; - - Vec f(inTargetPosition - this->translation); - f.Normalize(); + Transform result(*this); + result.translation = inPosition; + if (!result.TryLookTo(inTargetPosition, inUpDirection, tolerance)) { + return false; + } + *this = result; + return true; + } - Vec s = inUpDirection.Cross(f); - s.Normalize(); + template + Transform& Transform::LookTo(const Vec& inTargetPosition, const Vec& inUpDirection) + { + const bool success = TryLookTo(inTargetPosition, inUpDirection); + Assert(success); + return *this; + } - Vec u = f.Cross(s); + template + bool Transform::TrySetFromMatrix(const Mat& inMatrix, T tolerance) + { + Vec translation; + Quaternion rotation; + Vec scale; + if (!inMatrix.TryDecomposeAffine(translation, rotation, scale, tolerance)) { + return false; + } - this->UpdateRotation(f, s, u); + this->translation = translation; + this->rotation = rotation; + this->scale = scale; + return true; + } + template + Transform& Transform::MoveAndLookTo(const Vec& inPosition, const Vec& inTargetPosition, const Vec& inUpDirection) + { + const bool success = TryMoveAndLookTo(inPosition, inTargetPosition, inUpDirection); + Assert(success); return *this; } @@ -410,27 +365,40 @@ namespace Common { template Mat Transform::GetTransformMatrix() const { - return GetTranslationMatrix() * GetRotationMatrix() * GetScaleMatrix(); + Mat result = GetRotationMatrix(); + for (auto row = 0; row < 3; row++) { + result.At(row, 0) *= this->scale.x; + result.At(row, 1) *= this->scale.y; + result.At(row, 2) *= this->scale.z; + } + result.At(0, 3) = this->translation.x; + result.At(1, 3) = this->translation.y; + result.At(2, 3) = this->translation.z; + return result; } template Mat Transform::GetTransformMatrixNoScale() const { - return GetTranslationMatrix() * GetRotationMatrix(); + Mat result = GetRotationMatrix(); + result.At(0, 3) = this->translation.x; + result.At(1, 3) = this->translation.y; + result.At(2, 3) = this->translation.z; + return result; } template Vec Transform::TransformPosition(const Vec& inPosition) const { - Mat posColMat = Mat::FromColVecs(Vec(inPosition.x, inPosition.y, inPosition.z, 1)); - return (GetTransformMatrix() * posColMat).Col(0).template SubVec<0, 1, 2>(); + return this->rotation.RotateVector(this->scale * inPosition) + this->translation; } template Vec Transform::TransformPosition(const Vec& inPosition) const { - Mat posColMat = Mat::FromColVecs(Vec(inPosition)); - return (GetTransformMatrix() * posColMat).Col(0); + const Vec scaled(inPosition.x * this->scale.x, inPosition.y * this->scale.y, inPosition.z * this->scale.z); + const Vec transformed = this->rotation.RotateVector(scaled) + this->translation * inPosition.w; + return Vec(transformed.x, transformed.y, transformed.z, inPosition.w); } template @@ -443,4 +411,13 @@ namespace Common { result.scale = this->scale.template CastTo(); return result; } + + template + requires FloatingPoint + bool AlmostEqual(const Transform& lhs, const Transform& rhs, T absoluteTolerance, T relativeTolerance) + { + return AlmostEqual(lhs.scale, rhs.scale, absoluteTolerance, relativeTolerance) + && AlmostEqual(lhs.rotation, rhs.rotation, absoluteTolerance, relativeTolerance) + && AlmostEqual(lhs.translation, rhs.translation, absoluteTolerance, relativeTolerance); + } } diff --git a/Engine/Source/Common/Include/Common/Math/Vector.h b/Engine/Source/Common/Include/Common/Math/Vector.h index f3d0cdc20..e73fbf8b6 100644 --- a/Engine/Source/Common/Include/Common/Math/Vector.h +++ b/Engine/Source/Common/Include/Common/Math/Vector.h @@ -9,8 +9,7 @@ #include #include -#include -#include +#include namespace Common { template struct Vec; @@ -25,7 +24,7 @@ namespace Common::Internal { namespace Common { template concept ValidVecDim = L >= 1 && L <= 4; - template concept VecN = std::is_same_v>; + template concept VecN = std::is_same_v, Vec>; template requires ValidVecDim @@ -82,13 +81,18 @@ namespace Common { template Vec SubVec() const; - T Model() const; - Vec Normalized() const; - void Normalize(); + T ModelSquared() const; + T Model() const requires FloatingPoint; + bool IsNormalized(T tolerance = DefaultTolerance()) const requires FloatingPoint; + Vec Normalized() const requires FloatingPoint; + bool TryNormalize(T tolerance = DefaultTolerance()) requires FloatingPoint; + void Normalize() requires FloatingPoint; T Dot(const Vec& rhs) const; - typename Internal::VecCrossResultTraits::Type Cross(const Vec& rhs) const; + typename Internal::VecCrossResultTraits::Type Cross(const Vec& rhs) const requires (FloatingPoint && (L == 2 || L == 3)); }; + template requires FloatingPoint bool AlmostEqual(const Vec& lhs, const Vec& rhs, T absoluteTolerance = DefaultTolerance(), T relativeTolerance = DefaultTolerance()); + template requires ValidVecDim struct VecConsts {}; @@ -219,75 +223,6 @@ namespace Common::Internal { }; } -namespace Common { - template - struct Serializer> { - static constexpr size_t typeId - = Common::HashUtils::StrCrc32("Common::Vector") - + Serializer::typeId - + L; - - static size_t Serialize(BinarySerializeStream& stream, const Vec& value) - { - size_t serialized = 0; - for (auto i = 0; i < L; i++) { - serialized += Serializer::Serialize(stream, value.data[i]); - } - return serialized; - } - - static size_t Deserialize(BinaryDeserializeStream& stream, Vec& value) - { - size_t deserialized = 0; - for (auto i = 0; i < L; i++) { - deserialized += Serializer::Deserialize(stream, value.data[i]); - } - return deserialized; - } - }; - - template - struct StringConverter> { - static std::string ToString(const Vec& inValue) - { - std::stringstream stream; - stream << "("; - for (auto i = 0; i < L; i++) { - stream << StringConverter::ToString(inValue.data[i]); - if (i != L - 1) { - stream << ", "; - } - } - stream << ")"; - return stream.str(); - } - }; - - template - struct JsonSerializer> { - static void JsonSerialize(rapidjson::Value& outJsonValue, rapidjson::Document::AllocatorType& inAllocator, const Vec& inValue) - { - outJsonValue.SetArray(); - outJsonValue.Reserve(L, inAllocator); - for (auto i = 0; i < L; i++) { - rapidjson::Value elementJson; - JsonSerializer::JsonSerialize(elementJson, inAllocator, inValue[i]); - outJsonValue.PushBack(elementJson, inAllocator); - } - } - - static void JsonDeserialize(const rapidjson::Value& inJsonValue, Vec& outValue) - { - if (!inJsonValue.IsArray() || inJsonValue.Size() != L) { - return; - } - for (auto i = 0; i < L; i++) { - JsonSerializer::JsonDeserialize(inJsonValue[i], outValue[i]); - } - } - }; -} - namespace Common { template struct BaseVec { @@ -662,7 +597,7 @@ namespace Common { { bool result = true; for (auto i = 0; i < L; i++) { - result = result && CompareNumber(this->data[i], rhs); + result = result && this->data[i] == rhs; } return result; } @@ -672,7 +607,7 @@ namespace Common { { bool result = true; for (auto i = 0; i < L; i++) { - result = result && CompareNumber(this->data[i], rhs.data[i]); + result = result && this->data[i] == rhs.data[i]; } return result; } @@ -814,36 +749,65 @@ namespace Common { } template - T Vec::Model() const + T Vec::Model() const requires FloatingPoint + { + return std::sqrt(ModelSquared()); + } + + template + T Vec::ModelSquared() const { - static_assert(FloatingPoint); - return std::sqrt(Internal::VecOps::Dot(*this, *this)); + return Internal::VecOps::Dot(*this, *this); } template - Vec Vec::Normalized() const + bool Vec::IsNormalized(T tolerance) const requires FloatingPoint { - return this->operator/(Model()); + using EvaluationT = std::conditional_t, float, T>; + const EvaluationT modelSquared = static_cast(ModelSquared()); + const EvaluationT toleranceValue = std::abs(static_cast(tolerance)); + return std::isfinite(modelSquared) && std::abs(modelSquared - static_cast(1)) <= toleranceValue; } template - void Vec::Normalize() + Vec Vec::Normalized() const requires FloatingPoint { - T oneOverModel = static_cast(1.0) / Model(); + Vec result(*this); + result.Normalize(); + return result; + } + + template + bool Vec::TryNormalize(T tolerance) requires FloatingPoint + { + const T modelSquared = ModelSquared(); + const double modelSquaredValue = static_cast(modelSquared); + const double toleranceValue = static_cast(tolerance); + if (!std::isfinite(modelSquaredValue) || modelSquaredValue <= toleranceValue * toleranceValue) { + return false; + } + + const T oneOverModel = static_cast(1) / static_cast(std::sqrt(modelSquared)); *this = Internal::VecOps::MulScalar(*this, oneOverModel); + return true; + } + + template + void Vec::Normalize() requires FloatingPoint + { + const bool normalized = TryNormalize(); + Assert(normalized); } template T Vec::Dot(const Vec& rhs) const { - static_assert(FloatingPoint); return Internal::VecOps::Dot(*this, rhs); } template - typename Internal::VecCrossResultTraits::Type Vec::Cross(const Vec& rhs) const + typename Internal::VecCrossResultTraits::Type Vec::Cross(const Vec& rhs) const requires (FloatingPoint && (L == 2 || L == 3)) { - static_assert(FloatingPoint && L >= 2 && L <= 3); typename Internal::VecCrossResultTraits::Type result; if constexpr (L == 2) { result = this->x * rhs.y - this->y * rhs.x; @@ -854,4 +818,16 @@ namespace Common { } return result; } + + template + requires FloatingPoint + bool AlmostEqual(const Vec& lhs, const Vec& rhs, T absoluteTolerance, T relativeTolerance) + { + for (auto i = 0; i < L; i++) { + if (!AlmostEqual(lhs.data[i], rhs.data[i], absoluteTolerance, relativeTolerance)) { + return false; + } + } + return true; + } } diff --git a/Engine/Source/Common/Include/Common/Math/View.h b/Engine/Source/Common/Include/Common/Math/View.h index 17c4f79c3..0f97f8b8e 100644 --- a/Engine/Source/Common/Include/Common/Math/View.h +++ b/Engine/Source/Common/Include/Common/Math/View.h @@ -5,8 +5,6 @@ #pragma once #include -#include -#include namespace Common { template @@ -24,51 +22,13 @@ namespace Common { Mat GetViewMatrix() const; }; + template requires FloatingPoint bool AlmostEqual(const ViewTransform& lhs, const ViewTransform& rhs, T absoluteTolerance = DefaultTolerance(), T relativeTolerance = DefaultTolerance()); + using HViewTransform = ViewTransform; using FViewTransform = ViewTransform; using DViewTransform = ViewTransform; } -namespace Common { - template - struct Serializer> { - static constexpr size_t typeId - = HashUtils::StrCrc32("Common::ViewTransform") - + Serializer::typeId; - - static size_t Serialize(BinarySerializeStream& stream, const ViewTransform& value) - { - return Serializer>::Serialize(stream, value); - } - - static size_t Deserialize(BinaryDeserializeStream& stream, ViewTransform& value) - { - return Serializer>::Deserialize(stream, value); - } - }; - - template - struct StringConverter> { - static std::string ToString(const ViewTransform& inValue) - { - return StringConverter>::ToString(inValue); - } - }; - - template - struct JsonSerializer> { - static void JsonSerialize(rapidjson::Value& outJsonValue, rapidjson::Document::AllocatorType& inAllocator, const ViewTransform& inValue) - { - JsonSerializer>::JsonSerialize(outJsonValue, inAllocator, inValue); - } - - static void JsonDeserialize(const rapidjson::Value& inJsonValue, ViewTransform& outValue) - { - JsonSerializer>::JsonDeserialize(inJsonValue, outValue); - } - }; -} - namespace Common { template ViewTransform ViewTransform::LookAt(const Vec& inPosition, const Vec& inTargetPosition, const Vec& inUpDirection) @@ -95,23 +55,13 @@ namespace Common { } template - ViewTransform::ViewTransform(const ViewTransform& inOther) - : Transform(inOther) - { - } + ViewTransform::ViewTransform(const ViewTransform& inOther) = default; template - ViewTransform::ViewTransform(ViewTransform&& inOther) noexcept - : Transform(std::move(inOther)) - { - } + ViewTransform::ViewTransform(ViewTransform&& inOther) noexcept = default; template - ViewTransform& ViewTransform::operator=(const ViewTransform& inOther) - { - Transform::operator=(inOther); - return *this; - } + ViewTransform& ViewTransform::operator=(const ViewTransform& inOther) = default; template bool ViewTransform::operator==(const ViewTransform& inRhs) const @@ -130,12 +80,21 @@ namespace Common { // x+ -> from left to right // y+ -> from bottom to top // z+ -> from screen outer to inner - static Mat axisTransMat = Mat( - 0, 1, 0, 0, - 0, 0, 1, 0, - 1, 0, 0, 0, - 0, 0, 0, 1 - ); - return axisTransMat * this->GetTransformMatrixNoScale().Inverse(); + const Mat rotation = this->GetRotationMatrix(); + const T tx = this->translation.x; + const T ty = this->translation.y; + const T tz = this->translation.z; + return Mat( + rotation.At(0, 1), rotation.At(1, 1), rotation.At(2, 1), -(rotation.At(0, 1) * tx + rotation.At(1, 1) * ty + rotation.At(2, 1) * tz), + rotation.At(0, 2), rotation.At(1, 2), rotation.At(2, 2), -(rotation.At(0, 2) * tx + rotation.At(1, 2) * ty + rotation.At(2, 2) * tz), + rotation.At(0, 0), rotation.At(1, 0), rotation.At(2, 0), -(rotation.At(0, 0) * tx + rotation.At(1, 0) * ty + rotation.At(2, 0) * tz), + 0, 0, 0, 1); } -} \ No newline at end of file + + template + requires FloatingPoint + bool AlmostEqual(const ViewTransform& lhs, const ViewTransform& rhs, T absoluteTolerance, T relativeTolerance) + { + return AlmostEqual(static_cast&>(lhs), static_cast&>(rhs), absoluteTolerance, relativeTolerance); + } +} diff --git a/Engine/Source/Common/Src/Math/Color.cpp b/Engine/Source/Common/Src/Math/Color.cpp index f6bc58244..867f4d146 100644 --- a/Engine/Source/Common/Src/Math/Color.cpp +++ b/Engine/Source/Common/Src/Math/Color.cpp @@ -32,10 +32,7 @@ namespace Common { Color::Color(const Color& inOther) = default; - Color::Color(Color&& inOther) noexcept - : r(inOther.r), g(inOther.g), b(inOther.b), a(inOther.a) - { - } + Color::Color(Color&& inOther) noexcept = default; Color& Color::operator=(const Color& inOther) = default; @@ -92,34 +89,26 @@ namespace Common { CheckValid(); } - LinearColor::LinearColor(const LinearColor& inOther) - : r(inOther.r), g(inOther.g), b(inOther.b), a(inOther.a) - { - CheckValid(); - } + LinearColor::LinearColor(const LinearColor& inOther) = default; - LinearColor::LinearColor(LinearColor&& inOther) noexcept - : r(inOther.r), g(inOther.g), b(inOther.b), a(inOther.a) - { - CheckValid(); - } + LinearColor::LinearColor(LinearColor&& inOther) noexcept = default; - LinearColor& LinearColor::operator=(const LinearColor& inOther) + LinearColor& LinearColor::operator=(const LinearColor& inOther) = default; + + bool LinearColor::operator==(const LinearColor& inRhs) const { - r = inOther.r; - g = inOther.g; - b = inOther.b; - a = inOther.a; - CheckValid(); - return *this; + return r == inRhs.r + && g == inRhs.g + && b == inRhs.b + && a == inRhs.a; } - bool LinearColor::operator==(const LinearColor& inRhs) const + bool AlmostEqual(const LinearColor& lhs, const LinearColor& rhs, float absoluteTolerance, float relativeTolerance) { - return CompareNumber(r, inRhs.r) - && CompareNumber(g, inRhs.g) - && CompareNumber(b, inRhs.b) - && CompareNumber(a, inRhs.a); + return AlmostEqual(lhs.r, rhs.r, absoluteTolerance, relativeTolerance) + && AlmostEqual(lhs.g, rhs.g, absoluteTolerance, relativeTolerance) + && AlmostEqual(lhs.b, rhs.b, absoluteTolerance, relativeTolerance) + && AlmostEqual(lhs.a, rhs.a, absoluteTolerance, relativeTolerance); } Color LinearColor::ToColor() const diff --git a/Engine/Source/Common/Test/MathTest.cpp b/Engine/Source/Common/Test/MathTest.cpp index c63548a7d..050d3cba6 100644 --- a/Engine/Source/Common/Test/MathTest.cpp +++ b/Engine/Source/Common/Test/MathTest.cpp @@ -4,6 +4,9 @@ #include +#include +#include + #include #include #include @@ -15,6 +18,7 @@ #include #include #include +#include #include using namespace Common; @@ -32,6 +36,10 @@ TEST(MathTest, CompareNumberTest) { ASSERT_TRUE(CompareNumber(1.0f, 1.0f + epsilon / 2.0f)); ASSERT_FALSE(CompareNumber(1.0f, 1.1f)); + ASSERT_TRUE(CompareNumber(1.0e9, 1.0e9 + 0.0005)); + ASSERT_TRUE(CompareNumber(std::numeric_limits::infinity(), std::numeric_limits::infinity())); + ASSERT_FALSE(CompareNumber(std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN())); + ASSERT_DOUBLE_EQ(Pi(), std::numbers::pi_v); ASSERT_TRUE(CompareNumber(5, 5)); ASSERT_FALSE(CompareNumber(5, 6)); } @@ -40,6 +48,8 @@ TEST(MathTest, CompareNumberTest) TEST(MathTest, HFloatTest) // NOLINT { + static_assert(sizeof(HFloat) == sizeof(uint16_t)); + const HFloat v0 = 1.0f; ASSERT_FLOAT_EQ(v0, 1.0f); ASSERT_TRUE(v0 == 1.0f); @@ -53,14 +63,14 @@ TEST(MathTest, HFloatTest) // NOLINT HFloat v3 = 1.0f; v3 /= v2; - ASSERT_TRUE(v3 == (1.0f / 1.5f)); + ASSERT_NEAR(v3.AsFloat(), 1.0f / 1.5f, halfEpsilon); HFloat v4 = 2.0f; v4 -= v2; ASSERT_TRUE(v4 == HFloat(0.5f)); const HFloat v5 = 3.0f; - ASSERT_TRUE(HFloat(9.0f) = HFloat(std::pow(v5, 2.0f))); + ASSERT_TRUE(HFloat(9.0f) == HFloat(std::pow(v5, 2.0f))); const HFloat v6 = 9.0f; ASSERT_TRUE(v5 == HFloat(std::sqrt(v6))); @@ -77,6 +87,11 @@ TEST(MathTest, HFloatComparisonTest) // NOLINT ASSERT_FALSE(a > b); ASSERT_TRUE(a != b); + const HFloat adjacent = 1.0009765625f; + ASSERT_FALSE(a == adjacent); + ASSERT_TRUE(AlmostEqual(a, adjacent)); + ASSERT_TRUE(AlmostEqual(HVec2(a, a), HVec2(adjacent, adjacent))); + ASSERT_TRUE((HFloat(1.0f) + HFloat(2.0f)) == 3.0f); ASSERT_TRUE((HFloat(6.0f) - HFloat(2.0f)) == 4.0f); ASSERT_TRUE((HFloat(2.0f) * HFloat(3.0f)) == 6.0f); @@ -99,10 +114,40 @@ TEST(MathTest, HFloatEdgeCaseTest) // NOLINT ASSERT_TRUE(HFloat(0.5f) == 0.5f); ASSERT_TRUE(HFloat(0.25f) == 0.25f); - // values beyond the half range are clamped to the largest representable finite half (~65504) - const float large = static_cast(HFloat(100000.0f)); - ASSERT_GT(large, 60000.0f); - ASSERT_LT(large, 70000.0f); + ASSERT_FLOAT_EQ(HFloat(65504.0f).AsFloat(), 65504.0f); + ASSERT_TRUE(std::isinf(HFloat(100000.0f).AsFloat())); + ASSERT_TRUE(std::isinf(HFloat(std::numeric_limits::infinity()).AsFloat())); + ASSERT_TRUE(std::isnan(HFloat(std::numeric_limits::quiet_NaN()).AsFloat())); + + HFloat minimumSubnormal; + minimumSubnormal.value = 1; + ASSERT_FLOAT_EQ(minimumSubnormal.AsFloat(), std::ldexp(1.0f, -24)); + + const HFloat positiveZero(0.0f); + const HFloat negativeZero(-0.0f); + ASSERT_TRUE(positiveZero == negativeZero); + ASSERT_FALSE(std::signbit(positiveZero.AsFloat())); + ASSERT_TRUE(std::signbit(negativeZero.AsFloat())); + + const HFloat one(1.0f); + const float halfwayToNext = 1.0f + std::ldexp(1.0f, -11); + ASSERT_EQ(HFloat(halfwayToNext).value, one.value); + ASSERT_EQ(HFloat(std::nextafter(halfwayToNext, 2.0f)).value, one.value + 1); + ASSERT_FALSE(one == HFloat(1.0f + std::ldexp(1.0f, -10))); +} + +TEST(MathTest, HFloatBitPatternRoundTripTest) // NOLINT +{ + for (uint32_t bits = 0; bits <= std::numeric_limits::max(); ++bits) { + HFloat value; + value.value = static_cast(bits); + const float asFloat = value.AsFloat(); + if ((bits & 0x7c00u) == 0x7c00u && (bits & 0x03ffu) != 0) { + ASSERT_TRUE(std::isnan(asFloat)); + } else { + ASSERT_EQ(HFloat(asFloat).value, value.value); + } + } } // ==================================== Vector ==================================== @@ -300,6 +345,11 @@ TEST(MathTest, VecScalarCompareTest) ASSERT_TRUE(v0 == 2.0f); ASSERT_TRUE(v0 != 3.0f); ASSERT_FALSE(FVec3(1, 2, 3) == 1.0f); + + const FVec2 exact(1.0f, 2.0f); + const FVec2 adjacent(std::nextafter(1.0f, 2.0f), 2.0f); + ASSERT_FALSE(exact == adjacent); + ASSERT_TRUE(AlmostEqual(exact, adjacent)); } TEST(MathTest, VecCastToTest) @@ -365,6 +415,20 @@ TEST(MathTest, VecNormalizeTest) v0.Normalize(); ASSERT_TRUE(v0 == n0); + + FVec3 zero = FVec3Consts::zero; + ASSERT_FALSE(zero.TryNormalize()); + ASSERT_TRUE(zero == FVec3Consts::zero); + + FVec3 infinite(std::numeric_limits::infinity(), 0.0f, 0.0f); + ASSERT_FALSE(infinite.TryNormalize()); + + FVec3 tiny(1.0e-8f, 0.0f, 0.0f); + ASSERT_FALSE(tiny.TryNormalize()); + ASSERT_TRUE(tiny.TryNormalize(1.0e-9f)); + ASSERT_TRUE(tiny.IsNormalized()); + ASSERT_FALSE(FVec3(2, 0, 0).IsNormalized()); + ASSERT_TRUE(tiny == FVec3Consts::unitX); } TEST(MathTest, VecConstsTest) @@ -494,6 +558,12 @@ TEST(MathTest, MatSetTest) // NOLINT ); ASSERT_TRUE(v0.Row(0) == FVec4(2, 3, 4, 5)); ASSERT_TRUE(v0.Row(1) == FVec4(6, 7, 8, 9)); + + const FVec4 row0(10, 11, 12, 13); + const FVec4 row1(14, 15, 16, 17); + v0.SetRows(row0, row1); + ASSERT_TRUE(v0.Row(0) == row0); + ASSERT_TRUE(v0.Row(1) == row1); } TEST(MathTest, MatFromVecsTest) @@ -505,6 +575,12 @@ TEST(MathTest, MatFromVecsTest) const FMat2x3 m1 = FMat2x3::FromColVecs(FVec2(1, 4), FVec2(2, 5), FVec2(3, 6)); ASSERT_TRUE(m1.Col(0) == FVec2(1, 4)); ASSERT_TRUE(m1 == m0); + + const FVec3 row0(7, 8, 9); + const FVec3 row1(10, 11, 12); + const FMat2x3 m2 = FMat2x3::FromRowVecs(row0, row1); + ASSERT_TRUE(m2.Row(0) == row0); + ASSERT_TRUE(m2.Row(1) == row1); } TEST(MathTest, MatCastToTest) @@ -542,6 +618,9 @@ TEST(MathTest, MatMulTest) ASSERT_TRUE(m2.Row(2) == FVec2(178, 220)); ASSERT_TRUE(v2 == FVec3(30, 70, 110)); ASSERT_TRUE(v3 == FVec4(5, 11, 17, 23)); + + const IMat2x3 intMatrix(1, 2, 3, 4, 5, 6); + ASSERT_TRUE((intMatrix * IVec3(2, 3, 4)) == IVec2(20, 47)); } TEST(MathTest, MathTranposeTest) @@ -581,6 +660,7 @@ TEST(MathTest, MatrixDetInverseTest) const FMat2x2 im0 = m0.Inverse(); const FMat3x3 im1 = m1.Inverse(); const FMat4x4 im2 = m2.Inverse(); + const FMat4x4 uim2 = m2.InverseUnchecked(); const FMat2x2 inverse0( -4, 7, @@ -596,6 +676,7 @@ TEST(MathTest, MatrixDetInverseTest) ASSERT_TRUE(im0 == inverse0); ASSERT_TRUE(im1.Col(0) == col1); ASSERT_TRUE(im2.Col(0) == col2); + ASSERT_TRUE(uim2 == im2); } TEST(MathTest, MatCanInverseTest) @@ -605,6 +686,18 @@ TEST(MathTest, MatCanInverseTest) const FMat2x2 m1(1, 2, 2, 4); ASSERT_FALSE(m1.CanInverse()); + + FMat2x2 result(7.0f); + ASSERT_FALSE(m1.TryInverse(result)); + ASSERT_TRUE(result == 7.0f); + + const FMat2x2 nearSingular(1.0f, 1.0f, 1.0f, 1.0f + 1.0e-7f); + ASSERT_FALSE(nearSingular.CanInverse()); + + const FMat2x2 smallButInvertible(1.0e-8f, 0.0f, 0.0f, 1.0e-8f); + ASSERT_TRUE(smallButInvertible.CanInverse()); + ASSERT_TRUE(smallButInvertible.TryInverse(result)); + ASSERT_TRUE(result == FMat2x2(1.0e8f, 0.0f, 0.0f, 1.0e8f)); } TEST(MathTest, MatScalarArithmeticTest) @@ -635,14 +728,37 @@ TEST(MathTest, MatExtractionTest) 0, -2, 0, 7, 4, 0, 0, 5, 0, 0, 3, 3, - 7, 5, 3, 1 + 0, 0, 0, 1 }; const FTransform trans = FTransform(m); ASSERT_TRUE(trans.translation == FVec3(7.0f, 5.0f, 3.0f)); ASSERT_TRUE(trans.scale == FVec3(4.0f, 2.0f, 3.0f)); - ASSERT_TRUE(trans.rotation == FQuat(0.7071067f, .0f, .0f, .7071067f)); + ASSERT_TRUE(AlmostEqual(trans.rotation, FQuat(0.7071067f, .0f, .0f, .7071067f))); + + FVec3 translation(9.0f); + FQuat rotation(9.0f, 9.0f, 9.0f, 9.0f); + FVec3 scale(9.0f); + + FMat4x4 nonAffine = m; + nonAffine.At(3, 0) = 1.0f; + ASSERT_FALSE(nonAffine.TryDecomposeAffine(translation, rotation, scale)); + ASSERT_TRUE(translation == FVec3(9.0f)); + ASSERT_TRUE(rotation == FQuat(9.0f, 9.0f, 9.0f, 9.0f)); + ASSERT_TRUE(scale == FVec3(9.0f)); + + FMat4x4 shear = FMat4x4Consts::identity; + shear.At(0, 1) = 0.25f; + ASSERT_FALSE(shear.TryDecomposeAffine(translation, rotation, scale)); + + FMat4x4 zeroScale = FMat4x4Consts::identity; + zeroScale.At(1, 1) = 0.0f; + ASSERT_FALSE(zeroScale.TryDecomposeAffine(translation, rotation, scale)); + + FTransform unchanged(FQuatConsts::identity, FVec3(1, 2, 3)); + ASSERT_FALSE(FTransform::TryFromMatrix(nonAffine, unchanged)); + ASSERT_TRUE(unchanged == FTransform(FQuatConsts::identity, FVec3(1, 2, 3))); } // ==================================== Quaternion ==================================== @@ -666,6 +782,17 @@ TEST(MathTest, AngleRadianConvertTest) const FAngle a1(r1); ASSERT_TRUE(a1 == FAngle(180.0f)); + FAngle assignedAngle; + assignedAngle = FRadian(pi / 2.0f); + ASSERT_TRUE(assignedAngle == FAngle(90.0f)); + + FRadian assignedRadian; + assignedRadian = FAngle(180.0f); + ASSERT_TRUE(assignedRadian == FRadian(pi)); + + const DAngle preciseAngle { DRadian(std::numbers::pi_v) }; + ASSERT_TRUE(preciseAngle == DAngle(180.0)); + ASSERT_TRUE(FAngle(45.0f) == FAngle(45.0f)); ASSERT_FALSE(FRadian(1.0f) == FRadian(2.0f)); } @@ -714,6 +841,16 @@ TEST(MathTest, QuaternionPropertiesTest) const FQuat v1(2, 0, 0, 0); ASSERT_TRUE(v1.Normalized() == FQuat(1, 0, 0, 0)); + FQuat zero; + ASSERT_FALSE(zero.TryNormalize()); + ASSERT_TRUE(zero == FQuatConsts::zero); + + FQuat normalized(2, 0, 0, 0); + ASSERT_TRUE(normalized.TryNormalize()); + ASSERT_TRUE(normalized == FQuatConsts::identity); + ASSERT_TRUE(normalized.IsNormalized()); + ASSERT_FALSE(FQuat(2, 0, 0, 0).IsNormalized()); + const FQuat v2(2, 3, 4, 5); ASSERT_FLOAT_EQ(v0.Dot(v2), 1.0f * 2 + 2 * 3 + 3 * 4 + 4 * 5); } @@ -722,13 +859,13 @@ TEST(MathTest, QuaternionRotationTest) { const FQuat v0(FVec3(0, 0, 1), 90); const FVec3 v0r0 = v0.RotateVector(FVec3(1, 0, 0)); - ASSERT_TRUE(v0r0 == FVec3(0, -1, 0)); + ASSERT_TRUE(AlmostEqual(v0r0, FVec3(0, -1, 0))); const FVec3 v0r1 = v0.RotateVector(FVec3(1, 1, 1)); - ASSERT_TRUE(v0r1 == FVec3(1, -1, 1)); + ASSERT_TRUE(AlmostEqual(v0r1, FVec3(1, -1, 1))); const FQuat v1(FVec3(1, 0, 0), 90); const FVec3 v1r0 = v1.RotateVector(FVec3(0, 1, 0)); - ASSERT_TRUE(v1r0 == FVec3(0, 0, -1)); + ASSERT_TRUE(AlmostEqual(v1r0, FVec3(0, 0, -1))); } TEST(MathTest, QuaternionRadianTest) @@ -740,17 +877,23 @@ TEST(MathTest, QuaternionRadianTest) const FQuat v2 = FQuat::FromEulerZYX(FRadian(0.0f), FRadian(0.0f), FRadian(pi / 2.0f)); const FQuat v3 = FQuat::FromEulerZYX(0.0f, 0.0f, 90.0f); ASSERT_TRUE(v2 == v3); + + const double preciseAngle = 90.000000001; + const DQuat precise(DVec3Consts::unitZ, preciseAngle); + const double halfRadian = preciseAngle * std::numbers::pi_v / 360.0; + EXPECT_NEAR(precise.w, std::cos(halfRadian), 1.0e-15); + EXPECT_NEAR(precise.z, std::sin(halfRadian), 1.0e-15); } TEST(MathTest, EulerRotationTest) { const FQuat v0 = FQuat::FromEulerZYX(0, 0, 90); const FVec3 v0r0 = v0.RotateVector(FVec3(1, 0, 0)); - ASSERT_TRUE(v0r0 == FVec3(0, -1, 0)); + ASSERT_TRUE(AlmostEqual(v0r0, FVec3(0, -1, 0))); const FQuat v1 = FQuat::FromEulerZYX(90, 0, 90); const FVec3 v1r0 = v1.RotateVector(FVec3(1, 0, 0)); - ASSERT_TRUE(v1r0 == FVec3(0, 0, 1)); + ASSERT_TRUE(AlmostEqual(v1r0, FVec3(0, 0, 1))); ASSERT_TRUE(FQuatConsts::identity == FQuat::FromEulerZYX(0, 0, 0)); } @@ -780,11 +923,19 @@ TEST(MathTest, QuaternionToRotationMatrixTest) const FMat4x4 v0 = FQuat(FVec3Consts::unitZ, 90).GetRotationMatrix(); const FVec3 v0r0 = applyRotationMatrix(v0, FVec3(1, 0, 0)); - ASSERT_TRUE(v0r0 == FVec3(0, -1, 0)); + ASSERT_TRUE(AlmostEqual(v0r0, FVec3(0, -1, 0))); const FMat4x4 v1 = (FQuat(FVec3Consts::unitZ, 90) * FQuat(FVec3Consts::unitY, 180)).GetRotationMatrix(); const FVec3 v1r0 = applyRotationMatrix(v1, FVec3(0, 1, 0)); - ASSERT_TRUE(v1r0 == FVec3(-1, 0, 0)); + ASSERT_TRUE(AlmostEqual(v1r0, FVec3(-1, 0, 0))); + + const FQuat nonNormalized(2, 3, 4, 5); + const FVec3 input(1, -2, 3); + const FVec3 matrixResult = applyRotationMatrix(nonNormalized.GetRotationMatrix(), input); + const FVec3 directResult = nonNormalized.RotateVector(input); + EXPECT_NEAR(directResult.x, matrixResult.x, 1.0e-5f); + EXPECT_NEAR(directResult.y, matrixResult.y, 1.0e-5f); + EXPECT_NEAR(directResult.z, matrixResult.z, 1.0e-5f); } TEST(MathTest, QuatConstsTest) @@ -810,7 +961,7 @@ TEST(MathTest, TransformTest) FTransform v0(FVec3(2, 2, 2), FQuat(FVec3Consts::unitZ, 90), FVec3(5, 0, 0)); FVec3 v0r0 = v0.TransformPosition(x); - ASSERT_TRUE(v0r0 == FVec3(5, -2, 0)); + ASSERT_TRUE(AlmostEqual(v0r0, FVec3(5, -2, 0))); FTransform v1(FQuat::FromEulerZYX(90, 0, 90), FVec3(0, 0, 0)); FTransform v2(FQuat::FromEulerZYX(0, 90, 90), FVec3(0, 0, 0)); @@ -819,10 +970,10 @@ TEST(MathTest, TransformTest) FVec3 v2y = v2.TransformPosition(y); FVec3 v3x = v3.TransformPosition(x); FVec3 v3z = v3.TransformPosition(z); - ASSERT_TRUE(v1x == FVec3(0, 0, 1)); - ASSERT_TRUE(v2y == FVec3(0, 0, 1)); - ASSERT_TRUE(v3x == FVec3(0, 1, 0)); - ASSERT_TRUE(v3z == FVec3(-1, 0, 0)); + ASSERT_TRUE(AlmostEqual(v1x, FVec3(0, 0, 1))); + ASSERT_TRUE(AlmostEqual(v2y, FVec3(0, 0, 1))); + ASSERT_TRUE(AlmostEqual(v3x, FVec3(0, 1, 0))); + ASSERT_TRUE(AlmostEqual(v3z, FVec3(-1, 0, 0))); // In general, quaternion from eular angle performs z-axis rotation first, then y-axis, and last z-axis } @@ -876,6 +1027,20 @@ TEST(MathTest, TransformMatrixTest) const FVec4 p1 = (v0.GetTransformMatrixNoScale() * FVec4(1, 1, 1, 1)); const FVec3 p1Xyz = p1.SubVec<0, 1, 2>(); ASSERT_TRUE(p1Xyz == FVec3(6, 7, 8)); + + const FTransform complex(FVec3(2, 3, 4), FQuat::FromEulerZYX(20, -35, 70), FVec3(5, -6, 7)); + const FMat4x4 composed = complex.GetTranslationMatrix() * complex.GetRotationMatrix() * complex.GetScaleMatrix(); + const FMat4x4 direct = complex.GetTransformMatrix(); + for (auto i = 0; i < 16; i++) { + EXPECT_NEAR(direct[i], composed[i], 1.0e-5f); + } + + const FVec3 input(3, -2, 1); + const FVec4 matrixPosition = direct * FVec4(input.x, input.y, input.z, 1); + const FVec3 directPosition = complex.TransformPosition(input); + EXPECT_NEAR(directPosition.x, matrixPosition.x, 1.0e-5f); + EXPECT_NEAR(directPosition.y, matrixPosition.y, 1.0e-5f); + EXPECT_NEAR(directPosition.z, matrixPosition.z, 1.0e-5f); } TEST(MathTest, TransformPositionVec4Test) @@ -883,6 +1048,9 @@ TEST(MathTest, TransformPositionVec4Test) const FTransform v0(FVec3(2, 2, 2), FQuatConsts::identity, FVec3(1, 1, 1)); const FVec4 p0 = v0.TransformPosition(FVec4(1, 1, 1, 1)); ASSERT_TRUE(p0 == FVec4(3, 3, 3, 1)); + + const FVec4 direction = v0.TransformPosition(FVec4(1, 1, 1, 0)); + ASSERT_TRUE(direction == FVec4(2, 2, 2, 0)); } TEST(MathTest, TransformLookAtTest) @@ -906,8 +1074,18 @@ TEST(MathTest, TransformLookAtTest) v3.LookTo(FVec3(1, 1, 0)); const FMat4x4 r3 = v3.GetRotationMatrix(); const float invSqrt2 = std::sqrt(0.5f); - ASSERT_TRUE((r3 * FVec4(1, 0, 0, 0)) == FVec4(invSqrt2, invSqrt2, 0, 0)); + ASSERT_TRUE(AlmostEqual(r3 * FVec4(1, 0, 0, 0), FVec4(invSqrt2, invSqrt2, 0, 0))); ASSERT_TRUE((r3 * FVec4(0, 0, 1, 0)) == FVec4(0, 0, 1, 0)); + + FTransform invalidLook(FQuatConsts::identity, FVec3(1, 2, 3)); + ASSERT_FALSE(invalidLook.TryLookTo(invalidLook.translation)); + ASSERT_TRUE(invalidLook == FTransform(FQuatConsts::identity, FVec3(1, 2, 3))); + ASSERT_FALSE(invalidLook.TryMoveAndLookTo(FVec3(4, 5, 6), FVec3(4, 5, 6))); + ASSERT_TRUE(invalidLook.translation == FVec3(1, 2, 3)); + + FTransform parallelUp; + ASSERT_TRUE(parallelUp.TryLookTo(FVec3Consts::unitZ, FVec3Consts::unitZ)); + ASSERT_TRUE(CompareNumber(parallelUp.rotation.Model(), 1.0f)); } TEST(MathTest, TransformCastToTest) @@ -1018,6 +1196,13 @@ TEST(MathTest, SphereGeometryTest) ASSERT_FLOAT_EQ(v0.Distance(v1), 3.0f); ASSERT_FALSE(v0.Inside(FVec3(2, 0, 0))); ASSERT_TRUE(v0.Inside(FVec3(0.5f, 0, 0))); + ASSERT_TRUE(v0.Inside(FVec3(1, 0, 0))); + ASSERT_TRUE(v0.Intersect(FSphere(FVec3(3, 0, 0), 2.0f))); + ASSERT_FALSE(FSphere(FVec3Consts::zero, -1.0f).Inside(FVec3Consts::zero)); + + const ISphere integerSphere(IVec3Consts::zero, 3); + ASSERT_TRUE(integerSphere.Inside(IVec3(1, 2, 2))); + ASSERT_FALSE(integerSphere.Inside(IVec3(1, 2, 3))); const FSphere v2(FVec3(1, 2, 3), 1.0f); const DSphere v3 = v2.CastTo(); @@ -1060,6 +1245,16 @@ TEST(MathTest, ViewMatrixTest) const FViewTransform v1 = FViewTransform::LookAt(FVec3(3, 4, 5), FVec3(0, 0, 0), FVec3Consts::unitZ); const FMat4x4 vm1 = v1.GetViewMatrix(); + const FMat4x4 axisTransform( + 0, 1, 0, 0, + 0, 0, 1, 0, + 1, 0, 0, 0, + 0, 0, 0, 1); + const FMat4x4 genericView = axisTransform * v1.GetTransformMatrixNoScale().InverseUnchecked(); + for (auto i = 0; i < 16; i++) { + EXPECT_NEAR(vm1[i], genericView[i], 1.0e-5f); + } + const FVec4 camInView = vm1 * FVec4(3, 4, 5, 1); ASSERT_NEAR(camInView.x, 0.0f, 1e-4f); ASSERT_NEAR(camInView.y, 0.0f, 1e-4f); diff --git a/Engine/Source/RHI-DirectX12/Src/Buffer.cpp b/Engine/Source/RHI-DirectX12/Src/Buffer.cpp index 93b0b3991..b9afe4fd9 100644 --- a/Engine/Source/RHI-DirectX12/Src/Buffer.cpp +++ b/Engine/Source/RHI-DirectX12/Src/Buffer.cpp @@ -7,6 +7,7 @@ #include +#include #include #include #include @@ -131,4 +132,4 @@ namespace RHI::DirectX12 { } #endif } -} \ No newline at end of file +} diff --git a/Engine/Source/RHI-DirectX12/Src/Pipeline.cpp b/Engine/Source/RHI-DirectX12/Src/Pipeline.cpp index cee31a71a..1e0ef56e1 100644 --- a/Engine/Source/RHI-DirectX12/Src/Pipeline.cpp +++ b/Engine/Source/RHI-DirectX12/Src/Pipeline.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include #include diff --git a/Engine/Source/RHI-DirectX12/Src/PipelineLayout.cpp b/Engine/Source/RHI-DirectX12/Src/PipelineLayout.cpp index 48feb40d7..7c2e3bfd5 100644 --- a/Engine/Source/RHI-DirectX12/Src/PipelineLayout.cpp +++ b/Engine/Source/RHI-DirectX12/Src/PipelineLayout.cpp @@ -7,6 +7,8 @@ #include +#include +#include #include #include #include diff --git a/Engine/Source/RHI-DirectX12/Src/Texture.cpp b/Engine/Source/RHI-DirectX12/Src/Texture.cpp index 0b96994fb..ca61de5de 100644 --- a/Engine/Source/RHI-DirectX12/Src/Texture.cpp +++ b/Engine/Source/RHI-DirectX12/Src/Texture.cpp @@ -4,6 +4,7 @@ #include +#include #include #include #include diff --git a/Engine/Source/Render/Include/Render/Shader.h b/Engine/Source/Render/Include/Render/Shader.h index bf5213a42..9c4d7737c 100644 --- a/Engine/Source/Render/Include/Render/Shader.h +++ b/Engine/Source/Render/Include/Render/Shader.h @@ -10,6 +10,7 @@ #include #include +#include #include #define ShaderTypeInfo(inClass, inStage, inSourceFile, inEntryPoint) \ diff --git a/Engine/Source/Render/Src/MeshRenderData.cpp b/Engine/Source/Render/Src/MeshRenderData.cpp index 3f7f30ba6..527fc1db1 100644 --- a/Engine/Source/Render/Src/MeshRenderData.cpp +++ b/Engine/Source/Render/Src/MeshRenderData.cpp @@ -2,6 +2,8 @@ // Created by johnk on 2026/7/5. // +#include + #include namespace Render::Internal { @@ -16,7 +18,7 @@ namespace Render::Internal { Common::UniquePtr result = inDevice.CreateBuffer(createInfo); Assert(result.Valid()); auto* data = result->Map(RHI::MapMode::write, 0, inSize); - memcpy(data, inData, inSize); + std::memcpy(data, inData, inSize); result->Unmap(); return result; } diff --git a/Engine/Source/Render/Src/RenderCache.cpp b/Engine/Source/Render/Src/RenderCache.cpp index 6e82a5f30..6c3e3be58 100644 --- a/Engine/Source/Render/Src/RenderCache.cpp +++ b/Engine/Source/Render/Src/RenderCache.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include #include diff --git a/Engine/Source/Render/Src/RenderGraph.cpp b/Engine/Source/Render/Src/RenderGraph.cpp index 6083d13a5..cd64bd461 100644 --- a/Engine/Source/Render/Src/RenderGraph.cpp +++ b/Engine/Source/Render/Src/RenderGraph.cpp @@ -2,6 +2,7 @@ // Created by johnk on 2023/11/28. // +#include #include #include @@ -349,7 +350,7 @@ namespace Render { if (inCopy) { auto& [data] = src.emplace(); data.resize(inSize); - memcpy(data.data(), inData, inSize); + std::memcpy(data.data(), inData, inSize); } else { src.emplace(inData, inSize); } @@ -888,7 +889,7 @@ namespace Render { Assert(srcDataPtr != nullptr && srcDataSize > 0); const auto* src = srcDataPtr + uploadInfo.srcOffset; // NOLINT auto* dst = rhiBuffer->Map(RHI::MapMode::write, uploadInfo.dstOffset, srcDataSize); - memcpy(dst, src, srcDataSize); + std::memcpy(dst, src, srcDataSize); rhiBuffer->Unmap(); })); } diff --git a/Engine/Source/Render/Src/Shader.cpp b/Engine/Source/Render/Src/Shader.cpp index 9053c253e..9956aa432 100644 --- a/Engine/Source/Render/Src/Shader.cpp +++ b/Engine/Source/Render/Src/Shader.cpp @@ -6,6 +6,9 @@ #include #include +#include +#include +#include #include #include diff --git a/Engine/Source/Render/Src/ShaderCompiler.cpp b/Engine/Source/Render/Src/ShaderCompiler.cpp index 49df3ac2b..abe08b64a 100644 --- a/Engine/Source/Render/Src/ShaderCompiler.cpp +++ b/Engine/Source/Render/Src/ShaderCompiler.cpp @@ -32,6 +32,8 @@ using namespace Microsoft::WRL; #include #include #include +#include +#include #include #include #include diff --git a/Engine/Source/Runtime/Include/Runtime/Asset/Material.h b/Engine/Source/Runtime/Include/Runtime/Asset/Material.h index 31aba53e1..12509178f 100644 --- a/Engine/Source/Runtime/Include/Runtime/Asset/Material.h +++ b/Engine/Source/Runtime/Include/Runtime/Asset/Material.h @@ -6,8 +6,7 @@ #include -#include -#include +#include #include #include #include diff --git a/Engine/Source/Runtime/Include/Runtime/Asset/Mesh.h b/Engine/Source/Runtime/Include/Runtime/Asset/Mesh.h index 85e90d556..f14dbd3b6 100644 --- a/Engine/Source/Runtime/Include/Runtime/Asset/Mesh.h +++ b/Engine/Source/Runtime/Include/Runtime/Asset/Mesh.h @@ -4,7 +4,7 @@ #pragma once -#include +#include #include #include #include diff --git a/Engine/Source/Runtime/Include/Runtime/Component/Light.h b/Engine/Source/Runtime/Include/Runtime/Component/Light.h index 337b78be1..5f0e24a64 100644 --- a/Engine/Source/Runtime/Include/Runtime/Component/Light.h +++ b/Engine/Source/Runtime/Include/Runtime/Component/Light.h @@ -4,7 +4,7 @@ #pragma once -#include +#include #include #include diff --git a/Engine/Source/Runtime/Include/Runtime/Component/Transform.h b/Engine/Source/Runtime/Include/Runtime/Component/Transform.h index f15063193..0c844cbc0 100644 --- a/Engine/Source/Runtime/Include/Runtime/Component/Transform.h +++ b/Engine/Source/Runtime/Include/Runtime/Component/Transform.h @@ -4,7 +4,7 @@ #pragma once -#include +#include #include #include #include diff --git a/Program/CMakeLists.txt b/Program/CMakeLists.txt new file mode 100644 index 000000000..af1a1a9cd --- /dev/null +++ b/Program/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(MirrorSourceGenerator) diff --git a/Tool/MirrorTool/CMakeLists.txt b/Program/MirrorSourceGenerator/CMakeLists.txt similarity index 57% rename from Tool/MirrorTool/CMakeLists.txt rename to Program/MirrorSourceGenerator/CMakeLists.txt index 7eb01bf98..801ad0be3 100644 --- a/Tool/MirrorTool/CMakeLists.txt +++ b/Program/MirrorSourceGenerator/CMakeLists.txt @@ -1,6 +1,6 @@ file(GLOB sources Src/*.cpp) exp_add_library( - NAME MirrorTool.Static + NAME MirrorSourceGenerator.Static SRC ${sources} PUBLIC_INC Include PUBLIC_LIB Mirror libclang::libclang clipp::clipp @@ -8,18 +8,18 @@ exp_add_library( file(GLOB exe_sources ExeSrc/*.cpp) exp_add_executable( - NAME MirrorTool + NAME MirrorSourceGenerator SRC ${exe_sources} INC Include - LIB MirrorTool.Static + LIB MirrorSourceGenerator.Static ) exp_add_test( - NAME MirrorTool.Test + NAME MirrorSourceGenerator.Test SRC Test/Main.cpp INC Include - LIB MirrorTool.Static + LIB MirrorSourceGenerator.Static RES - ${CMAKE_CURRENT_SOURCE_DIR}/Test/MirrorToolInput.h->../Test/Resource/Mirror/MirrorToolInput.h + ${CMAKE_CURRENT_SOURCE_DIR}/Test/MirrorSourceGeneratorInput.h->../Test/Resource/Mirror/MirrorSourceGeneratorInput.h ${CMAKE_SOURCE_DIR}/Engine/Source/Mirror/Include/Mirror/Meta.h->../Test/Resource/Mirror/Mirror/Meta.h ) diff --git a/Tool/MirrorTool/ExeSrc/Main.cpp b/Program/MirrorSourceGenerator/ExeSrc/Main.cpp similarity index 89% rename from Tool/MirrorTool/ExeSrc/Main.cpp rename to Program/MirrorSourceGenerator/ExeSrc/Main.cpp index 49df956af..78b088a50 100644 --- a/Tool/MirrorTool/ExeSrc/Main.cpp +++ b/Program/MirrorSourceGenerator/ExeSrc/Main.cpp @@ -6,8 +6,8 @@ #include -#include -#include +#include +#include #include #include #include @@ -69,9 +69,9 @@ int main(int argc, char* argv[]) // NOLINT headerDirs = ProcessHeaderDirs(headerDirs); auto outputErrorWithDebugContext = [fullCmdLineStr, inputFile, outputFile, headerDirs, frameworkDirs, dynamic](const std::string& error) -> void { - std::cout << "MirrorTool fatal error:" << Common::newline; + std::cout << "MirrorSourceGenerator fatal error:" << Common::newline; std::cout << error << Common::newline; - std::cout << "MirrorTool debug context: " << Common::newline; + std::cout << "MirrorSourceGenerator debug context: " << Common::newline; std::cout << "[fullCmdLine] " << fullCmdLineStr << Common::newline; std::cout << "[dynamic] " << dynamic << Common::newline; std::cout << "[inputFile] " << inputFile << Common::newline; @@ -96,14 +96,14 @@ int main(int argc, char* argv[]) // NOLINT return 1; } - MirrorTool::Parser parser(inputFile, headerDirs, frameworkDirs); + MirrorSourceGenerator::Parser parser(inputFile, headerDirs, frameworkDirs); const auto parseResult = parser.Parse(); if (parseResult.IsErr()) { outputErrorWithDebugContext(parseResult.Error()); return 1; } - MirrorTool::Generator generator(inputFile, outputFile, headerDirs, parseResult.Value(), dynamic); + MirrorSourceGenerator::Generator generator(inputFile, outputFile, headerDirs, parseResult.Value(), dynamic); if (const auto generateResult = generator.Generate(); generateResult.IsErr()) { outputErrorWithDebugContext(generateResult.Error()); diff --git a/Tool/MirrorTool/Include/MirrorTool/Generator.h b/Program/MirrorSourceGenerator/Include/MirrorSourceGenerator/Generator.h similarity index 91% rename from Tool/MirrorTool/Include/MirrorTool/Generator.h rename to Program/MirrorSourceGenerator/Include/MirrorSourceGenerator/Generator.h index 36605c7ef..82acc6bb8 100644 --- a/Tool/MirrorTool/Include/MirrorTool/Generator.h +++ b/Program/MirrorSourceGenerator/Include/MirrorSourceGenerator/Generator.h @@ -9,9 +9,9 @@ #include #include -#include +#include -namespace MirrorTool { +namespace MirrorSourceGenerator { struct MetaInfo; class Generator { diff --git a/Tool/MirrorTool/Include/MirrorTool/Parser.h b/Program/MirrorSourceGenerator/Include/MirrorSourceGenerator/Parser.h similarity index 98% rename from Tool/MirrorTool/Include/MirrorTool/Parser.h rename to Program/MirrorSourceGenerator/Include/MirrorSourceGenerator/Parser.h index 6fdf9f597..36cd2ad88 100644 --- a/Tool/MirrorTool/Include/MirrorTool/Parser.h +++ b/Program/MirrorSourceGenerator/Include/MirrorSourceGenerator/Parser.h @@ -13,7 +13,7 @@ #include #include -namespace MirrorTool { +namespace MirrorSourceGenerator { enum class FieldAccess : uint8_t { pub, pro, diff --git a/Tool/MirrorTool/Src/Generator.cpp b/Program/MirrorSourceGenerator/Src/Generator.cpp similarity index 99% rename from Tool/MirrorTool/Src/Generator.cpp rename to Program/MirrorSourceGenerator/Src/Generator.cpp index c989aff4f..d416b35ba 100644 --- a/Tool/MirrorTool/Src/Generator.cpp +++ b/Program/MirrorSourceGenerator/Src/Generator.cpp @@ -8,12 +8,12 @@ #include #include -#include +#include #include #include #include -namespace MirrorTool { +namespace MirrorSourceGenerator { static std::string GetFullName(const Node& node) { std::string outerName = node.outerName; @@ -435,7 +435,7 @@ namespace MirrorTool { } } -namespace MirrorTool { +namespace MirrorSourceGenerator { Generator::Generator(std::string inInputFile, std::string inOutputFile, std::vector inHeaderDirs, const MetaInfo& inMetaInfo, bool inDynamic) : metaInfo(inMetaInfo) , inputFile(std::move(inInputFile)) diff --git a/Tool/MirrorTool/Src/Parser.cpp b/Program/MirrorSourceGenerator/Src/Parser.cpp similarity index 99% rename from Tool/MirrorTool/Src/Parser.cpp rename to Program/MirrorSourceGenerator/Src/Parser.cpp index 4adb890e8..abf692a3d 100644 --- a/Tool/MirrorTool/Src/Parser.cpp +++ b/Program/MirrorSourceGenerator/Src/Parser.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include #define DEBUG_OUTPUT 0 @@ -22,7 +22,7 @@ #define VisitChildren(funcName, contextType, cursor, context) \ clang_visitChildren(cursor, [](CXCursor c, CXCursor p, CXClientData cd) -> CXChildVisitResult { \ auto* ctx = reinterpret_cast(cd); \ - return MirrorTool::funcName(c, p, *ctx); \ + return MirrorSourceGenerator::funcName(c, p, *ctx); \ }, &context); \ #define FetchCursorInfo(visitorName, cursorVar) \ @@ -67,7 +67,7 @@ static void PrintDebugInfo(const std::string& visitorName, CXCursor cursor) #endif } -namespace MirrorTool { +namespace MirrorSourceGenerator { static constexpr auto propertyMetaTag = "property"; static constexpr auto functionMetaTag = "func"; static constexpr auto classMetaTag = "class"; @@ -414,7 +414,7 @@ namespace MirrorTool { } } -namespace MirrorTool { +namespace MirrorSourceGenerator { #if PLATFORM_LINUX // The conan libclang package ships only libclang.so, without clang's builtin headers (stddef.h, stdarg.h, ...) or any // system include paths, so query the host GCC for the directories it searches and feed them to clang verbatim. diff --git a/Tool/MirrorTool/Test/Main.cpp b/Program/MirrorSourceGenerator/Test/Main.cpp similarity index 91% rename from Tool/MirrorTool/Test/Main.cpp rename to Program/MirrorSourceGenerator/Test/Main.cpp index bd9d9ab20..23220e1f1 100644 --- a/Tool/MirrorTool/Test/Main.cpp +++ b/Program/MirrorSourceGenerator/Test/Main.cpp @@ -4,10 +4,10 @@ #include -#include -#include +#include +#include -using namespace MirrorTool; +using namespace MirrorSourceGenerator; void AssertMetaDatasEqual(const MetaDataMap& lhs, const MetaDataMap& rhs) { @@ -120,7 +120,7 @@ void AssertNamespaceInfoEqual(const NamespaceInfo& lhs, const NamespaceInfo& rhs TEST(MirrorTest, ParserTest) { - const Parser parser("../Test/Resource/Mirror/MirrorToolInput.h", { "../Test/Resource/Mirror" }, {}); + const Parser parser("../Test/Resource/Mirror/MirrorSourceGeneratorInput.h", { "../Test/Resource/Mirror" }, {}); const auto parseResult = parser.Parse(); ASSERT_TRUE(parseResult.IsOk()); @@ -160,11 +160,11 @@ TEST(MirrorTest, ParserTest) TEST(MirrorTest, GeneratorTest) { - const Parser parser("../Test/Resource/Mirror/MirrorToolInput.h", { "../Test/Resource/Mirror" }, {}); + const Parser parser("../Test/Resource/Mirror/MirrorSourceGeneratorInput.h", { "../Test/Resource/Mirror" }, {}); const auto parseResult = parser.Parse(); ASSERT_TRUE(parseResult.IsOk()); - const Generator generator("../Test/Resource/Mirror/MirrorToolInput.h", "../Test/Generated/Mirror/MirrorToolTest.generated.cpp", { "../" }, parseResult.Value(), false); + const Generator generator("../Test/Resource/Mirror/MirrorSourceGeneratorInput.h", "../Test/Generated/Mirror/MirrorSourceGeneratorTest.generated.cpp", { "../" }, parseResult.Value(), false); const auto generateResult = generator.Generate(); ASSERT_TRUE(generateResult.IsOk()); } diff --git a/Tool/MirrorTool/Test/MirrorToolInput.h b/Program/MirrorSourceGenerator/Test/MirrorSourceGeneratorInput.h similarity index 100% rename from Tool/MirrorTool/Test/MirrorToolInput.h rename to Program/MirrorSourceGenerator/Test/MirrorSourceGeneratorInput.h diff --git a/README.md b/README.md index 40ed6ae83..31e7fc1fd 100644 --- a/README.md +++ b/README.md @@ -153,6 +153,7 @@ Thanks all those following projects: * [VulkanMemoryAllocator](https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator) * [rapidjson](https://github.com/Tencent/rapidjson) * [cpp-httplib](https://github.com/yhirose/cpp-httplib) +* [Tabler Icons](https://github.com/tabler/tabler-icons) # License diff --git a/Sample/Base/Application.cpp b/Sample/Base/Application.cpp index 06285f7ad..eff6e22b4 100644 --- a/Sample/Base/Application.cpp +++ b/Sample/Base/Application.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include #include diff --git a/Tool/CMakeLists.txt b/Tool/CMakeLists.txt deleted file mode 100644 index a6d38b679..000000000 --- a/Tool/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -add_subdirectory(MirrorTool) \ No newline at end of file diff --git a/Tool/Scripts/IconFontGenerator/tabler.py b/Tool/Scripts/IconFontGenerator/tabler.py new file mode 100644 index 000000000..0a7d2fc7e --- /dev/null +++ b/Tool/Scripts/IconFontGenerator/tabler.py @@ -0,0 +1,399 @@ +#!/usr/bin/env python3 + +"""Generate the C++ Tabler icon catalog from an official webfont release.""" + +from __future__ import annotations + +import argparse +import re +import struct +import sys +from dataclasses import dataclass +from pathlib import Path + + +REPOSITORY_ROOT = Path(__file__).resolve().parents[3] +DEFAULT_FONT_PATH = REPOSITORY_ROOT / "Editor" / "Resource" / "Icons" / "Tabler" / "tabler-icons.ttf" +DEFAULT_OUTPUT_PATH = REPOSITORY_ROOT / "Editor" / "Include" / "Editor" / "Widget" / "TablerIcons.h" + +ICON_PATTERN = re.compile(r'\.ti-([a-z0-9-]+):before\s*\{\s*content:\s*"\\([0-9a-fA-F]+)";\s*\}') +VERSION_PATTERN = re.compile(r"Tabler Icons\s+([0-9]+\.[0-9]+\.[0-9]+)") +CPP_KEYWORDS = frozenset( + { + "alignas", + "alignof", + "and", + "and_eq", + "asm", + "atomic_cancel", + "atomic_commit", + "atomic_noexcept", + "auto", + "bitand", + "bitor", + "bool", + "break", + "case", + "catch", + "char", + "char8_t", + "char16_t", + "char32_t", + "class", + "compl", + "concept", + "const", + "const_cast", + "consteval", + "constexpr", + "constinit", + "continue", + "co_await", + "co_return", + "co_yield", + "decltype", + "default", + "delete", + "do", + "double", + "dynamic_cast", + "else", + "enum", + "explicit", + "export", + "extern", + "false", + "float", + "for", + "friend", + "goto", + "if", + "inline", + "int", + "long", + "mutable", + "namespace", + "new", + "noexcept", + "not", + "not_eq", + "nullptr", + "operator", + "or", + "or_eq", + "private", + "protected", + "public", + "reflexpr", + "register", + "reinterpret_cast", + "requires", + "return", + "short", + "signed", + "sizeof", + "static", + "static_assert", + "static_cast", + "struct", + "switch", + "synchronized", + "template", + "this", + "thread_local", + "throw", + "true", + "try", + "typedef", + "typeid", + "typename", + "union", + "unsigned", + "using", + "virtual", + "void", + "volatile", + "wchar_t", + "while", + "xor", + "xor_eq", + } +) + + +class GenerationError(RuntimeError): + pass + + +@dataclass(frozen=True) +class Icon: + css_name: str + identifier: str + codepoint: int + + +def read_u16(data: bytes, offset: int) -> int: + if offset < 0 or offset + 2 > len(data): + raise GenerationError("Unexpected end of TTF data while reading a 16-bit value") + return struct.unpack_from(">H", data, offset)[0] + + +def read_i16(data: bytes, offset: int) -> int: + if offset < 0 or offset + 2 > len(data): + raise GenerationError("Unexpected end of TTF data while reading a signed 16-bit value") + return struct.unpack_from(">h", data, offset)[0] + + +def read_u32(data: bytes, offset: int) -> int: + if offset < 0 or offset + 4 > len(data): + raise GenerationError("Unexpected end of TTF data while reading a 32-bit value") + return struct.unpack_from(">I", data, offset)[0] + + +def ttf_table(font_data: bytes, tag: bytes) -> bytes: + if len(font_data) < 12: + raise GenerationError("TTF offset table is truncated") + table_count = read_u16(font_data, 4) + records_end = 12 + table_count * 16 + if records_end > len(font_data): + raise GenerationError("TTF table directory is truncated") + for index in range(table_count): + record_offset = 12 + index * 16 + if font_data[record_offset : record_offset + 4] != tag: + continue + table_offset = read_u32(font_data, record_offset + 8) + table_length = read_u32(font_data, record_offset + 12) + if table_offset + table_length > len(font_data): + raise GenerationError(f"TTF {tag.decode('ascii')} table is truncated") + return font_data[table_offset : table_offset + table_length] + raise GenerationError(f"TTF does not contain a {tag.decode('ascii')} table") + + +def parse_cmap_format_4(cmap: bytes, subtable_offset: int) -> set[int]: + length = read_u16(cmap, subtable_offset + 2) + subtable_end = subtable_offset + length + if subtable_end > len(cmap): + raise GenerationError("TTF cmap format 4 subtable is truncated") + + segment_count = read_u16(cmap, subtable_offset + 6) // 2 + end_codes_offset = subtable_offset + 14 + start_codes_offset = end_codes_offset + segment_count * 2 + 2 + deltas_offset = start_codes_offset + segment_count * 2 + range_offsets_offset = deltas_offset + segment_count * 2 + if range_offsets_offset + segment_count * 2 > subtable_end: + raise GenerationError("TTF cmap format 4 segment arrays are truncated") + + codepoints: set[int] = set() + for index in range(segment_count): + end_code = read_u16(cmap, end_codes_offset + index * 2) + start_code = read_u16(cmap, start_codes_offset + index * 2) + delta = read_i16(cmap, deltas_offset + index * 2) + range_offset_position = range_offsets_offset + index * 2 + range_offset = read_u16(cmap, range_offset_position) + if start_code > end_code: + raise GenerationError("TTF cmap format 4 contains an invalid segment") + + for codepoint in range(start_code, end_code + 1): + if codepoint == 0xFFFF: + continue + if range_offset == 0: + glyph_index = (codepoint + delta) & 0xFFFF + else: + glyph_position = range_offset_position + range_offset + (codepoint - start_code) * 2 + if glyph_position + 2 > subtable_end: + raise GenerationError("TTF cmap format 4 glyph array is truncated") + glyph_index = read_u16(cmap, glyph_position) + if glyph_index != 0: + glyph_index = (glyph_index + delta) & 0xFFFF + if glyph_index != 0: + codepoints.add(codepoint) + return codepoints + + +def parse_cmap_format_12(cmap: bytes, subtable_offset: int) -> set[int]: + length = read_u32(cmap, subtable_offset + 4) + subtable_end = subtable_offset + length + if subtable_end > len(cmap): + raise GenerationError("TTF cmap format 12 subtable is truncated") + + group_count = read_u32(cmap, subtable_offset + 12) + groups_offset = subtable_offset + 16 + if groups_offset + group_count * 12 > subtable_end: + raise GenerationError("TTF cmap format 12 groups are truncated") + + codepoints: set[int] = set() + for index in range(group_count): + group_offset = groups_offset + index * 12 + start_codepoint = read_u32(cmap, group_offset) + end_codepoint = read_u32(cmap, group_offset + 4) + start_glyph = read_u32(cmap, group_offset + 8) + if start_codepoint > end_codepoint or end_codepoint > 0x10FFFF: + raise GenerationError("TTF cmap format 12 contains an invalid group") + for codepoint in range(start_codepoint, end_codepoint + 1): + if start_glyph + codepoint - start_codepoint != 0: + codepoints.add(codepoint) + return codepoints + + +def parse_ttf_codepoints(font_path: Path) -> set[int]: + try: + font_data = font_path.read_bytes() + except OSError as error: + raise GenerationError(f"Could not read TTF '{font_path}': {error}") from error + cmap = ttf_table(font_data, b"cmap") + if len(cmap) < 4: + raise GenerationError("TTF cmap table is truncated") + + subtable_count = read_u16(cmap, 2) + if 4 + subtable_count * 8 > len(cmap): + raise GenerationError("TTF cmap encoding records are truncated") + + codepoints: set[int] = set() + parsed_offsets: set[int] = set() + for index in range(subtable_count): + record_offset = 4 + index * 8 + platform_id = read_u16(cmap, record_offset) + encoding_id = read_u16(cmap, record_offset + 2) + if platform_id != 0 and not (platform_id == 3 and encoding_id in {1, 10}): + continue + subtable_offset = read_u32(cmap, record_offset + 4) + if subtable_offset in parsed_offsets: + continue + parsed_offsets.add(subtable_offset) + cmap_format = read_u16(cmap, subtable_offset) + if cmap_format == 4: + codepoints.update(parse_cmap_format_4(cmap, subtable_offset)) + elif cmap_format == 12: + codepoints.update(parse_cmap_format_12(cmap, subtable_offset)) + + if not codepoints: + raise GenerationError("TTF cmap does not contain a supported Unicode format 4 or 12 subtable") + return codepoints + + +def cpp_identifier(css_name: str) -> str: + parts = css_name.split("-") + identifier = parts[0] + "".join(part[:1].upper() + part[1:] for part in parts[1:]) + if identifier[0].isdigit(): + identifier = "icon" + identifier[:1].upper() + identifier[1:] + if identifier in CPP_KEYWORDS: + identifier += "Icon" + return identifier + + +def utf8_literal(codepoint: int) -> str: + try: + encoded = chr(codepoint).encode("utf-8") + except (ValueError, UnicodeEncodeError) as error: + raise GenerationError(f"Invalid Unicode codepoint U+{codepoint:04X}") from error + return "".join(f"\\x{byte:02x}" for byte in encoded) + + +def parse_css(css_path: Path) -> tuple[str, list[Icon]]: + try: + css = css_path.read_text(encoding="utf-8") + except OSError as error: + raise GenerationError(f"Could not read CSS '{css_path}': {error}") from error + + version_match = VERSION_PATTERN.search(css) + if version_match is None: + raise GenerationError("Could not determine the Tabler Icons version from the CSS header") + + raw_icons = ICON_PATTERN.findall(css) + if not raw_icons: + raise GenerationError("No Tabler icon declarations were found in the CSS") + + icons = [Icon(css_name, cpp_identifier(css_name), int(codepoint, 16)) for css_name, codepoint in raw_icons] + css_names = [icon.css_name for icon in icons] + identifiers = [icon.identifier for icon in icons] + if len(set(css_names)) != len(css_names): + raise GenerationError("The CSS contains duplicate icon names") + if len(set(identifiers)) != len(identifiers): + collisions = sorted(identifier for identifier in set(identifiers) if identifiers.count(identifier) > 1) + raise GenerationError(f"Generated C++ identifier collisions: {', '.join(collisions)}") + return version_match.group(1), icons + + +def validate_font(icons: list[Icon], font_path: Path) -> set[int]: + css_codepoints = {icon.codepoint for icon in icons} + font_codepoints = parse_ttf_codepoints(font_path) + if css_codepoints != font_codepoints: + missing_from_font = sorted(css_codepoints - font_codepoints) + missing_from_css = sorted(font_codepoints - css_codepoints) + format_codepoints = lambda values: ", ".join(f"U+{value:04X}" for value in values[:8]) or "none" + raise GenerationError( + "CSS and TTF codepoints differ; " + f"missing from TTF: {format_codepoints(missing_from_font)}; " + f"missing from CSS: {format_codepoints(missing_from_css)}" + ) + return css_codepoints + + +def render_header(version: str, icons: list[Icon], codepoints: set[int]) -> str: + lines = [ + "#pragma once", + "", + f"// Generated from @tabler/icons-webfont v{version} by Tool/Scripts/IconFontGenerator/tabler.py.", + "namespace Editor::Icons::Tabler {", + ] + for icon in icons: + lines.append(f' inline constexpr char {icon.identifier}[] = "{utf8_literal(icon.codepoint)}";') + + lines.extend(["", " inline constexpr char allGlyphs[] ="]) + sorted_codepoints = sorted(codepoints) + for offset in range(0, len(sorted_codepoints), 32): + literal = "".join(utf8_literal(codepoint) for codepoint in sorted_codepoints[offset : offset + 32]) + suffix = ";" if offset + 32 >= len(sorted_codepoints) else "" + lines.append(f' "{literal}"{suffix}') + lines.extend(["}", ""]) + return "\n".join(lines) + + +def create_argument_parser() -> argparse.ArgumentParser: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("css", type=Path, help="Path to dist/tabler-icons.css from the official webfont package") + parser.add_argument("--font", type=Path, default=DEFAULT_FONT_PATH, help=f"TTF to validate (default: {DEFAULT_FONT_PATH})") + parser.add_argument("--output", type=Path, default=DEFAULT_OUTPUT_PATH, help=f"Generated header path (default: {DEFAULT_OUTPUT_PATH})") + parser.add_argument("--check", action="store_true", help="Verify that the output is current without modifying it") + return parser + + +def run(arguments: argparse.Namespace) -> int: + version, icons = parse_css(arguments.css.resolve()) + codepoints = validate_font(icons, arguments.font.resolve()) + generated = render_header(version, icons, codepoints) + output_path = arguments.output.resolve() + + if arguments.check: + try: + current = output_path.read_text(encoding="ascii") + except OSError: + current = None + if current != generated: + print(f"Outdated generated header: {output_path}", file=sys.stderr) + return 1 + print(f"Validated {len(icons)} names and {len(codepoints)} glyphs in {output_path}") + return 0 + + output_path.parent.mkdir(parents=True, exist_ok=True) + if output_path.exists() and output_path.read_text(encoding="ascii") == generated: + action = "Unchanged" + else: + output_path.write_text(generated, encoding="ascii", newline="\n") + action = "Generated" + print(f"{action} {output_path}: Tabler Icons {version}, {len(icons)} names, {len(codepoints)} glyphs") + return 0 + + +def main() -> int: + parser = create_argument_parser() + arguments = parser.parse_args() + try: + return run(arguments) + except GenerationError as error: + parser.error(str(error)) + return 2 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/conanfile.py b/conanfile.py index a1ecad68d..078dd7f0f 100644 --- a/conanfile.py +++ b/conanfile.py @@ -3,6 +3,9 @@ class ExplosionConan(ConanFile): generators = "CMakeConfigDeps" settings = "os", "compiler", "build_type", "arch" + default_options = { + "imgui/*:use_wchar32": True, + } def requirements(self): self.requires("stb/cci.20230920")