commit f69b202da8b937166fae1e546b6733bd6fad9930 Author: Paul Wilde Date: Sat Jul 16 23:07:51 2022 +0100 destroyed repo, recreated with new nimble packaging diff --git a/.gitignore b/.gitignore new file mode 100755 index 0000000..1e27ec3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +# ignore all +* + +# unignore all with extensions +!*.* + +# unignore directories +!*/ diff --git a/README.MD b/README.MD new file mode 100755 index 0000000..d799f6c --- /dev/null +++ b/README.MD @@ -0,0 +1,70 @@ +# A selection of information output tools for dmenu + +These are a selection of independant tools for displaying various information +about system status in dmenu. Some of them i.e. `volume` have options (up, down, mute...) +which are selectable options in dmenu. + +## Tools +- `pingclock` performs a single `ping` to a server and returns the response time +- `battery` shows the current battery level +- `brightness` shows the current backlight level and gives options to adjust it +- `volume` shows the current volume level and gives options to adjust and manage it +- `date` shows the date +- `fuzzytime` shows the fuzzytime clock +- `wlan` shows the state of the wireless network interface. SSID connected to and signal level. +- `nic` shows the status and/or the ip address of the network interface card +- `temperature` shows the current CPU temperature +- `notes` a simple one liner note taking tool, displaying notes in `dmenu`/`rofi` +- `calculate` a calculator, utilising `qalculate` - inspired by [@fedops](https://codeberg.org/fedops/scripts) +- `emoji` an emoji picker +- `remmina` reads the files in your remmina config directory and allows you to connect to and edit them +- `translate` utilises libretranslate (you'll need and API key or your own instance) to translate test. Prefix the text with `en>de`, `de>en`, `en>fr`, etc. as you need. Must be compiled with `-d:ssl` + +The next two do not work with `rofi` unless you have `alias dmenu=rofi` set, but they're pretty nice tools + +- `passmenu_wrapper` a wrapper for passmenu. It basically just styles `passmenu` with no other features +- `command_wrapper` inspired by passmenu_wrapper, a basic tool to run other `dmenu` related tools with uniform styling. + - For example: `dmenu_run`, `clipmenu`, `passmenu` etc. + +### Example in `dmenu`: + +![dmenu_tools](https://user-images.githubusercontent.com/31094984/167123173-ee8092a2-d5ab-47b4-b207-ced328072cc0.gif) + +### Example of `command_wrapper` with `clipmenu` + +![command_wrap](https://user-images.githubusercontent.com/31094984/167122436-eea0be88-a929-46e8-9b4d-cb677dcb129c.gif) + +## How to compile +There are some configuration variables explicit to me, you'll need to change them for you for them to be useful I imagine. +Configuration variables are compile - there are no config files or runtime parameters (except for "rofi") + +Each tool is compiled separately, for example: +```nim +nim c pingclock +``` +and then run with +```sh +./pingclock +or +./pingclock rofi +``` + +## How to use +Personally, I have these bound to key combinations in i3. +In fact, I have a seperate `bindsym` mode in which all these +tools are accessible i.e. `$mod+i` to get to "info" mode then `p` to show pingclock. +It's completely up to you how to run them, they're just simple CLI tools really. + +### You can also set the volume and brightness levels by typing a numeric figure into the dmenu/rofi input box + +## Dependencies +- `dmenu` or `rofi` +- `yad` for calendar +- `passmenu` for passmenu_wrapper +- basically any tool that's used to gather the information. +- "tools" for audio etc. (`pamixer`, `ncpamixer`, etc.) can be set in the source + +## Full disclosure +I'm aware my code is messy. +I'm aware my code is mostly undocumented. +But hopefully these things are simple enough to work out. diff --git a/base.nim b/base.nim new file mode 100644 index 0000000..bd3eaac --- /dev/null +++ b/base.nim @@ -0,0 +1,293 @@ +import std/[os,osproc,strutils,json,rdstdin,marshal] + +type + Info* = object + title*: string + selected_fg*: string + selected_bg*: string + unselected_fg*: string + unselected_bg*: string + full_text*: string + # next few are for i3bar use + border*: string + background*: string + color*: string + html_text*: string + short_text*: string + args*: seq[string] + Menu = object + command: string + bottom: string + grab_kb: string + i_case: string + lines_shown: string + monitor: string + prompt: string + font: string + norm_bg: string + norm_fg: string + sel_bg: string + sel_fg: string + extra_cmd: string + i3BarInput* = object + button*: int + x*: int + y*: int + +const WM_TOOLS_DIR* = getHomeDir() & "Nextcloud/.wm_tools/" +const background* = "#000000" +const backgroundalt* = "#bb222222" +const backgroundalt2* = "#bb333333" +const foreground* = "#dfdfdf" +const foregroundalt* = "#777" +const foregroundalt2* = "#ccc" +const black* = "#000000" +const white* = "#FFFFFF" +const yellow* = "#ffb52a" +const red* = "#e60053" +const purple* = "#9f78e1" +const blue* = "#0a6cf5" +const lightblue* = "#7296EF" +const lighterblue* = "#B5DDF7" +const green* = "#4b9901" +const lightgreen* = "#00ff00" +const grey* = "#dfdfdf" +const darkgrey* = "#444" +const primary* = yellow +const secondary* = red +const alert* = "#bd2c40" +const MAX_LINES = 20 +const font = "Hermit-12" +const WL_DMENU = "dmenu" +const WL_ROFI = "wofi --dmenu" +var loop* = false +var stoploop* = true +var tool* = "dmenu" +var passmenu* = false +var command_wrapper* = false +var run_command* = "" +var wayland* = false + +proc newInfo*(str: string = "Info"): Info = + var title = str + if tool == "rofi": + title = title & " : " + return Info( + title: title, + selected_fg: black, + selected_bg: white, + unselected_fg: white, + unselected_bg: black, + # next few are for i3bar use + border: white, + background: black, + color: foreground, + ) + +proc newMenuConfig(cmd: string = "dmenu"): Menu = + var run = cmd + if wayland and cmd == "dmenu": + run = WL_DMENU + var menu = Menu() + menu.command = run + menu.prompt = "-p" + menu.i_case = "-i" + menu.lines_shown = "-l" + return menu + +proc newRofiConfig(cmd: string = "rofi -dmenu"): Menu = + var run = cmd + if wayland and cmd == "rofi -dmenu": + run = WL_ROFI + var menu = newMenuConfig(run) + menu.extra_cmd = "-markup-rows -kb-row-select \"Tab\" -kb-row-tab \"\"" + return menu + +proc newDmenuConfig(cmd: string = "dmenu"): Menu = + var run = cmd + if wayland and cmd == "dmenu": + run = WL_DMENU + var menu = newMenuConfig(run) + menu.bottom = "-b" + menu.grabkb = "-f" + menu.monitor = "-m" + menu.font = "-fn" + menu.norm_bg = "-nb" + menu.norm_fg = "-nf" + menu.sel_bg = "-sb" + menu.sel_fg = "-sf" + return menu + +proc newMenu(): Menu = + if passmenu: + return newDmenuConfig("passmenu") + elif command_wrapper: + return newDmenuConfig(run_command) + elif tool == "rofi": + return newRofiConfig() + elif tool == "dmenu": + return newDmenuConfig() + return newMenuConfig() + +proc debugLog*(str: string) = + let f = open("/tmp/debug.txt",fmAppend) + defer: f.close() + f.writeLine(str) + +proc switchTwmMode*(mode: string = "default") = + # I intend to add support for more twm as time goes on (I switch around a lot) + # Switch out of an i3 bindsym mode if set + if wayland: + discard execCmd("sway mode \"" & mode & "\"") + else: + discard execCmd("i3-msg mode \"" & mode & "\"") + +proc checkWayland() = + if getEnv("XDG_SESSION_TYPE") == "wayland": + wayland = true + +proc parseInput*(): i3BarInput = + let input = readLineFromStdin("") + try: + let jsonNode = parseJson(input) + let i3input = to(jsonNode, i3BarInput) + return i3input + except: + return i3BarInput() + +proc clearInput*(count: int = 1) = + for x in countup(1, count): + discard readLineFromStdin("") + +proc getArguments*(): seq[string] = + let args = commandLineParams() + return args + +proc stripQuotes*(str: string): string = + return replace(str,"\"",""") + +proc quote*(str: string): string = + var text = str + # May need to put some further work to escape some special chars here + text = stripQuotes(text) + + # Put leading and ending quote marks in + return " \"" & text & "\" " + # ^ Add a spaces ^ so the previous flag isn't touching + # + # +proc markup(str: string): string = + var text = str + + return text + +proc genMenuCmd*(data: Info, opts: varargs[string], rofi: bool = false): string = + # Build dmenu/rofi command + var cmd = "" + # if the text is empty, we don't want to create a menu item of it + if data.full_text != "": + let text = markup(data.full_text) + cmd &= text & "\n" + for opt in opts: + let text = markup(opt) + cmd = cmd & text & "\n" + cmd.removeSuffix("\n") + + cmd = "echo -e" & quote(cmd) & " | " + + var menu = newMenu() + cmd = cmd & menu.command & " " + cmd = cmd & menu.extra_cmd & " " + cmd = cmd & menu.i_case & " " + cmd = cmd & menu.lines_shown & " " & $MAX_LINES & " " + cmd = cmd & menu.prompt & quote(data.title) + cmd = cmd & menu.norm_bg & quote(data.unselected_bg) + cmd = cmd & menu.norm_fg & quote(data.unselected_fg) + cmd = cmd & menu.sel_bg & quote(data.selected_bg) + cmd = cmd & menu.sel_fg & quote(data.selected_fg) + cmd = cmd & menu.font & quote(font) + echo cmd + return cmd + + + +proc runMenu*(data: Info, opts: varargs[string], rofi: bool = false): string = + let cmd = genMenuCmd(data, opts, rofi) + #echo cmd + # + # Run command and get output + var output = execCmdEx(cmd) + output.output.stripLineEnd() + return output.output + +proc copyToClipboard*(str: string) = + if wayland: + discard execCmd("wl-copy " & str) + else: + discard execCmd("echo -n " & quote(str) & " | xclip -selection clipboard") + +proc getCurrentClipboardContent*(): string = + var str = "" + if wayland: + let cur = execCmdEx("wl-paste") + if cur.exitcode == 0: + str = cur[0] + else: + echo cur + else: + let cur = execCmdEx("xsel -o -b") + if cur.exitcode == 0: + str = cur[0] + else: + echo cur + return strip(str) + +proc outputData*(data: Info, args: varargs[string]): string {.discardable.} = + var output = "" + if tool == "rofi": + output = runMenu(data,args, rofi = true) + elif loop: + # mainly for i3bar/i3blocks compatible output + var j_data = data + if j_data.html_text != "": + j_data.full_text = j_data.html_text + echo $$j_data + else: + # if all else fails, use dmenu (default) + output = runMenu(data,args) + return output + + +proc checkCacheDir() = + if not dirExists(WM_TOOLS_DIR): + createDir(WM_TOOLS_DIR) + +# At Start up: +checkCacheDir() +checkWayland() + +# Switch bindsym mode back to default as it could be being used. +switchTwmMode() + + +let args* = getArguments() +for idx, arg in args: + case arg: + of "noloop": + stoploop = true + of "i3bar": + # I've kind of changed from using an i3bar to using #nobar so i3bar + # isn't really supported any more but this is here for backwards compatibility + loop = true + stoploop = false + of "dmenu": + stoploop = true + tool = "dmenu" + of "rofi": + stoploop = true + tool = "rofi" + of ["pass","passmenu"]: + passmenu = true + break + + diff --git a/battery/battery.nimble b/battery/battery.nimble new file mode 100644 index 0000000..d48f910 --- /dev/null +++ b/battery/battery.nimble @@ -0,0 +1,13 @@ +# Package + +version = "0.1.0" +author = "Paul Wilde" +description = "Shows battery percentage using dmenu" +license = "MIT" +srcDir = "src" +bin = @["battery"] + + +# Dependencies + +requires "nim >= 1.6.6" diff --git a/battery/src/battery.nim b/battery/src/battery.nim new file mode 100644 index 0000000..860028e --- /dev/null +++ b/battery/src/battery.nim @@ -0,0 +1,126 @@ +import ../../base +import std/[strutils,os] + +const battery = "BAT0" +const ok_fg = lightgreen +const default_fg = white +const default_bg = black +const warning_fg = black +const warning_bg = red +const low_bg = black +const low_fg = red +const alert_fg = black +const alert_bg = yellow +const med_fg = green +const med_bg = black + + +proc batteryExists(): bool = + try: + let state = strip(readFile("/sys/class/power_supply/" & battery & "/present")) + if state == "1": + return true + except: + echo "Error getting battery : " & getCurrentExceptionMsg() + return false + +proc isCharging(): bool = + try: + let state = strip(readFile("/sys/class/power_supply/" & battery & "/status")) + if state == "Charging": + return true + except: + echo "Error getting charging status : " & getCurrentExceptionMsg() + return false + +proc getCharge(): int = + var charge = 0 + try: + let chg = strip(readFile("/sys/class/power_supply/" & battery & "/capacity")) + if chg != "": + charge = parseInt(chg) + except: + echo "Error getting battery level : " & getCurrentExceptionMsg() + return charge + +proc getDesign(charge: int, state: bool): (string, string, string, string, string) = + var icon = " " + var icon_colour = ok_fg + var col = default_fg + var bg = default_bg + var border = ok_fg + if isCharging(): + icon = " " + else: + case charge: + of 0..5: + icon_colour = warning_fg + col = warning_fg + bg = warning_bg + of 6..19: + icon_colour = low_fg + border = low_bg + bg = default_bg + of 20..39: + icon_colour = alert_fg + border = alert_bg + icon = " " + of 40..59: + icon_colour = med_fg + border= med_fg + icon = " " + of 60..79: + icon_colour = med_fg + border = med_fg + icon = " " + of 80..100: + icon_colour = ok_fg + border = ok_fg + icon = " " + else: + icon = "x " + + let main_text = icon & " " & $charge & "%" + # This next line is here for i3bar purposes + let html_text = "" & icon & "" & $charge & "%" + + return (html_text,main_text, col, bg, border) + +proc getOutput(charge: int, state: bool): Info = + let (html_text,main_text,col,bg_col,highlight_col) = get_design(charge, state) + var data = newInfo("Battery") + data.full_text = main_text + data.selected_bg = highlight_col + data.selected_fg = col # may just want `black` here + # i3bar stuff + data.html_text = html_text + data.color = col + data.border = highlight_col + data.background = bg_col + return data + + +proc getBatteryInfo() = + var last_charge = -1 + var last_state = false + while true: + let charge = getCharge() + let state = isCharging() + if charge != last_charge or state != last_state: + let data = getoutput(charge, state) + outputData(data) + last_charge = charge + last_state = state + if stoploop: + break + sleep(1000) + +proc main() = + if batteryExists(): + getBatteryInfo() + else: + switchTwmMode() + +if isMainModule: + main() + diff --git a/brightness/brightness.nimble b/brightness/brightness.nimble new file mode 100644 index 0000000..3698d8c --- /dev/null +++ b/brightness/brightness.nimble @@ -0,0 +1,13 @@ +# Package + +version = "0.1.0" +author = "Paul Wilde" +description = "Shows and controls laptop brightness" +license = "MIT" +srcDir = "src" +bin = @["brightness"] + + +# Dependencies + +requires "nim >= 1.6.6" diff --git a/brightness/src/brightness.nim b/brightness/src/brightness.nim new file mode 100644 index 0000000..266e6e0 --- /dev/null +++ b/brightness/src/brightness.nim @@ -0,0 +1,116 @@ +import ../../base +import std/[os,strutils,osproc,math] + +const backlight = "intel_backlight" +const default_bg = yellow +const default_fg = black +const BACKLIGHT_CMD = "xbacklight" +const UP_X = BACKLIGHT_CMD & " -inc %v" # %v is amount by +const DOWN_X = BACKLIGHT_CMD & " -dec %v" # %v is amount by +const SET_X = BACKLIGHT_CMD & " -set %v" # %v is amount by +const BACKLIGHT_CMD_WL = "brightnessctl" +const UP_WL = BACKLIGHT_CMD_WL & " set %v%+" +const DOWN_WL = BACKLIGHT_CMD_WL & " set %v%-" +const SET_WL = BACKLIGHT_CMD_WL & " set %v%" +var CMD = BACKLIGHT_CMD +var UP = UP_X +var DOWN = DOWN_X +var SET = SET_X +const default_value = "5" + +proc getLimit(): int = + try: + let back_l = readFile("/sys/class/backlight/" & backlight & "/max_brightness") + return parseInt(strip(back_l)) + except: + echo "Error getting backlight max : ", getCurrentExceptionMsg() + return -1 + +let limit = getLimit() + +proc getDesign(pcnt: float): string = + var icon = "🌑" + case pcnt: + of 85..100: + icon = "🌕" + of 75..85: + icon = "🌖" + of 50..75: + icon = "🌗" + of 35..50: + icon = "🌘" + else: + icon = "🌑" + let percent = toInt(round(pcnt,0)) + let text = icon & " " & $percent & "%" + return text + +proc brightnessUp() = + let cmd = replace(UP,"%v",default_value) + discard execCmd(cmd) +proc brightnessDown() = + let cmd = replace(DOWN,"%v",default_value) + discard execCmd(cmd) + +proc getBrightness*(run_once: bool = false) = + var last_pcnt: float = 0 + while true: + let current = parseInt(strip(readFile("/sys/class/backlight/" & backlight & "/actual_brightness"))) + let pcnt = (current/limit)*100 + if pcnt != last_pcnt: + let text = getDesign(pcnt) + var data = newInfo("Brightness") + data.full_text = text + data.selected_bg = default_fg + data.selected_fg = default_bg + # i3bar stuff + data.border = default_fg + let args = @["up", "down"] + let option = outputData(data,args) + if option in args: + case option: + of "up": + brightnessUp() + getBrightness(true) + of "down": + brightnessDown() + getBrightness(true) + else: + try: + let i = parseInt(option) + let cmd = replace(SET,"%v",$i) + discard execCmd(cmd) + getBrightness(true) + except: + echo getCurrentExceptionMsg() + + if run_once: + break + if stoploop: + break + last_pcnt = pcnt + sleep(1000) + +proc main() = + if limit == -1: + switchTwmMode() + return + getBrightness() + +if isMainModule: + block start: + if wayland: + CMD = BACKLIGHT_CMD_WL + UP = UP_WL + DOWN = DOWN_WL + SET = SET_WL + for arg in args: + case arg: + of "up": + brightnessUp() + break start + of "down": + brightnessDown() + break start + + main() diff --git a/brightness/src/src/thingy.nim b/brightness/src/src/thingy.nim new file mode 100644 index 0000000..862d40c --- /dev/null +++ b/brightness/src/src/thingy.nim @@ -0,0 +1,5 @@ +# This is just an example to get you started. A typical binary package +# uses this file as the main entry point of the application. + +when isMainModule: + echo("Hello, World!") diff --git a/calculate/calculate.nimble b/calculate/calculate.nimble new file mode 100644 index 0000000..c8075e9 --- /dev/null +++ b/calculate/calculate.nimble @@ -0,0 +1,13 @@ +# Package + +version = "0.1.0" +author = "Paul Wilde" +description = "A simple dmenu calculator" +license = "MIT" +srcDir = "src" +bin = @["calculate"] + + +# Dependencies + +requires "nim >= 1.6.6" diff --git a/calculate/src/calculate.nim b/calculate/src/calculate.nim new file mode 100644 index 0000000..9a8a299 --- /dev/null +++ b/calculate/src/calculate.nim @@ -0,0 +1,35 @@ +import ../../base +import std/[osproc,strutils,sequtils] + +#using qalc as it has a lot of nice inbuilt features +# +proc doCalculation(calc: string) = + var info = newInfo("Calculator") + let ans_cmd_terse = "echo \"" & calc & "\" | qalc +u8 -terse -color=never | awk '!/^>/ && !/^$/ {gsub(/^[ \\t]+|[ \\t]+$/, \"\", $0); print}'" + let ans_cmd_full = "echo \"" & calc & "\" | qalc +u8 -color=never | awk '!/^>/ && !/^$/ {gsub(/^[ \\t]+|[ \\t]+$/, \"\", $0); print}'" + var ans_full = execCmdEx(ans_cmd_full) + ans_full.output.stripLineEnd() + var ans_terse = execCmdEx(ans_cmd_terse) + ans_terse.output.stripLineEnd() + let answers = @[strip(ans_full.output), + strip(ans_terse.output)] + let args = concat(answers,@["exit"]) + var cmd = outputData(info, args) + cmd.stripLineEnd() + if cmd in answers: + copyToClipboard(cmd) + elif cmd == "exit" or cmd == "": + return + else: + doCalculation(cmd) + +proc main() = + var info = newInfo("Calculator") + let args = @["exit"] + let cmd = outputData(info, args) + if cmd != "": + doCalculation(cmd) + return + +if isMainModule: + main() diff --git a/clipurr/clipurr.nimble b/clipurr/clipurr.nimble new file mode 100644 index 0000000..bd82aa7 --- /dev/null +++ b/clipurr/clipurr.nimble @@ -0,0 +1,13 @@ +# Package + +version = "0.1.0" +author = "Paul Wilde" +description = "Clipboard manager for X11 or Wayland" +license = "MIT" +srcDir = "src" +bin = @["clipurr"] + + +# Dependencies + +requires "nim >= 1.6.6" diff --git a/clipurr/src/clipurr.nim b/clipurr/src/clipurr.nim new file mode 100644 index 0000000..ef0e43e --- /dev/null +++ b/clipurr/src/clipurr.nim @@ -0,0 +1,135 @@ +import ../../base +import std/[strutils,os,db_sqlite,osproc] + +const CLIP_DB = WM_TOOLS_DIR & ".clipurr_cache.sqlite" +const KEEP_ITEMS = 20 + +proc addClip(str: var string) + +proc killOldRunningProcesses() = + let x = execCmdEx("killall wl-paste clipnotify") + echo x + + +proc runDaemon() = + echo "Starting Daemon..." + if wayland: + echo "Using Wl-paste" + let cwd = getAppDir() + let outp = execProcess("wl-paste -n -w " & cwd & "/clipurr set") + else: + var run = true + while run: + echo "Using Clipnotify" + let outp = execCmdEx("clipnotify") + if outp.exitcode == 0: + var content = getCurrentClipboardContent() + addClip(content) + + echo "Exiting Daemon..." + +proc openDBConn(): DBConn = + let db: DBconn = open(CLIP_DB,"","","") + try: + db.exec(sql"""create table if not exists + clip_items ( + timestamp DATETIME NOT NULL, + clip NVARCHAR(500) NOT NULL + ) + """) + except: + echo getCurrentExceptionMsg() + return db + +proc clearHistory() = + let db = openDBConn() + defer: db.close() + try: + db.exec(sql"drop table if exists clip_items") + except: + echo getCurrentExceptionMsg() + +proc maintainDB() = + let db = openDBConn() + try: + db.exec(sql"""BEGIN""") + db.exec(sql"delete from clip_items order by timestamp desc offset ?", KEEP_ITEMS) + db.exec(sql"""COMMIT""") + except: + echo "Error cleaning DB : " & getCurrentExceptionMsg() + +proc escapeClip(str: string): string = + var clip = str + clip = clip.replace("`","\\`") + clip = escape(clip) + return strip(clip) + +proc unescapeClip(str: string): string = + var clip = str + try: + clip = unescape(clip) + except: + echo getCurrentExceptionMsg() + + return strip(clip) + +proc readClipFile(): seq[string] = + var clips: seq[string] = @[] + let db = openDBConn() + defer: db.close() + try: + for row in db.fastRows(sql"select distinct(clip) from clip_items order by timestamp desc"): + var str = unescapeClip(row[0]) + clips.add(str) + except: + echo "Error Reading Clip File : " & getCurrentExceptionMsg() + return clips + +proc addClip(str: var string) = + if str == "": + return + elif str[0] == '\x89': + var t = str[1..3] + echo "Is a ", $t, " file , not storing" + str = "[" & t & " Image] (not stored)" + let db = openDBConn() + defer: db.close() + try: + db.exec(sql"""BEGIN""") + db.exec(sql"""insert into clip_items (timestamp, clip) + values (CURRENT_TIMESTAMP, ?) + """, escapeClip(str)) + db.exec(sql"""COMMIT""") + except: + echo getCurrentExceptionMsg() + return + +proc showClips() = + let clips = readClipFile() + let info = newInfo("Clipurr") + let option = outputData(info, clips) + if option != "": + copyToClipboard(option) + return + +proc main() = + for idx, arg in args: + if arg == "daemon": + killOldRunningProcesses() + runDaemon() + return + if arg == "set": + var content = getCurrentClipboardContent() + addClip(content) + return + if arg == "clear": + clearHistory() + return + showClips() + return + +block start: + if isMainModule: + main() + +maintainDB() diff --git a/command_wrapper/command_wrapper.nimble b/command_wrapper/command_wrapper.nimble new file mode 100644 index 0000000..0e711eb --- /dev/null +++ b/command_wrapper/command_wrapper.nimble @@ -0,0 +1,13 @@ +# Package + +version = "0.1.0" +author = "Paul Wilde" +description = "A Command wrapper thing - i.e. run clipmenu/passmenu into dmenu with styling, sucks really" +license = "MIT" +srcDir = "src" +bin = @["command_wrapper"] + + +# Dependencies + +requires "nim >= 1.6.6" diff --git a/command_wrapper/src/command_wrapper.nim b/command_wrapper/src/command_wrapper.nim new file mode 100644 index 0000000..7b6462c --- /dev/null +++ b/command_wrapper/src/command_wrapper.nim @@ -0,0 +1,22 @@ +import ../../base +import std/[strutils,osproc] + +# Basically just a wrapper to style passmenu nicely +proc main() = + var info = newInfo(capitalizeAscii(run_command)) + let cmd = genMenuCmd(info) + discard execCmd(cmd) + return + +if isMainModule: + base.command_wrapper = true + for idx, arg in args: + case arg: + of "-r", "--run": + run_command = args[idx + 1] + break + else: + echo "No command given, please run again with `[-r|--run] __cmd__`" + + if run_command != "": + main() diff --git a/compile_all.sh b/compile_all.sh new file mode 100755 index 0000000..c552683 --- /dev/null +++ b/compile_all.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +for dir in ./*; do + if [ -d $dir ]; then + cd $dir + f=$(echo $dir | sed 's/\.\///') + nimble install -y + sudo cp -v $f /usr/local/bin/$f + cd ../ + fi +done diff --git a/emoji/emoji.nimble b/emoji/emoji.nimble new file mode 100644 index 0000000..6a79d40 --- /dev/null +++ b/emoji/emoji.nimble @@ -0,0 +1,13 @@ +# Package + +version = "0.1.0" +author = "Paul Wilde" +description = "An emoji picker for dmenu/rofi" +license = "MIT" +srcDir = "src" +bin = @["emoji"] + + +# Dependencies + +requires "nim >= 1.6.6" diff --git a/emoji/src/emoji.nim b/emoji/src/emoji.nim new file mode 100644 index 0000000..f6810f9 --- /dev/null +++ b/emoji/src/emoji.nim @@ -0,0 +1,20 @@ +import ../../base +import lib/emojilist +import std/[re] + +proc main() = + var info = newInfo("Emoji Picker") + var args = getEmoji() + args.add("exit") + let output = outputData(info,args) + if output == "exit" or output == "": + return + else: + let e = re.findAll(output,re(".+ :")) + if len(e) > 0: + let emoji = re.replace(e[0], re(" :"),"") + copyToClipboard(emoji) + return + +if isMainModule: + main() diff --git a/emoji/src/lib/emojilist.nim b/emoji/src/lib/emojilist.nim new file mode 100644 index 0000000..13994b3 --- /dev/null +++ b/emoji/src/lib/emojilist.nim @@ -0,0 +1,3572 @@ +const emoji_list: seq[string] = @[ +"😀 : grinning face", +"😁 : beaming face with smiling eyes", +"😂 : face with tears of joy", +"🤣 : rolling on the floor laughing", +"😃 : grinning face with big eyes", +"😄 : grinning face with smiling eyes", +"😅 : grinning face with sweat", +"😆 : grinning squinting face", +"😉 : winking face", +"😊 : smiling face with smiling eyes", +"😋 : face savoring food", +"😎 : smiling face with sunglasses", +"😍 : smiling face with heart-eyes", +"😘 : face blowing a kiss", +"🥰 : smiling face with 3 hearts", +"😗 : kissing face", +"😙 : kissing face with smiling eyes", +"😚 : kissing face with closed eyes", +"☺️ : smiling face", +"☺ : smiling face", +"🙂 : slightly smiling face", +"🤗 : hugging face", +"🤩 : star-struck", +"🤔 : thinking face", +"🤨 : face with raised eyebrow", +"😐 : neutral face", +"😑 : expressionless face", +"😶 : face without mouth", +"🙄 : face with rolling eyes", +"😏 : smirking face", +"😣 : persevering face", +"😥 : sad but relieved face", +"😮 : face with open mouth", +"🤐 : zipper-mouth face", +"😯 : hushed face", +"😪 : sleepy face", +"😫 : tired face", +"😴 : sleeping face", +"😌 : relieved face", +"😛 : face with tongue", +"😜 : winking face with tongue", +"😝 : squinting face with tongue", +"🤤 : drooling face", +"😒 : unamused face", +"😓 : downcast face with sweat", +"😔 : pensive face", +"😕 : confused face", +"🙃 : upside-down face", +"🤑 : money-mouth face", +"😲 : astonished face", +"☹️ : frowning face", +"☹ : frowning face", +"🙁 : slightly frowning face", +"😖 : confounded face", +"😞 : disappointed face", +"😟 : worried face", +"😤 : face with steam from nose", +"😢 : crying face", +"😭 : loudly crying face", +"😦 : frowning face with open mouth", +"😧 : anguished face", +"😨 : fearful face", +"😩 : weary face", +"🤯 : exploding head", +"😬 : grimacing face", +"😰 : anxious face with sweat", +"😱 : face screaming in fear", +"🥵 : hot face", +"🥶 : cold face", +"😳 : flushed face", +"🤪 : zany face", +"😵 : dizzy face", +"😡 : pouting face", +"😠 : angry face", +"🤬 : face with symbols on mouth", +"😷 : face with medical mask", +"🤒 : face with thermometer", +"🤕 : face with head-bandage", +"🤢 : nauseated face", +"🤮 : face vomiting", +"🤧 : sneezing face", +"😇 : smiling face with halo", +"🤠 : cowboy hat face", +"🥳 : partying face", +"🥴 : woozy face", +"🥺 : pleading face", +"🤥 : lying face", +"🤫 : shushing face", +"🤭 : face with hand over mouth", +"🧐 : face with monocle", +"🤓 : nerd face", +"😈 : smiling face with horns", +"👿 : angry face with horns", +"🤡 : clown face", +"👹 : ogre", +"👺 : goblin", +"💀 : skull", +"☠️ : skull and crossbones", +"☠ : skull and crossbones", +"👻 : ghost", +"👽 : alien", +"👾 : alien monster", +"🤖 : robot face", +"💩 : pile of poo", +"😺 : grinning cat face", +"😸 : grinning cat face with smiling eyes", +"😹 : cat face with tears of joy", +"😻 : smiling cat face with heart-eyes", +"😼 : cat face with wry smile", +"😽 : kissing cat face", +"🙀 : weary cat face", +"😿 : crying cat face", +"😾 : pouting cat face", +"🙈 : see-no-evil monkey", +"🙉 : hear-no-evil monkey", +"🙊 : speak-no-evil monkey", +"🏻 : light skin tone", +"🏼 : medium-light skin tone", +"🏽 : medium skin tone", +"🏾 : medium-dark skin tone", +"🏿 : dark skin tone", +"👶 : baby", +"👶🏻 : baby: light skin tone", +"👶🏼 : baby: medium-light skin tone", +"👶🏽 : baby: medium skin tone", +"👶🏾 : baby: medium-dark skin tone", +"👶🏿 : baby: dark skin tone", +"🧒 : child", +"🧒🏻 : child: light skin tone", +"🧒🏼 : child: medium-light skin tone", +"🧒🏽 : child: medium skin tone", +"🧒🏾 : child: medium-dark skin tone", +"🧒🏿 : child: dark skin tone", +"👦 : boy", +"👦🏻 : boy: light skin tone", +"👦🏼 : boy: medium-light skin tone", +"👦🏽 : boy: medium skin tone", +"👦🏾 : boy: medium-dark skin tone", +"👦🏿 : boy: dark skin tone", +"👧 : girl", +"👧🏻 : girl: light skin tone", +"👧🏼 : girl: medium-light skin tone", +"👧🏽 : girl: medium skin tone", +"👧🏾 : girl: medium-dark skin tone", +"👧🏿 : girl: dark skin tone", +"🧑 : adult", +"🧑🏻 : adult: light skin tone", +"🧑🏼 : adult: medium-light skin tone", +"🧑🏽 : adult: medium skin tone", +"🧑🏾 : adult: medium-dark skin tone", +"🧑🏿 : adult: dark skin tone", +"👨 : man", +"👨🏻 : man: light skin tone", +"👨🏼 : man: medium-light skin tone", +"👨🏽 : man: medium skin tone", +"👨🏾 : man: medium-dark skin tone", +"👨🏿 : man: dark skin tone", +"👩 : woman", +"👩🏻 : woman: light skin tone", +"👩🏼 : woman: medium-light skin tone", +"👩🏽 : woman: medium skin tone", +"👩🏾 : woman: medium-dark skin tone", +"👩🏿 : woman: dark skin tone", +"🧓 : older adult", +"🧓🏻 : older adult: light skin tone", +"🧓🏼 : older adult: medium-light skin tone", +"🧓🏽 : older adult: medium skin tone", +"🧓🏾 : older adult: medium-dark skin tone", +"🧓🏿 : older adult: dark skin tone", +"👴 : old man", +"👴🏻 : old man: light skin tone", +"👴🏼 : old man: medium-light skin tone", +"👴🏽 : old man: medium skin tone", +"👴🏾 : old man: medium-dark skin tone", +"👴🏿 : old man: dark skin tone", +"👵 : old woman", +"👵🏻 : old woman: light skin tone", +"👵🏼 : old woman: medium-light skin tone", +"👵🏽 : old woman: medium skin tone", +"👵🏾 : old woman: medium-dark skin tone", +"👵🏿 : old woman: dark skin tone", +"👨‍⚕️ : man health worker", +"👨‍⚕ : man health worker", +"👨🏻‍⚕️ : man health worker: light skin tone", +"👨🏻‍⚕ : man health worker: light skin tone", +"👨🏼‍⚕️ : man health worker: medium-light skin tone", +"👨🏼‍⚕ : man health worker: medium-light skin tone", +"👨🏽‍⚕️ : man health worker: medium skin tone", +"👨🏽‍⚕ : man health worker: medium skin tone", +"👨🏾‍⚕️ : man health worker: medium-dark skin tone", +"👨🏾‍⚕ : man health worker: medium-dark skin tone", +"👨🏿‍⚕️ : man health worker: dark skin tone", +"👨🏿‍⚕ : man health worker: dark skin tone", +"👩‍⚕️ : woman health worker", +"👩‍⚕ : woman health worker", +"👩🏻‍⚕️ : woman health worker: light skin tone", +"👩🏻‍⚕ : woman health worker: light skin tone", +"👩🏼‍⚕️ : woman health worker: medium-light skin tone", +"👩🏼‍⚕ : woman health worker: medium-light skin tone", +"👩🏽‍⚕️ : woman health worker: medium skin tone", +"👩🏽‍⚕ : woman health worker: medium skin tone", +"👩🏾‍⚕️ : woman health worker: medium-dark skin tone", +"👩🏾‍⚕ : woman health worker: medium-dark skin tone", +"👩🏿‍⚕️ : woman health worker: dark skin tone", +"👩🏿‍⚕ : woman health worker: dark skin tone", +"👨‍🎓 : man student", +"👨🏻‍🎓 : man student: light skin tone", +"👨🏼‍🎓 : man student: medium-light skin tone", +"👨🏽‍🎓 : man student: medium skin tone", +"👨🏾‍🎓 : man student: medium-dark skin tone", +"👨🏿‍🎓 : man student: dark skin tone", +"👩‍🎓 : woman student", +"👩🏻‍🎓 : woman student: light skin tone", +"👩🏼‍🎓 : woman student: medium-light skin tone", +"👩🏽‍🎓 : woman student: medium skin tone", +"👩🏾‍🎓 : woman student: medium-dark skin tone", +"👩🏿‍🎓 : woman student: dark skin tone", +"👨‍🏫 : man teacher", +"👨🏻‍🏫 : man teacher: light skin tone", +"👨🏼‍🏫 : man teacher: medium-light skin tone", +"👨🏽‍🏫 : man teacher: medium skin tone", +"👨🏾‍🏫 : man teacher: medium-dark skin tone", +"👨🏿‍🏫 : man teacher: dark skin tone", +"👩‍🏫 : woman teacher", +"👩🏻‍🏫 : woman teacher: light skin tone", +"👩🏼‍🏫 : woman teacher: medium-light skin tone", +"👩🏽‍🏫 : woman teacher: medium skin tone", +"👩🏾‍🏫 : woman teacher: medium-dark skin tone", +"👩🏿‍🏫 : woman teacher: dark skin tone", +"👨‍⚖️ : man judge", +"👨‍⚖ : man judge", +"👨🏻‍⚖️ : man judge: light skin tone", +"👨🏻‍⚖ : man judge: light skin tone", +"👨🏼‍⚖️ : man judge: medium-light skin tone", +"👨🏼‍⚖ : man judge: medium-light skin tone", +"👨🏽‍⚖️ : man judge: medium skin tone", +"👨🏽‍⚖ : man judge: medium skin tone", +"👨🏾‍⚖️ : man judge: medium-dark skin tone", +"👨🏾‍⚖ : man judge: medium-dark skin tone", +"👨🏿‍⚖️ : man judge: dark skin tone", +"👨🏿‍⚖ : man judge: dark skin tone", +"👩‍⚖️ : woman judge", +"👩‍⚖ : woman judge", +"👩🏻‍⚖️ : woman judge: light skin tone", +"👩🏻‍⚖ : woman judge: light skin tone", +"👩🏼‍⚖️ : woman judge: medium-light skin tone", +"👩🏼‍⚖ : woman judge: medium-light skin tone", +"👩🏽‍⚖️ : woman judge: medium skin tone", +"👩🏽‍⚖ : woman judge: medium skin tone", +"👩🏾‍⚖️ : woman judge: medium-dark skin tone", +"👩🏾‍⚖ : woman judge: medium-dark skin tone", +"👩🏿‍⚖️ : woman judge: dark skin tone", +"👩🏿‍⚖ : woman judge: dark skin tone", +"👨‍🌾 : man farmer", +"👨🏻‍🌾 : man farmer: light skin tone", +"👨🏼‍🌾 : man farmer: medium-light skin tone", +"👨🏽‍🌾 : man farmer: medium skin tone", +"👨🏾‍🌾 : man farmer: medium-dark skin tone", +"👨🏿‍🌾 : man farmer: dark skin tone", +"👩‍🌾 : woman farmer", +"👩🏻‍🌾 : woman farmer: light skin tone", +"👩🏼‍🌾 : woman farmer: medium-light skin tone", +"👩🏽‍🌾 : woman farmer: medium skin tone", +"👩🏾‍🌾 : woman farmer: medium-dark skin tone", +"👩🏿‍🌾 : woman farmer: dark skin tone", +"👨‍🍳 : man cook", +"👨🏻‍🍳 : man cook: light skin tone", +"👨🏼‍🍳 : man cook: medium-light skin tone", +"👨🏽‍🍳 : man cook: medium skin tone", +"👨🏾‍🍳 : man cook: medium-dark skin tone", +"👨🏿‍🍳 : man cook: dark skin tone", +"👩‍🍳 : woman cook", +"👩🏻‍🍳 : woman cook: light skin tone", +"👩🏼‍🍳 : woman cook: medium-light skin tone", +"👩🏽‍🍳 : woman cook: medium skin tone", +"👩🏾‍🍳 : woman cook: medium-dark skin tone", +"👩🏿‍🍳 : woman cook: dark skin tone", +"👨‍🔧 : man mechanic", +"👨🏻‍🔧 : man mechanic: light skin tone", +"👨🏼‍🔧 : man mechanic: medium-light skin tone", +"👨🏽‍🔧 : man mechanic: medium skin tone", +"👨🏾‍🔧 : man mechanic: medium-dark skin tone", +"👨🏿‍🔧 : man mechanic: dark skin tone", +"👩‍🔧 : woman mechanic", +"👩🏻‍🔧 : woman mechanic: light skin tone", +"👩🏼‍🔧 : woman mechanic: medium-light skin tone", +"👩🏽‍🔧 : woman mechanic: medium skin tone", +"👩🏾‍🔧 : woman mechanic: medium-dark skin tone", +"👩🏿‍🔧 : woman mechanic: dark skin tone", +"👨‍🏭 : man factory worker", +"👨🏻‍🏭 : man factory worker: light skin tone", +"👨🏼‍🏭 : man factory worker: medium-light skin tone", +"👨🏽‍🏭 : man factory worker: medium skin tone", +"👨🏾‍🏭 : man factory worker: medium-dark skin tone", +"👨🏿‍🏭 : man factory worker: dark skin tone", +"👩‍🏭 : woman factory worker", +"👩🏻‍🏭 : woman factory worker: light skin tone", +"👩🏼‍🏭 : woman factory worker: medium-light skin tone", +"👩🏽‍🏭 : woman factory worker: medium skin tone", +"👩🏾‍🏭 : woman factory worker: medium-dark skin tone", +"👩🏿‍🏭 : woman factory worker: dark skin tone", +"👨‍💼 : man office worker", +"👨🏻‍💼 : man office worker: light skin tone", +"👨🏼‍💼 : man office worker: medium-light skin tone", +"👨🏽‍💼 : man office worker: medium skin tone", +"👨🏾‍💼 : man office worker: medium-dark skin tone", +"👨🏿‍💼 : man office worker: dark skin tone", +"👩‍💼 : woman office worker", +"👩🏻‍💼 : woman office worker: light skin tone", +"👩🏼‍💼 : woman office worker: medium-light skin tone", +"👩🏽‍💼 : woman office worker: medium skin tone", +"👩🏾‍💼 : woman office worker: medium-dark skin tone", +"👩🏿‍💼 : woman office worker: dark skin tone", +"👨‍🔬 : man scientist", +"👨🏻‍🔬 : man scientist: light skin tone", +"👨🏼‍🔬 : man scientist: medium-light skin tone", +"👨🏽‍🔬 : man scientist: medium skin tone", +"👨🏾‍🔬 : man scientist: medium-dark skin tone", +"👨🏿‍🔬 : man scientist: dark skin tone", +"👩‍🔬 : woman scientist", +"👩🏻‍🔬 : woman scientist: light skin tone", +"👩🏼‍🔬 : woman scientist: medium-light skin tone", +"👩🏽‍🔬 : woman scientist: medium skin tone", +"👩🏾‍🔬 : woman scientist: medium-dark skin tone", +"👩🏿‍🔬 : woman scientist: dark skin tone", +"👨‍💻 : man technologist", +"👨🏻‍💻 : man technologist: light skin tone", +"👨🏼‍💻 : man technologist: medium-light skin tone", +"👨🏽‍💻 : man technologist: medium skin tone", +"👨🏾‍💻 : man technologist: medium-dark skin tone", +"👨🏿‍💻 : man technologist: dark skin tone", +"👩‍💻 : woman technologist", +"👩🏻‍💻 : woman technologist: light skin tone", +"👩🏼‍💻 : woman technologist: medium-light skin tone", +"👩🏽‍💻 : woman technologist: medium skin tone", +"👩🏾‍💻 : woman technologist: medium-dark skin tone", +"👩🏿‍💻 : woman technologist: dark skin tone", +"👨‍🎤 : man singer", +"👨🏻‍🎤 : man singer: light skin tone", +"👨🏼‍🎤 : man singer: medium-light skin tone", +"👨🏽‍🎤 : man singer: medium skin tone", +"👨🏾‍🎤 : man singer: medium-dark skin tone", +"👨🏿‍🎤 : man singer: dark skin tone", +"👩‍🎤 : woman singer", +"👩🏻‍🎤 : woman singer: light skin tone", +"👩🏼‍🎤 : woman singer: medium-light skin tone", +"👩🏽‍🎤 : woman singer: medium skin tone", +"👩🏾‍🎤 : woman singer: medium-dark skin tone", +"👩🏿‍🎤 : woman singer: dark skin tone", +"👨‍🎨 : man artist", +"👨🏻‍🎨 : man artist: light skin tone", +"👨🏼‍🎨 : man artist: medium-light skin tone", +"👨🏽‍🎨 : man artist: medium skin tone", +"👨🏾‍🎨 : man artist: medium-dark skin tone", +"👨🏿‍🎨 : man artist: dark skin tone", +"👩‍🎨 : woman artist", +"👩🏻‍🎨 : woman artist: light skin tone", +"👩🏼‍🎨 : woman artist: medium-light skin tone", +"👩🏽‍🎨 : woman artist: medium skin tone", +"👩🏾‍🎨 : woman artist: medium-dark skin tone", +"👩🏿‍🎨 : woman artist: dark skin tone", +"👨‍✈️ : man pilot", +"👨‍✈ : man pilot", +"👨🏻‍✈️ : man pilot: light skin tone", +"👨🏻‍✈ : man pilot: light skin tone", +"👨🏼‍✈️ : man pilot: medium-light skin tone", +"👨🏼‍✈ : man pilot: medium-light skin tone", +"👨🏽‍✈️ : man pilot: medium skin tone", +"👨🏽‍✈ : man pilot: medium skin tone", +"👨🏾‍✈️ : man pilot: medium-dark skin tone", +"👨🏾‍✈ : man pilot: medium-dark skin tone", +"👨🏿‍✈️ : man pilot: dark skin tone", +"👨🏿‍✈ : man pilot: dark skin tone", +"👩‍✈️ : woman pilot", +"👩‍✈ : woman pilot", +"👩🏻‍✈️ : woman pilot: light skin tone", +"👩🏻‍✈ : woman pilot: light skin tone", +"👩🏼‍✈️ : woman pilot: medium-light skin tone", +"👩🏼‍✈ : woman pilot: medium-light skin tone", +"👩🏽‍✈️ : woman pilot: medium skin tone", +"👩🏽‍✈ : woman pilot: medium skin tone", +"👩🏾‍✈️ : woman pilot: medium-dark skin tone", +"👩🏾‍✈ : woman pilot: medium-dark skin tone", +"👩🏿‍✈️ : woman pilot: dark skin tone", +"👩🏿‍✈ : woman pilot: dark skin tone", +"👨‍🚀 : man astronaut", +"👨🏻‍🚀 : man astronaut: light skin tone", +"👨🏼‍🚀 : man astronaut: medium-light skin tone", +"👨🏽‍🚀 : man astronaut: medium skin tone", +"👨🏾‍🚀 : man astronaut: medium-dark skin tone", +"👨🏿‍🚀 : man astronaut: dark skin tone", +"👩‍🚀 : woman astronaut", +"👩🏻‍🚀 : woman astronaut: light skin tone", +"👩🏼‍🚀 : woman astronaut: medium-light skin tone", +"👩🏽‍🚀 : woman astronaut: medium skin tone", +"👩🏾‍🚀 : woman astronaut: medium-dark skin tone", +"👩🏿‍🚀 : woman astronaut: dark skin tone", +"👨‍🚒 : man firefighter", +"👨🏻‍🚒 : man firefighter: light skin tone", +"👨🏼‍🚒 : man firefighter: medium-light skin tone", +"👨🏽‍🚒 : man firefighter: medium skin tone", +"👨🏾‍🚒 : man firefighter: medium-dark skin tone", +"👨🏿‍🚒 : man firefighter: dark skin tone", +"👩‍🚒 : woman firefighter", +"👩🏻‍🚒 : woman firefighter: light skin tone", +"👩🏼‍🚒 : woman firefighter: medium-light skin tone", +"👩🏽‍🚒 : woman firefighter: medium skin tone", +"👩🏾‍🚒 : woman firefighter: medium-dark skin tone", +"👩🏿‍🚒 : woman firefighter: dark skin tone", +"👮 : police officer", +"👮🏻 : police officer: light skin tone", +"👮🏼 : police officer: medium-light skin tone", +"👮🏽 : police officer: medium skin tone", +"👮🏾 : police officer: medium-dark skin tone", +"👮🏿 : police officer: dark skin tone", +"👮‍♂️ : man police officer", +"👮‍♂ : man police officer", +"👮🏻‍♂️ : man police officer: light skin tone", +"👮🏻‍♂ : man police officer: light skin tone", +"👮🏼‍♂️ : man police officer: medium-light skin tone", +"👮🏼‍♂ : man police officer: medium-light skin tone", +"👮🏽‍♂️ : man police officer: medium skin tone", +"👮🏽‍♂ : man police officer: medium skin tone", +"👮🏾‍♂️ : man police officer: medium-dark skin tone", +"👮🏾‍♂ : man police officer: medium-dark skin tone", +"👮🏿‍♂️ : man police officer: dark skin tone", +"👮🏿‍♂ : man police officer: dark skin tone", +"👮‍♀️ : woman police officer", +"👮‍♀ : woman police officer", +"👮🏻‍♀️ : woman police officer: light skin tone", +"👮🏻‍♀ : woman police officer: light skin tone", +"👮🏼‍♀️ : woman police officer: medium-light skin tone", +"👮🏼‍♀ : woman police officer: medium-light skin tone", +"👮🏽‍♀️ : woman police officer: medium skin tone", +"👮🏽‍♀ : woman police officer: medium skin tone", +"👮🏾‍♀️ : woman police officer: medium-dark skin tone", +"👮🏾‍♀ : woman police officer: medium-dark skin tone", +"👮🏿‍♀️ : woman police officer: dark skin tone", +"👮🏿‍♀ : woman police officer: dark skin tone", +"🕵️ : detective", +"🕵 : detective", +"🕵🏻 : detective: light skin tone", +"🕵🏼 : detective: medium-light skin tone", +"🕵🏽 : detective: medium skin tone", +"🕵🏾 : detective: medium-dark skin tone", +"🕵🏿 : detective: dark skin tone", +"🕵️‍♂️ : man detective", +"🕵‍♂️ : man detective", +"🕵️‍♂ : man detective", +"🕵‍♂ : man detective", +"🕵🏻‍♂️ : man detective: light skin tone", +"🕵🏻‍♂ : man detective: light skin tone", +"🕵🏼‍♂️ : man detective: medium-light skin tone", +"🕵🏼‍♂ : man detective: medium-light skin tone", +"🕵🏽‍♂️ : man detective: medium skin tone", +"🕵🏽‍♂ : man detective: medium skin tone", +"🕵🏾‍♂️ : man detective: medium-dark skin tone", +"🕵🏾‍♂ : man detective: medium-dark skin tone", +"🕵🏿‍♂️ : man detective: dark skin tone", +"🕵🏿‍♂ : man detective: dark skin tone", +"🕵️‍♀️ : woman detective", +"🕵‍♀️ : woman detective", +"🕵️‍♀ : woman detective", +"🕵‍♀ : woman detective", +"🕵🏻‍♀️ : woman detective: light skin tone", +"🕵🏻‍♀ : woman detective: light skin tone", +"🕵🏼‍♀️ : woman detective: medium-light skin tone", +"🕵🏼‍♀ : woman detective: medium-light skin tone", +"🕵🏽‍♀️ : woman detective: medium skin tone", +"🕵🏽‍♀ : woman detective: medium skin tone", +"🕵🏾‍♀️ : woman detective: medium-dark skin tone", +"🕵🏾‍♀ : woman detective: medium-dark skin tone", +"🕵🏿‍♀️ : woman detective: dark skin tone", +"🕵🏿‍♀ : woman detective: dark skin tone", +"💂 : guard", +"💂🏻 : guard: light skin tone", +"💂🏼 : guard: medium-light skin tone", +"💂🏽 : guard: medium skin tone", +"💂🏾 : guard: medium-dark skin tone", +"💂🏿 : guard: dark skin tone", +"💂‍♂️ : man guard", +"💂‍♂ : man guard", +"💂🏻‍♂️ : man guard: light skin tone", +"💂🏻‍♂ : man guard: light skin tone", +"💂🏼‍♂️ : man guard: medium-light skin tone", +"💂🏼‍♂ : man guard: medium-light skin tone", +"💂🏽‍♂️ : man guard: medium skin tone", +"💂🏽‍♂ : man guard: medium skin tone", +"💂🏾‍♂️ : man guard: medium-dark skin tone", +"💂🏾‍♂ : man guard: medium-dark skin tone", +"💂🏿‍♂️ : man guard: dark skin tone", +"💂🏿‍♂ : man guard: dark skin tone", +"💂‍♀️ : woman guard", +"💂‍♀ : woman guard", +"💂🏻‍♀️ : woman guard: light skin tone", +"💂🏻‍♀ : woman guard: light skin tone", +"💂🏼‍♀️ : woman guard: medium-light skin tone", +"💂🏼‍♀ : woman guard: medium-light skin tone", +"💂🏽‍♀️ : woman guard: medium skin tone", +"💂🏽‍♀ : woman guard: medium skin tone", +"💂🏾‍♀️ : woman guard: medium-dark skin tone", +"💂🏾‍♀ : woman guard: medium-dark skin tone", +"💂🏿‍♀️ : woman guard: dark skin tone", +"💂🏿‍♀ : woman guard: dark skin tone", +"👷 : construction worker", +"👷🏻 : construction worker: light skin tone", +"👷🏼 : construction worker: medium-light skin tone", +"👷🏽 : construction worker: medium skin tone", +"👷🏾 : construction worker: medium-dark skin tone", +"👷🏿 : construction worker: dark skin tone", +"👷‍♂️ : man construction worker", +"👷‍♂ : man construction worker", +"👷🏻‍♂️ : man construction worker: light skin tone", +"👷🏻‍♂ : man construction worker: light skin tone", +"👷🏼‍♂️ : man construction worker: medium-light skin tone", +"👷🏼‍♂ : man construction worker: medium-light skin tone", +"👷🏽‍♂️ : man construction worker: medium skin tone", +"👷🏽‍♂ : man construction worker: medium skin tone", +"👷🏾‍♂️ : man construction worker: medium-dark skin tone", +"👷🏾‍♂ : man construction worker: medium-dark skin tone", +"👷🏿‍♂️ : man construction worker: dark skin tone", +"👷🏿‍♂ : man construction worker: dark skin tone", +"👷‍♀️ : woman construction worker", +"👷‍♀ : woman construction worker", +"👷🏻‍♀️ : woman construction worker: light skin tone", +"👷🏻‍♀ : woman construction worker: light skin tone", +"👷🏼‍♀️ : woman construction worker: medium-light skin tone", +"👷🏼‍♀ : woman construction worker: medium-light skin tone", +"👷🏽‍♀️ : woman construction worker: medium skin tone", +"👷🏽‍♀ : woman construction worker: medium skin tone", +"👷🏾‍♀️ : woman construction worker: medium-dark skin tone", +"👷🏾‍♀ : woman construction worker: medium-dark skin tone", +"👷🏿‍♀️ : woman construction worker: dark skin tone", +"👷🏿‍♀ : woman construction worker: dark skin tone", +"🤴 : prince", +"🤴🏻 : prince: light skin tone", +"🤴🏼 : prince: medium-light skin tone", +"🤴🏽 : prince: medium skin tone", +"🤴🏾 : prince: medium-dark skin tone", +"🤴🏿 : prince: dark skin tone", +"👸 : princess", +"👸🏻 : princess: light skin tone", +"👸🏼 : princess: medium-light skin tone", +"👸🏽 : princess: medium skin tone", +"👸🏾 : princess: medium-dark skin tone", +"👸🏿 : princess: dark skin tone", +"👳 : person wearing turban", +"👳🏻 : person wearing turban: light skin tone", +"👳🏼 : person wearing turban: medium-light skin tone", +"👳🏽 : person wearing turban: medium skin tone", +"👳🏾 : person wearing turban: medium-dark skin tone", +"👳🏿 : person wearing turban: dark skin tone", +"👳‍♂️ : man wearing turban", +"👳‍♂ : man wearing turban", +"👳🏻‍♂️ : man wearing turban: light skin tone", +"👳🏻‍♂ : man wearing turban: light skin tone", +"👳🏼‍♂️ : man wearing turban: medium-light skin tone", +"👳🏼‍♂ : man wearing turban: medium-light skin tone", +"👳🏽‍♂️ : man wearing turban: medium skin tone", +"👳🏽‍♂ : man wearing turban: medium skin tone", +"👳🏾‍♂️ : man wearing turban: medium-dark skin tone", +"👳🏾‍♂ : man wearing turban: medium-dark skin tone", +"👳🏿‍♂️ : man wearing turban: dark skin tone", +"👳🏿‍♂ : man wearing turban: dark skin tone", +"👳‍♀️ : woman wearing turban", +"👳‍♀ : woman wearing turban", +"👳🏻‍♀️ : woman wearing turban: light skin tone", +"👳🏻‍♀ : woman wearing turban: light skin tone", +"👳🏼‍♀️ : woman wearing turban: medium-light skin tone", +"👳🏼‍♀ : woman wearing turban: medium-light skin tone", +"👳🏽‍♀️ : woman wearing turban: medium skin tone", +"👳🏽‍♀ : woman wearing turban: medium skin tone", +"👳🏾‍♀️ : woman wearing turban: medium-dark skin tone", +"👳🏾‍♀ : woman wearing turban: medium-dark skin tone", +"👳🏿‍♀️ : woman wearing turban: dark skin tone", +"👳🏿‍♀ : woman wearing turban: dark skin tone", +"👲 : man with chinese cap", +"👲🏻 : man with chinese cap: light skin tone", +"👲🏼 : man with chinese cap: medium-light skin tone", +"👲🏽 : man with chinese cap: medium skin tone", +"👲🏾 : man with chinese cap: medium-dark skin tone", +"👲🏿 : man with chinese cap: dark skin tone", +"🧕 : woman with headscarf", +"🧕🏻 : woman with headscarf: light skin tone", +"🧕🏼 : woman with headscarf: medium-light skin tone", +"🧕🏽 : woman with headscarf: medium skin tone", +"🧕🏾 : woman with headscarf: medium-dark skin tone", +"🧕🏿 : woman with headscarf: dark skin tone", +"🧔 : bearded person", +"🧔🏻 : bearded person: light skin tone", +"🧔🏼 : bearded person: medium-light skin tone", +"🧔🏽 : bearded person: medium skin tone", +"🧔🏾 : bearded person: medium-dark skin tone", +"🧔🏿 : bearded person: dark skin tone", +"👱 : blond-haired person", +"👱🏻 : blond-haired person: light skin tone", +"👱🏼 : blond-haired person: medium-light skin tone", +"👱🏽 : blond-haired person: medium skin tone", +"👱🏾 : blond-haired person: medium-dark skin tone", +"👱🏿 : blond-haired person: dark skin tone", +"👱‍♂️ : blond-haired man", +"👱‍♂ : blond-haired man", +"👱🏻‍♂️ : blond-haired man: light skin tone", +"👱🏻‍♂ : blond-haired man: light skin tone", +"👱🏼‍♂️ : blond-haired man: medium-light skin tone", +"👱🏼‍♂ : blond-haired man: medium-light skin tone", +"👱🏽‍♂️ : blond-haired man: medium skin tone", +"👱🏽‍♂ : blond-haired man: medium skin tone", +"👱🏾‍♂️ : blond-haired man: medium-dark skin tone", +"👱🏾‍♂ : blond-haired man: medium-dark skin tone", +"👱🏿‍♂️ : blond-haired man: dark skin tone", +"👱🏿‍♂ : blond-haired man: dark skin tone", +"👱‍♀️ : blond-haired woman", +"👱‍♀ : blond-haired woman", +"👱🏻‍♀️ : blond-haired woman: light skin tone", +"👱🏻‍♀ : blond-haired woman: light skin tone", +"👱🏼‍♀️ : blond-haired woman: medium-light skin tone", +"👱🏼‍♀ : blond-haired woman: medium-light skin tone", +"👱🏽‍♀️ : blond-haired woman: medium skin tone", +"👱🏽‍♀ : blond-haired woman: medium skin tone", +"👱🏾‍♀️ : blond-haired woman: medium-dark skin tone", +"👱🏾‍♀ : blond-haired woman: medium-dark skin tone", +"👱🏿‍♀️ : blond-haired woman: dark skin tone", +"👱🏿‍♀ : blond-haired woman: dark skin tone", +"👨‍🦰 : man, red haired", +"👨🏻‍🦰 : man, red haired: light skin tone", +"👨🏼‍🦰 : man, red haired: medium-light skin tone", +"👨🏽‍🦰 : man, red haired: medium skin tone", +"👨🏾‍🦰 : man, red haired: medium-dark skin tone", +"👨🏿‍🦰 : man, red haired: dark skin tone", +"👩‍🦰 : woman, red haired", +"👩🏻‍🦰 : woman, red haired: light skin tone", +"👩🏼‍🦰 : woman, red haired: medium-light skin tone", +"👩🏽‍🦰 : woman, red haired: medium skin tone", +"👩🏾‍🦰 : woman, red haired: medium-dark skin tone", +"👩🏿‍🦰 : woman, red haired: dark skin tone", +"👨‍🦱 : man, curly haired", +"👨🏻‍🦱 : man, curly haired: light skin tone", +"👨🏼‍🦱 : man, curly haired: medium-light skin tone", +"👨🏽‍🦱 : man, curly haired: medium skin tone", +"👨🏾‍🦱 : man, curly haired: medium-dark skin tone", +"👨🏿‍🦱 : man, curly haired: dark skin tone", +"👩‍🦱 : woman, curly haired", +"👩🏻‍🦱 : woman, curly haired: light skin tone", +"👩🏼‍🦱 : woman, curly haired: medium-light skin tone", +"👩🏽‍🦱 : woman, curly haired: medium skin tone", +"👩🏾‍🦱 : woman, curly haired: medium-dark skin tone", +"👩🏿‍🦱 : woman, curly haired: dark skin tone", +"👨‍🦲 : man, bald", +"👨🏻‍🦲 : man, bald: light skin tone", +"👨🏼‍🦲 : man, bald: medium-light skin tone", +"👨🏽‍🦲 : man, bald: medium skin tone", +"👨🏾‍🦲 : man, bald: medium-dark skin tone", +"👨🏿‍🦲 : man, bald: dark skin tone", +"👩‍🦲 : woman, bald", +"👩🏻‍🦲 : woman, bald: light skin tone", +"👩🏼‍🦲 : woman, bald: medium-light skin tone", +"👩🏽‍🦲 : woman, bald: medium skin tone", +"👩🏾‍🦲 : woman, bald: medium-dark skin tone", +"👩🏿‍🦲 : woman, bald: dark skin tone", +"👨‍🦳 : man, white haired", +"👨🏻‍🦳 : man, white haired: light skin tone", +"👨🏼‍🦳 : man, white haired: medium-light skin tone", +"👨🏽‍🦳 : man, white haired: medium skin tone", +"👨🏾‍🦳 : man, white haired: medium-dark skin tone", +"👨🏿‍🦳 : man, white haired: dark skin tone", +"👩‍🦳 : woman, white haired", +"👩🏻‍🦳 : woman, white haired: light skin tone", +"👩🏼‍🦳 : woman, white haired: medium-light skin tone", +"👩🏽‍🦳 : woman, white haired: medium skin tone", +"👩🏾‍🦳 : woman, white haired: medium-dark skin tone", +"👩🏿‍🦳 : woman, white haired: dark skin tone", +"🤵 : man in tuxedo", +"🤵🏻 : man in tuxedo: light skin tone", +"🤵🏼 : man in tuxedo: medium-light skin tone", +"🤵🏽 : man in tuxedo: medium skin tone", +"🤵🏾 : man in tuxedo: medium-dark skin tone", +"🤵🏿 : man in tuxedo: dark skin tone", +"👰 : bride with veil", +"👰🏻 : bride with veil: light skin tone", +"👰🏼 : bride with veil: medium-light skin tone", +"👰🏽 : bride with veil: medium skin tone", +"👰🏾 : bride with veil: medium-dark skin tone", +"👰🏿 : bride with veil: dark skin tone", +"🤰 : pregnant woman", +"🤰🏻 : pregnant woman: light skin tone", +"🤰🏼 : pregnant woman: medium-light skin tone", +"🤰🏽 : pregnant woman: medium skin tone", +"🤰🏾 : pregnant woman: medium-dark skin tone", +"🤰🏿 : pregnant woman: dark skin tone", +"🤱 : breast-feeding", +"🤱🏻 : breast-feeding: light skin tone", +"🤱🏼 : breast-feeding: medium-light skin tone", +"🤱🏽 : breast-feeding: medium skin tone", +"🤱🏾 : breast-feeding: medium-dark skin tone", +"🤱🏿 : breast-feeding: dark skin tone", +"👼 : baby angel", +"👼🏻 : baby angel: light skin tone", +"👼🏼 : baby angel: medium-light skin tone", +"👼🏽 : baby angel: medium skin tone", +"👼🏾 : baby angel: medium-dark skin tone", +"👼🏿 : baby angel: dark skin tone", +"🎅 : santa claus", +"🎅🏻 : santa claus: light skin tone", +"🎅🏼 : santa claus: medium-light skin tone", +"🎅🏽 : santa claus: medium skin tone", +"🎅🏾 : santa claus: medium-dark skin tone", +"🎅🏿 : santa claus: dark skin tone", +"🤶 : mrs. claus", +"🤶🏻 : mrs. claus: light skin tone", +"🤶🏼 : mrs. claus: medium-light skin tone", +"🤶🏽 : mrs. claus: medium skin tone", +"🤶🏾 : mrs. claus: medium-dark skin tone", +"🤶🏿 : mrs. claus: dark skin tone", +"🦸 : superhero", +"🦸🏻 : superhero: light skin tone", +"🦸🏼 : superhero: medium-light skin tone", +"🦸🏽 : superhero: medium skin tone", +"🦸🏾 : superhero: medium-dark skin tone", +"🦸🏿 : superhero: dark skin tone", +"🦸‍♀️ : woman superhero", +"🦸‍♀ : woman superhero", +"🦸🏻‍♀️ : woman superhero: light skin tone", +"🦸🏻‍♀ : woman superhero: light skin tone", +"🦸🏼‍♀️ : woman superhero: medium-light skin tone", +"🦸🏼‍♀ : woman superhero: medium-light skin tone", +"🦸🏽‍♀️ : woman superhero: medium skin tone", +"🦸🏽‍♀ : woman superhero: medium skin tone", +"🦸🏾‍♀️ : woman superhero: medium-dark skin tone", +"🦸🏾‍♀ : woman superhero: medium-dark skin tone", +"🦸🏿‍♀️ : woman superhero: dark skin tone", +"🦸🏿‍♀ : woman superhero: dark skin tone", +"🦸‍♂️ : man superhero", +"🦸‍♂ : man superhero", +"🦸🏻‍♂️ : man superhero: light skin tone", +"🦸🏻‍♂ : man superhero: light skin tone", +"🦸🏼‍♂️ : man superhero: medium-light skin tone", +"🦸🏼‍♂ : man superhero: medium-light skin tone", +"🦸🏽‍♂️ : man superhero: medium skin tone", +"🦸🏽‍♂ : man superhero: medium skin tone", +"🦸🏾‍♂️ : man superhero: medium-dark skin tone", +"🦸🏾‍♂ : man superhero: medium-dark skin tone", +"🦸🏿‍♂️ : man superhero: dark skin tone", +"🦸🏿‍♂ : man superhero: dark skin tone", +"🦹 : supervillain", +"🦹🏻 : supervillain: light skin tone", +"🦹🏼 : supervillain: medium-light skin tone", +"🦹🏽 : supervillain: medium skin tone", +"🦹🏾 : supervillain: medium-dark skin tone", +"🦹🏿 : supervillain: dark skin tone", +"🦹‍♀️ : woman supervillain", +"🦹‍♀ : woman supervillain", +"🦹🏻‍♀️ : woman supervillain: light skin tone", +"🦹🏻‍♀ : woman supervillain: light skin tone", +"🦹🏼‍♀️ : woman supervillain: medium-light skin tone", +"🦹🏼‍♀ : woman supervillain: medium-light skin tone", +"🦹🏽‍♀️ : woman supervillain: medium skin tone", +"🦹🏽‍♀ : woman supervillain: medium skin tone", +"🦹🏾‍♀️ : woman supervillain: medium-dark skin tone", +"🦹🏾‍♀ : woman supervillain: medium-dark skin tone", +"🦹🏿‍♀️ : woman supervillain: dark skin tone", +"🦹🏿‍♀ : woman supervillain: dark skin tone", +"🦹‍♂️ : man supervillain", +"🦹‍♂ : man supervillain", +"🦹🏻‍♂️ : man supervillain: light skin tone", +"🦹🏻‍♂ : man supervillain: light skin tone", +"🦹🏼‍♂️ : man supervillain: medium-light skin tone", +"🦹🏼‍♂ : man supervillain: medium-light skin tone", +"🦹🏽‍♂️ : man supervillain: medium skin tone", +"🦹🏽‍♂ : man supervillain: medium skin tone", +"🦹🏾‍♂️ : man supervillain: medium-dark skin tone", +"🦹🏾‍♂ : man supervillain: medium-dark skin tone", +"🦹🏿‍♂️ : man supervillain: dark skin tone", +"🦹🏿‍♂ : man supervillain: dark skin tone", +"🧙 : mage", +"🧙🏻 : mage: light skin tone", +"🧙🏼 : mage: medium-light skin tone", +"🧙🏽 : mage: medium skin tone", +"🧙🏾 : mage: medium-dark skin tone", +"🧙🏿 : mage: dark skin tone", +"🧙‍♀️ : woman mage", +"🧙‍♀ : woman mage", +"🧙🏻‍♀️ : woman mage: light skin tone", +"🧙🏻‍♀ : woman mage: light skin tone", +"🧙🏼‍♀️ : woman mage: medium-light skin tone", +"🧙🏼‍♀ : woman mage: medium-light skin tone", +"🧙🏽‍♀️ : woman mage: medium skin tone", +"🧙🏽‍♀ : woman mage: medium skin tone", +"🧙🏾‍♀️ : woman mage: medium-dark skin tone", +"🧙🏾‍♀ : woman mage: medium-dark skin tone", +"🧙🏿‍♀️ : woman mage: dark skin tone", +"🧙🏿‍♀ : woman mage: dark skin tone", +"🧙‍♂️ : man mage", +"🧙‍♂ : man mage", +"🧙🏻‍♂️ : man mage: light skin tone", +"🧙🏻‍♂ : man mage: light skin tone", +"🧙🏼‍♂️ : man mage: medium-light skin tone", +"🧙🏼‍♂ : man mage: medium-light skin tone", +"🧙🏽‍♂️ : man mage: medium skin tone", +"🧙🏽‍♂ : man mage: medium skin tone", +"🧙🏾‍♂️ : man mage: medium-dark skin tone", +"🧙🏾‍♂ : man mage: medium-dark skin tone", +"🧙🏿‍♂️ : man mage: dark skin tone", +"🧙🏿‍♂ : man mage: dark skin tone", +"🧚 : fairy", +"🧚🏻 : fairy: light skin tone", +"🧚🏼 : fairy: medium-light skin tone", +"🧚🏽 : fairy: medium skin tone", +"🧚🏾 : fairy: medium-dark skin tone", +"🧚🏿 : fairy: dark skin tone", +"🧚‍♀️ : woman fairy", +"🧚‍♀ : woman fairy", +"🧚🏻‍♀️ : woman fairy: light skin tone", +"🧚🏻‍♀ : woman fairy: light skin tone", +"🧚🏼‍♀️ : woman fairy: medium-light skin tone", +"🧚🏼‍♀ : woman fairy: medium-light skin tone", +"🧚🏽‍♀️ : woman fairy: medium skin tone", +"🧚🏽‍♀ : woman fairy: medium skin tone", +"🧚🏾‍♀️ : woman fairy: medium-dark skin tone", +"🧚🏾‍♀ : woman fairy: medium-dark skin tone", +"🧚🏿‍♀️ : woman fairy: dark skin tone", +"🧚🏿‍♀ : woman fairy: dark skin tone", +"🧚‍♂️ : man fairy", +"🧚‍♂ : man fairy", +"🧚🏻‍♂️ : man fairy: light skin tone", +"🧚🏻‍♂ : man fairy: light skin tone", +"🧚🏼‍♂️ : man fairy: medium-light skin tone", +"🧚🏼‍♂ : man fairy: medium-light skin tone", +"🧚🏽‍♂️ : man fairy: medium skin tone", +"🧚🏽‍♂ : man fairy: medium skin tone", +"🧚🏾‍♂️ : man fairy: medium-dark skin tone", +"🧚🏾‍♂ : man fairy: medium-dark skin tone", +"🧚🏿‍♂️ : man fairy: dark skin tone", +"🧚🏿‍♂ : man fairy: dark skin tone", +"🧛 : vampire", +"🧛🏻 : vampire: light skin tone", +"🧛🏼 : vampire: medium-light skin tone", +"🧛🏽 : vampire: medium skin tone", +"🧛🏾 : vampire: medium-dark skin tone", +"🧛🏿 : vampire: dark skin tone", +"🧛‍♀️ : woman vampire", +"🧛‍♀ : woman vampire", +"🧛🏻‍♀️ : woman vampire: light skin tone", +"🧛🏻‍♀ : woman vampire: light skin tone", +"🧛🏼‍♀️ : woman vampire: medium-light skin tone", +"🧛🏼‍♀ : woman vampire: medium-light skin tone", +"🧛🏽‍♀️ : woman vampire: medium skin tone", +"🧛🏽‍♀ : woman vampire: medium skin tone", +"🧛🏾‍♀️ : woman vampire: medium-dark skin tone", +"🧛🏾‍♀ : woman vampire: medium-dark skin tone", +"🧛🏿‍♀️ : woman vampire: dark skin tone", +"🧛🏿‍♀ : woman vampire: dark skin tone", +"🧛‍♂️ : man vampire", +"🧛‍♂ : man vampire", +"🧛🏻‍♂️ : man vampire: light skin tone", +"🧛🏻‍♂ : man vampire: light skin tone", +"🧛🏼‍♂️ : man vampire: medium-light skin tone", +"🧛🏼‍♂ : man vampire: medium-light skin tone", +"🧛🏽‍♂️ : man vampire: medium skin tone", +"🧛🏽‍♂ : man vampire: medium skin tone", +"🧛🏾‍♂️ : man vampire: medium-dark skin tone", +"🧛🏾‍♂ : man vampire: medium-dark skin tone", +"🧛🏿‍♂️ : man vampire: dark skin tone", +"🧛🏿‍♂ : man vampire: dark skin tone", +"🧜 : merperson", +"🧜🏻 : merperson: light skin tone", +"🧜🏼 : merperson: medium-light skin tone", +"🧜🏽 : merperson: medium skin tone", +"🧜🏾 : merperson: medium-dark skin tone", +"🧜🏿 : merperson: dark skin tone", +"🧜‍♀️ : mermaid", +"🧜‍♀ : mermaid", +"🧜🏻‍♀️ : mermaid: light skin tone", +"🧜🏻‍♀ : mermaid: light skin tone", +"🧜🏼‍♀️ : mermaid: medium-light skin tone", +"🧜🏼‍♀ : mermaid: medium-light skin tone", +"🧜🏽‍♀️ : mermaid: medium skin tone", +"🧜🏽‍♀ : mermaid: medium skin tone", +"🧜🏾‍♀️ : mermaid: medium-dark skin tone", +"🧜🏾‍♀ : mermaid: medium-dark skin tone", +"🧜🏿‍♀️ : mermaid: dark skin tone", +"🧜🏿‍♀ : mermaid: dark skin tone", +"🧜‍♂️ : merman", +"🧜‍♂ : merman", +"🧜🏻‍♂️ : merman: light skin tone", +"🧜🏻‍♂ : merman: light skin tone", +"🧜🏼‍♂️ : merman: medium-light skin tone", +"🧜🏼‍♂ : merman: medium-light skin tone", +"🧜🏽‍♂️ : merman: medium skin tone", +"🧜🏽‍♂ : merman: medium skin tone", +"🧜🏾‍♂️ : merman: medium-dark skin tone", +"🧜🏾‍♂ : merman: medium-dark skin tone", +"🧜🏿‍♂️ : merman: dark skin tone", +"🧜🏿‍♂ : merman: dark skin tone", +"🧝 : elf", +"🧝🏻 : elf: light skin tone", +"🧝🏼 : elf: medium-light skin tone", +"🧝🏽 : elf: medium skin tone", +"🧝🏾 : elf: medium-dark skin tone", +"🧝🏿 : elf: dark skin tone", +"🧝‍♀️ : woman elf", +"🧝‍♀ : woman elf", +"🧝🏻‍♀️ : woman elf: light skin tone", +"🧝🏻‍♀ : woman elf: light skin tone", +"🧝🏼‍♀️ : woman elf: medium-light skin tone", +"🧝🏼‍♀ : woman elf: medium-light skin tone", +"🧝🏽‍♀️ : woman elf: medium skin tone", +"🧝🏽‍♀ : woman elf: medium skin tone", +"🧝🏾‍♀️ : woman elf: medium-dark skin tone", +"🧝🏾‍♀ : woman elf: medium-dark skin tone", +"🧝🏿‍♀️ : woman elf: dark skin tone", +"🧝🏿‍♀ : woman elf: dark skin tone", +"🧝‍♂️ : man elf", +"🧝‍♂ : man elf", +"🧝🏻‍♂️ : man elf: light skin tone", +"🧝🏻‍♂ : man elf: light skin tone", +"🧝🏼‍♂️ : man elf: medium-light skin tone", +"🧝🏼‍♂ : man elf: medium-light skin tone", +"🧝🏽‍♂️ : man elf: medium skin tone", +"🧝🏽‍♂ : man elf: medium skin tone", +"🧝🏾‍♂️ : man elf: medium-dark skin tone", +"🧝🏾‍♂ : man elf: medium-dark skin tone", +"🧝🏿‍♂️ : man elf: dark skin tone", +"🧝🏿‍♂ : man elf: dark skin tone", +"🧞 : genie", +"🧞‍♀️ : woman genie", +"🧞‍♀ : woman genie", +"🧞‍♂️ : man genie", +"🧞‍♂ : man genie", +"🧟 : zombie", +"🧟‍♀️ : woman zombie", +"🧟‍♀ : woman zombie", +"🧟‍♂️ : man zombie", +"🧟‍♂ : man zombie", +"🙍 : person frowning", +"🙍🏻 : person frowning: light skin tone", +"🙍🏼 : person frowning: medium-light skin tone", +"🙍🏽 : person frowning: medium skin tone", +"🙍🏾 : person frowning: medium-dark skin tone", +"🙍🏿 : person frowning: dark skin tone", +"🙍‍♂️ : man frowning", +"🙍‍♂ : man frowning", +"🙍🏻‍♂️ : man frowning: light skin tone", +"🙍🏻‍♂ : man frowning: light skin tone", +"🙍🏼‍♂️ : man frowning: medium-light skin tone", +"🙍🏼‍♂ : man frowning: medium-light skin tone", +"🙍🏽‍♂️ : man frowning: medium skin tone", +"🙍🏽‍♂ : man frowning: medium skin tone", +"🙍🏾‍♂️ : man frowning: medium-dark skin tone", +"🙍🏾‍♂ : man frowning: medium-dark skin tone", +"🙍🏿‍♂️ : man frowning: dark skin tone", +"🙍🏿‍♂ : man frowning: dark skin tone", +"🙍‍♀️ : woman frowning", +"🙍‍♀ : woman frowning", +"🙍🏻‍♀️ : woman frowning: light skin tone", +"🙍🏻‍♀ : woman frowning: light skin tone", +"🙍🏼‍♀️ : woman frowning: medium-light skin tone", +"🙍🏼‍♀ : woman frowning: medium-light skin tone", +"🙍🏽‍♀️ : woman frowning: medium skin tone", +"🙍🏽‍♀ : woman frowning: medium skin tone", +"🙍🏾‍♀️ : woman frowning: medium-dark skin tone", +"🙍🏾‍♀ : woman frowning: medium-dark skin tone", +"🙍🏿‍♀️ : woman frowning: dark skin tone", +"🙍🏿‍♀ : woman frowning: dark skin tone", +"🙎 : person pouting", +"🙎🏻 : person pouting: light skin tone", +"🙎🏼 : person pouting: medium-light skin tone", +"🙎🏽 : person pouting: medium skin tone", +"🙎🏾 : person pouting: medium-dark skin tone", +"🙎🏿 : person pouting: dark skin tone", +"🙎‍♂️ : man pouting", +"🙎‍♂ : man pouting", +"🙎🏻‍♂️ : man pouting: light skin tone", +"🙎🏻‍♂ : man pouting: light skin tone", +"🙎🏼‍♂️ : man pouting: medium-light skin tone", +"🙎🏼‍♂ : man pouting: medium-light skin tone", +"🙎🏽‍♂️ : man pouting: medium skin tone", +"🙎🏽‍♂ : man pouting: medium skin tone", +"🙎🏾‍♂️ : man pouting: medium-dark skin tone", +"🙎🏾‍♂ : man pouting: medium-dark skin tone", +"🙎🏿‍♂️ : man pouting: dark skin tone", +"🙎🏿‍♂ : man pouting: dark skin tone", +"🙎‍♀️ : woman pouting", +"🙎‍♀ : woman pouting", +"🙎🏻‍♀️ : woman pouting: light skin tone", +"🙎🏻‍♀ : woman pouting: light skin tone", +"🙎🏼‍♀️ : woman pouting: medium-light skin tone", +"🙎🏼‍♀ : woman pouting: medium-light skin tone", +"🙎🏽‍♀️ : woman pouting: medium skin tone", +"🙎🏽‍♀ : woman pouting: medium skin tone", +"🙎🏾‍♀️ : woman pouting: medium-dark skin tone", +"🙎🏾‍♀ : woman pouting: medium-dark skin tone", +"🙎🏿‍♀️ : woman pouting: dark skin tone", +"🙎🏿‍♀ : woman pouting: dark skin tone", +"🙅 : person gesturing no", +"🙅🏻 : person gesturing no: light skin tone", +"🙅🏼 : person gesturing no: medium-light skin tone", +"🙅🏽 : person gesturing no: medium skin tone", +"🙅🏾 : person gesturing no: medium-dark skin tone", +"🙅🏿 : person gesturing no: dark skin tone", +"🙅‍♂️ : man gesturing no", +"🙅‍♂ : man gesturing no", +"🙅🏻‍♂️ : man gesturing no: light skin tone", +"🙅🏻‍♂ : man gesturing no: light skin tone", +"🙅🏼‍♂️ : man gesturing no: medium-light skin tone", +"🙅🏼‍♂ : man gesturing no: medium-light skin tone", +"🙅🏽‍♂️ : man gesturing no: medium skin tone", +"🙅🏽‍♂ : man gesturing no: medium skin tone", +"🙅🏾‍♂️ : man gesturing no: medium-dark skin tone", +"🙅🏾‍♂ : man gesturing no: medium-dark skin tone", +"🙅🏿‍♂️ : man gesturing no: dark skin tone", +"🙅🏿‍♂ : man gesturing no: dark skin tone", +"🙅‍♀️ : woman gesturing no", +"🙅‍♀ : woman gesturing no", +"🙅🏻‍♀️ : woman gesturing no: light skin tone", +"🙅🏻‍♀ : woman gesturing no: light skin tone", +"🙅🏼‍♀️ : woman gesturing no: medium-light skin tone", +"🙅🏼‍♀ : woman gesturing no: medium-light skin tone", +"🙅🏽‍♀️ : woman gesturing no: medium skin tone", +"🙅🏽‍♀ : woman gesturing no: medium skin tone", +"🙅🏾‍♀️ : woman gesturing no: medium-dark skin tone", +"🙅🏾‍♀ : woman gesturing no: medium-dark skin tone", +"🙅🏿‍♀️ : woman gesturing no: dark skin tone", +"🙅🏿‍♀ : woman gesturing no: dark skin tone", +"🙆 : person gesturing ok", +"🙆🏻 : person gesturing ok: light skin tone", +"🙆🏼 : person gesturing ok: medium-light skin tone", +"🙆🏽 : person gesturing ok: medium skin tone", +"🙆🏾 : person gesturing ok: medium-dark skin tone", +"🙆🏿 : person gesturing ok: dark skin tone", +"🙆‍♂️ : man gesturing ok", +"🙆‍♂ : man gesturing ok", +"🙆🏻‍♂️ : man gesturing ok: light skin tone", +"🙆🏻‍♂ : man gesturing ok: light skin tone", +"🙆🏼‍♂️ : man gesturing ok: medium-light skin tone", +"🙆🏼‍♂ : man gesturing ok: medium-light skin tone", +"🙆🏽‍♂️ : man gesturing ok: medium skin tone", +"🙆🏽‍♂ : man gesturing ok: medium skin tone", +"🙆🏾‍♂️ : man gesturing ok: medium-dark skin tone", +"🙆🏾‍♂ : man gesturing ok: medium-dark skin tone", +"🙆🏿‍♂️ : man gesturing ok: dark skin tone", +"🙆🏿‍♂ : man gesturing ok: dark skin tone", +"🙆‍♀️ : woman gesturing ok", +"🙆‍♀ : woman gesturing ok", +"🙆🏻‍♀️ : woman gesturing ok: light skin tone", +"🙆🏻‍♀ : woman gesturing ok: light skin tone", +"🙆🏼‍♀️ : woman gesturing ok: medium-light skin tone", +"🙆🏼‍♀ : woman gesturing ok: medium-light skin tone", +"🙆🏽‍♀️ : woman gesturing ok: medium skin tone", +"🙆🏽‍♀ : woman gesturing ok: medium skin tone", +"🙆🏾‍♀️ : woman gesturing ok: medium-dark skin tone", +"🙆🏾‍♀ : woman gesturing ok: medium-dark skin tone", +"🙆🏿‍♀️ : woman gesturing ok: dark skin tone", +"🙆🏿‍♀ : woman gesturing ok: dark skin tone", +"💁 : person tipping hand", +"💁🏻 : person tipping hand: light skin tone", +"💁🏼 : person tipping hand: medium-light skin tone", +"💁🏽 : person tipping hand: medium skin tone", +"💁🏾 : person tipping hand: medium-dark skin tone", +"💁🏿 : person tipping hand: dark skin tone", +"💁‍♂️ : man tipping hand", +"💁‍♂ : man tipping hand", +"💁🏻‍♂️ : man tipping hand: light skin tone", +"💁🏻‍♂ : man tipping hand: light skin tone", +"💁🏼‍♂️ : man tipping hand: medium-light skin tone", +"💁🏼‍♂ : man tipping hand: medium-light skin tone", +"💁🏽‍♂️ : man tipping hand: medium skin tone", +"💁🏽‍♂ : man tipping hand: medium skin tone", +"💁🏾‍♂️ : man tipping hand: medium-dark skin tone", +"💁🏾‍♂ : man tipping hand: medium-dark skin tone", +"💁🏿‍♂️ : man tipping hand: dark skin tone", +"💁🏿‍♂ : man tipping hand: dark skin tone", +"💁‍♀️ : woman tipping hand", +"💁‍♀ : woman tipping hand", +"💁🏻‍♀️ : woman tipping hand: light skin tone", +"💁🏻‍♀ : woman tipping hand: light skin tone", +"💁🏼‍♀️ : woman tipping hand: medium-light skin tone", +"💁🏼‍♀ : woman tipping hand: medium-light skin tone", +"💁🏽‍♀️ : woman tipping hand: medium skin tone", +"💁🏽‍♀ : woman tipping hand: medium skin tone", +"💁🏾‍♀️ : woman tipping hand: medium-dark skin tone", +"💁🏾‍♀ : woman tipping hand: medium-dark skin tone", +"💁🏿‍♀️ : woman tipping hand: dark skin tone", +"💁🏿‍♀ : woman tipping hand: dark skin tone", +"🙋 : person raising hand", +"🙋🏻 : person raising hand: light skin tone", +"🙋🏼 : person raising hand: medium-light skin tone", +"🙋🏽 : person raising hand: medium skin tone", +"🙋🏾 : person raising hand: medium-dark skin tone", +"🙋🏿 : person raising hand: dark skin tone", +"🙋‍♂️ : man raising hand", +"🙋‍♂ : man raising hand", +"🙋🏻‍♂️ : man raising hand: light skin tone", +"🙋🏻‍♂ : man raising hand: light skin tone", +"🙋🏼‍♂️ : man raising hand: medium-light skin tone", +"🙋🏼‍♂ : man raising hand: medium-light skin tone", +"🙋🏽‍♂️ : man raising hand: medium skin tone", +"🙋🏽‍♂ : man raising hand: medium skin tone", +"🙋🏾‍♂️ : man raising hand: medium-dark skin tone", +"🙋🏾‍♂ : man raising hand: medium-dark skin tone", +"🙋🏿‍♂️ : man raising hand: dark skin tone", +"🙋🏿‍♂ : man raising hand: dark skin tone", +"🙋‍♀️ : woman raising hand", +"🙋‍♀ : woman raising hand", +"🙋🏻‍♀️ : woman raising hand: light skin tone", +"🙋🏻‍♀ : woman raising hand: light skin tone", +"🙋🏼‍♀️ : woman raising hand: medium-light skin tone", +"🙋🏼‍♀ : woman raising hand: medium-light skin tone", +"🙋🏽‍♀️ : woman raising hand: medium skin tone", +"🙋🏽‍♀ : woman raising hand: medium skin tone", +"🙋🏾‍♀️ : woman raising hand: medium-dark skin tone", +"🙋🏾‍♀ : woman raising hand: medium-dark skin tone", +"🙋🏿‍♀️ : woman raising hand: dark skin tone", +"🙋🏿‍♀ : woman raising hand: dark skin tone", +"🙇 : person bowing", +"🙇🏻 : person bowing: light skin tone", +"🙇🏼 : person bowing: medium-light skin tone", +"🙇🏽 : person bowing: medium skin tone", +"🙇🏾 : person bowing: medium-dark skin tone", +"🙇🏿 : person bowing: dark skin tone", +"🙇‍♂️ : man bowing", +"🙇‍♂ : man bowing", +"🙇🏻‍♂️ : man bowing: light skin tone", +"🙇🏻‍♂ : man bowing: light skin tone", +"🙇🏼‍♂️ : man bowing: medium-light skin tone", +"🙇🏼‍♂ : man bowing: medium-light skin tone", +"🙇🏽‍♂️ : man bowing: medium skin tone", +"🙇🏽‍♂ : man bowing: medium skin tone", +"🙇🏾‍♂️ : man bowing: medium-dark skin tone", +"🙇🏾‍♂ : man bowing: medium-dark skin tone", +"🙇🏿‍♂️ : man bowing: dark skin tone", +"🙇🏿‍♂ : man bowing: dark skin tone", +"🙇‍♀️ : woman bowing", +"🙇‍♀ : woman bowing", +"🙇🏻‍♀️ : woman bowing: light skin tone", +"🙇🏻‍♀ : woman bowing: light skin tone", +"🙇🏼‍♀️ : woman bowing: medium-light skin tone", +"🙇🏼‍♀ : woman bowing: medium-light skin tone", +"🙇🏽‍♀️ : woman bowing: medium skin tone", +"🙇🏽‍♀ : woman bowing: medium skin tone", +"🙇🏾‍♀️ : woman bowing: medium-dark skin tone", +"🙇🏾‍♀ : woman bowing: medium-dark skin tone", +"🙇🏿‍♀️ : woman bowing: dark skin tone", +"🙇🏿‍♀ : woman bowing: dark skin tone", +"🤦 : person facepalming", +"🤦🏻 : person facepalming: light skin tone", +"🤦🏼 : person facepalming: medium-light skin tone", +"🤦🏽 : person facepalming: medium skin tone", +"🤦🏾 : person facepalming: medium-dark skin tone", +"🤦🏿 : person facepalming: dark skin tone", +"🤦‍♂️ : man facepalming", +"🤦‍♂ : man facepalming", +"🤦🏻‍♂️ : man facepalming: light skin tone", +"🤦🏻‍♂ : man facepalming: light skin tone", +"🤦🏼‍♂️ : man facepalming: medium-light skin tone", +"🤦🏼‍♂ : man facepalming: medium-light skin tone", +"🤦🏽‍♂️ : man facepalming: medium skin tone", +"🤦🏽‍♂ : man facepalming: medium skin tone", +"🤦🏾‍♂️ : man facepalming: medium-dark skin tone", +"🤦🏾‍♂ : man facepalming: medium-dark skin tone", +"🤦🏿‍♂️ : man facepalming: dark skin tone", +"🤦🏿‍♂ : man facepalming: dark skin tone", +"🤦‍♀️ : woman facepalming", +"🤦‍♀ : woman facepalming", +"🤦🏻‍♀️ : woman facepalming: light skin tone", +"🤦🏻‍♀ : woman facepalming: light skin tone", +"🤦🏼‍♀️ : woman facepalming: medium-light skin tone", +"🤦🏼‍♀ : woman facepalming: medium-light skin tone", +"🤦🏽‍♀️ : woman facepalming: medium skin tone", +"🤦🏽‍♀ : woman facepalming: medium skin tone", +"🤦🏾‍♀️ : woman facepalming: medium-dark skin tone", +"🤦🏾‍♀ : woman facepalming: medium-dark skin tone", +"🤦🏿‍♀️ : woman facepalming: dark skin tone", +"🤦🏿‍♀ : woman facepalming: dark skin tone", +"🤷 : person shrugging", +"🤷🏻 : person shrugging: light skin tone", +"🤷🏼 : person shrugging: medium-light skin tone", +"🤷🏽 : person shrugging: medium skin tone", +"🤷🏾 : person shrugging: medium-dark skin tone", +"🤷🏿 : person shrugging: dark skin tone", +"🤷‍♂️ : man shrugging", +"🤷‍♂ : man shrugging", +"🤷🏻‍♂️ : man shrugging: light skin tone", +"🤷🏻‍♂ : man shrugging: light skin tone", +"🤷🏼‍♂️ : man shrugging: medium-light skin tone", +"🤷🏼‍♂ : man shrugging: medium-light skin tone", +"🤷🏽‍♂️ : man shrugging: medium skin tone", +"🤷🏽‍♂ : man shrugging: medium skin tone", +"🤷🏾‍♂️ : man shrugging: medium-dark skin tone", +"🤷🏾‍♂ : man shrugging: medium-dark skin tone", +"🤷🏿‍♂️ : man shrugging: dark skin tone", +"🤷🏿‍♂ : man shrugging: dark skin tone", +"🤷‍♀️ : woman shrugging", +"🤷‍♀ : woman shrugging", +"🤷🏻‍♀️ : woman shrugging: light skin tone", +"🤷🏻‍♀ : woman shrugging: light skin tone", +"🤷🏼‍♀️ : woman shrugging: medium-light skin tone", +"🤷🏼‍♀ : woman shrugging: medium-light skin tone", +"🤷🏽‍♀️ : woman shrugging: medium skin tone", +"🤷🏽‍♀ : woman shrugging: medium skin tone", +"🤷🏾‍♀️ : woman shrugging: medium-dark skin tone", +"🤷🏾‍♀ : woman shrugging: medium-dark skin tone", +"🤷🏿‍♀️ : woman shrugging: dark skin tone", +"🤷🏿‍♀ : woman shrugging: dark skin tone", +"💆 : person getting massage", +"💆🏻 : person getting massage: light skin tone", +"💆🏼 : person getting massage: medium-light skin tone", +"💆🏽 : person getting massage: medium skin tone", +"💆🏾 : person getting massage: medium-dark skin tone", +"💆🏿 : person getting massage: dark skin tone", +"💆‍♂️ : man getting massage", +"💆‍♂ : man getting massage", +"💆🏻‍♂️ : man getting massage: light skin tone", +"💆🏻‍♂ : man getting massage: light skin tone", +"💆🏼‍♂️ : man getting massage: medium-light skin tone", +"💆🏼‍♂ : man getting massage: medium-light skin tone", +"💆🏽‍♂️ : man getting massage: medium skin tone", +"💆🏽‍♂ : man getting massage: medium skin tone", +"💆🏾‍♂️ : man getting massage: medium-dark skin tone", +"💆🏾‍♂ : man getting massage: medium-dark skin tone", +"💆🏿‍♂️ : man getting massage: dark skin tone", +"💆🏿‍♂ : man getting massage: dark skin tone", +"💆‍♀️ : woman getting massage", +"💆‍♀ : woman getting massage", +"💆🏻‍♀️ : woman getting massage: light skin tone", +"💆🏻‍♀ : woman getting massage: light skin tone", +"💆🏼‍♀️ : woman getting massage: medium-light skin tone", +"💆🏼‍♀ : woman getting massage: medium-light skin tone", +"💆🏽‍♀️ : woman getting massage: medium skin tone", +"💆🏽‍♀ : woman getting massage: medium skin tone", +"💆🏾‍♀️ : woman getting massage: medium-dark skin tone", +"💆🏾‍♀ : woman getting massage: medium-dark skin tone", +"💆🏿‍♀️ : woman getting massage: dark skin tone", +"💆🏿‍♀ : woman getting massage: dark skin tone", +"💇 : person getting haircut", +"💇🏻 : person getting haircut: light skin tone", +"💇🏼 : person getting haircut: medium-light skin tone", +"💇🏽 : person getting haircut: medium skin tone", +"💇🏾 : person getting haircut: medium-dark skin tone", +"💇🏿 : person getting haircut: dark skin tone", +"💇‍♂️ : man getting haircut", +"💇‍♂ : man getting haircut", +"💇🏻‍♂️ : man getting haircut: light skin tone", +"💇🏻‍♂ : man getting haircut: light skin tone", +"💇🏼‍♂️ : man getting haircut: medium-light skin tone", +"💇🏼‍♂ : man getting haircut: medium-light skin tone", +"💇🏽‍♂️ : man getting haircut: medium skin tone", +"💇🏽‍♂ : man getting haircut: medium skin tone", +"💇🏾‍♂️ : man getting haircut: medium-dark skin tone", +"💇🏾‍♂ : man getting haircut: medium-dark skin tone", +"💇🏿‍♂️ : man getting haircut: dark skin tone", +"💇🏿‍♂ : man getting haircut: dark skin tone", +"💇‍♀️ : woman getting haircut", +"💇‍♀ : woman getting haircut", +"💇🏻‍♀️ : woman getting haircut: light skin tone", +"💇🏻‍♀ : woman getting haircut: light skin tone", +"💇🏼‍♀️ : woman getting haircut: medium-light skin tone", +"💇🏼‍♀ : woman getting haircut: medium-light skin tone", +"💇🏽‍♀️ : woman getting haircut: medium skin tone", +"💇🏽‍♀ : woman getting haircut: medium skin tone", +"💇🏾‍♀️ : woman getting haircut: medium-dark skin tone", +"💇🏾‍♀ : woman getting haircut: medium-dark skin tone", +"💇🏿‍♀️ : woman getting haircut: dark skin tone", +"💇🏿‍♀ : woman getting haircut: dark skin tone", +"🚶 : person walking", +"🚶🏻 : person walking: light skin tone", +"🚶🏼 : person walking: medium-light skin tone", +"🚶🏽 : person walking: medium skin tone", +"🚶🏾 : person walking: medium-dark skin tone", +"🚶🏿 : person walking: dark skin tone", +"🚶‍♂️ : man walking", +"🚶‍♂ : man walking", +"🚶🏻‍♂️ : man walking: light skin tone", +"🚶🏻‍♂ : man walking: light skin tone", +"🚶🏼‍♂️ : man walking: medium-light skin tone", +"🚶🏼‍♂ : man walking: medium-light skin tone", +"🚶🏽‍♂️ : man walking: medium skin tone", +"🚶🏽‍♂ : man walking: medium skin tone", +"🚶🏾‍♂️ : man walking: medium-dark skin tone", +"🚶🏾‍♂ : man walking: medium-dark skin tone", +"🚶🏿‍♂️ : man walking: dark skin tone", +"🚶🏿‍♂ : man walking: dark skin tone", +"🚶‍♀️ : woman walking", +"🚶‍♀ : woman walking", +"🚶🏻‍♀️ : woman walking: light skin tone", +"🚶🏻‍♀ : woman walking: light skin tone", +"🚶🏼‍♀️ : woman walking: medium-light skin tone", +"🚶🏼‍♀ : woman walking: medium-light skin tone", +"🚶🏽‍♀️ : woman walking: medium skin tone", +"🚶🏽‍♀ : woman walking: medium skin tone", +"🚶🏾‍♀️ : woman walking: medium-dark skin tone", +"🚶🏾‍♀ : woman walking: medium-dark skin tone", +"🚶🏿‍♀️ : woman walking: dark skin tone", +"🚶🏿‍♀ : woman walking: dark skin tone", +"🏃 : person running", +"🏃🏻 : person running: light skin tone", +"🏃🏼 : person running: medium-light skin tone", +"🏃🏽 : person running: medium skin tone", +"🏃🏾 : person running: medium-dark skin tone", +"🏃🏿 : person running: dark skin tone", +"🏃‍♂️ : man running", +"🏃‍♂ : man running", +"🏃🏻‍♂️ : man running: light skin tone", +"🏃🏻‍♂ : man running: light skin tone", +"🏃🏼‍♂️ : man running: medium-light skin tone", +"🏃🏼‍♂ : man running: medium-light skin tone", +"🏃🏽‍♂️ : man running: medium skin tone", +"🏃🏽‍♂ : man running: medium skin tone", +"🏃🏾‍♂️ : man running: medium-dark skin tone", +"🏃🏾‍♂ : man running: medium-dark skin tone", +"🏃🏿‍♂️ : man running: dark skin tone", +"🏃🏿‍♂ : man running: dark skin tone", +"🏃‍♀️ : woman running", +"🏃‍♀ : woman running", +"🏃🏻‍♀️ : woman running: light skin tone", +"🏃🏻‍♀ : woman running: light skin tone", +"🏃🏼‍♀️ : woman running: medium-light skin tone", +"🏃🏼‍♀ : woman running: medium-light skin tone", +"🏃🏽‍♀️ : woman running: medium skin tone", +"🏃🏽‍♀ : woman running: medium skin tone", +"🏃🏾‍♀️ : woman running: medium-dark skin tone", +"🏃🏾‍♀ : woman running: medium-dark skin tone", +"🏃🏿‍♀️ : woman running: dark skin tone", +"🏃🏿‍♀ : woman running: dark skin tone", +"💃 : woman dancing", +"💃🏻 : woman dancing: light skin tone", +"💃🏼 : woman dancing: medium-light skin tone", +"💃🏽 : woman dancing: medium skin tone", +"💃🏾 : woman dancing: medium-dark skin tone", +"💃🏿 : woman dancing: dark skin tone", +"🕺 : man dancing", +"🕺🏻 : man dancing: light skin tone", +"🕺🏼 : man dancing: medium-light skin tone", +"🕺🏽 : man dancing: medium skin tone", +"🕺🏾 : man dancing: medium-dark skin tone", +"🕺🏿 : man dancing: dark skin tone", +"👯 : people with bunny ears", +"👯‍♂️ : men with bunny ears", +"👯‍♂ : men with bunny ears", +"👯‍♀️ : women with bunny ears", +"👯‍♀ : women with bunny ears", +"🧖 : person in steamy room", +"🧖🏻 : person in steamy room: light skin tone", +"🧖🏼 : person in steamy room: medium-light skin tone", +"🧖🏽 : person in steamy room: medium skin tone", +"🧖🏾 : person in steamy room: medium-dark skin tone", +"🧖🏿 : person in steamy room: dark skin tone", +"🧖‍♀️ : woman in steamy room", +"🧖‍♀ : woman in steamy room", +"🧖🏻‍♀️ : woman in steamy room: light skin tone", +"🧖🏻‍♀ : woman in steamy room: light skin tone", +"🧖🏼‍♀️ : woman in steamy room: medium-light skin tone", +"🧖🏼‍♀ : woman in steamy room: medium-light skin tone", +"🧖🏽‍♀️ : woman in steamy room: medium skin tone", +"🧖🏽‍♀ : woman in steamy room: medium skin tone", +"🧖🏾‍♀️ : woman in steamy room: medium-dark skin tone", +"🧖🏾‍♀ : woman in steamy room: medium-dark skin tone", +"🧖🏿‍♀️ : woman in steamy room: dark skin tone", +"🧖🏿‍♀ : woman in steamy room: dark skin tone", +"🧖‍♂️ : man in steamy room", +"🧖‍♂ : man in steamy room", +"🧖🏻‍♂️ : man in steamy room: light skin tone", +"🧖🏻‍♂ : man in steamy room: light skin tone", +"🧖🏼‍♂️ : man in steamy room: medium-light skin tone", +"🧖🏼‍♂ : man in steamy room: medium-light skin tone", +"🧖🏽‍♂️ : man in steamy room: medium skin tone", +"🧖🏽‍♂ : man in steamy room: medium skin tone", +"🧖🏾‍♂️ : man in steamy room: medium-dark skin tone", +"🧖🏾‍♂ : man in steamy room: medium-dark skin tone", +"🧖🏿‍♂️ : man in steamy room: dark skin tone", +"🧖🏿‍♂ : man in steamy room: dark skin tone", +"🧗 : person climbing", +"🧗🏻 : person climbing: light skin tone", +"🧗🏼 : person climbing: medium-light skin tone", +"🧗🏽 : person climbing: medium skin tone", +"🧗🏾 : person climbing: medium-dark skin tone", +"🧗🏿 : person climbing: dark skin tone", +"🧗‍♀️ : woman climbing", +"🧗‍♀ : woman climbing", +"🧗🏻‍♀️ : woman climbing: light skin tone", +"🧗🏻‍♀ : woman climbing: light skin tone", +"🧗🏼‍♀️ : woman climbing: medium-light skin tone", +"🧗🏼‍♀ : woman climbing: medium-light skin tone", +"🧗🏽‍♀️ : woman climbing: medium skin tone", +"🧗🏽‍♀ : woman climbing: medium skin tone", +"🧗🏾‍♀️ : woman climbing: medium-dark skin tone", +"🧗🏾‍♀ : woman climbing: medium-dark skin tone", +"🧗🏿‍♀️ : woman climbing: dark skin tone", +"🧗🏿‍♀ : woman climbing: dark skin tone", +"🧗‍♂️ : man climbing", +"🧗‍♂ : man climbing", +"🧗🏻‍♂️ : man climbing: light skin tone", +"🧗🏻‍♂ : man climbing: light skin tone", +"🧗🏼‍♂️ : man climbing: medium-light skin tone", +"🧗🏼‍♂ : man climbing: medium-light skin tone", +"🧗🏽‍♂️ : man climbing: medium skin tone", +"🧗🏽‍♂ : man climbing: medium skin tone", +"🧗🏾‍♂️ : man climbing: medium-dark skin tone", +"🧗🏾‍♂ : man climbing: medium-dark skin tone", +"🧗🏿‍♂️ : man climbing: dark skin tone", +"🧗🏿‍♂ : man climbing: dark skin tone", +"🧘 : person in lotus position", +"🧘🏻 : person in lotus position: light skin tone", +"🧘🏼 : person in lotus position: medium-light skin tone", +"🧘🏽 : person in lotus position: medium skin tone", +"🧘🏾 : person in lotus position: medium-dark skin tone", +"🧘🏿 : person in lotus position: dark skin tone", +"🧘‍♀️ : woman in lotus position", +"🧘‍♀ : woman in lotus position", +"🧘🏻‍♀️ : woman in lotus position: light skin tone", +"🧘🏻‍♀ : woman in lotus position: light skin tone", +"🧘🏼‍♀️ : woman in lotus position: medium-light skin tone", +"🧘🏼‍♀ : woman in lotus position: medium-light skin tone", +"🧘🏽‍♀️ : woman in lotus position: medium skin tone", +"🧘🏽‍♀ : woman in lotus position: medium skin tone", +"🧘🏾‍♀️ : woman in lotus position: medium-dark skin tone", +"🧘🏾‍♀ : woman in lotus position: medium-dark skin tone", +"🧘🏿‍♀️ : woman in lotus position: dark skin tone", +"🧘🏿‍♀ : woman in lotus position: dark skin tone", +"🧘‍♂️ : man in lotus position", +"🧘‍♂ : man in lotus position", +"🧘🏻‍♂️ : man in lotus position: light skin tone", +"🧘🏻‍♂ : man in lotus position: light skin tone", +"🧘🏼‍♂️ : man in lotus position: medium-light skin tone", +"🧘🏼‍♂ : man in lotus position: medium-light skin tone", +"🧘🏽‍♂️ : man in lotus position: medium skin tone", +"🧘🏽‍♂ : man in lotus position: medium skin tone", +"🧘🏾‍♂️ : man in lotus position: medium-dark skin tone", +"🧘🏾‍♂ : man in lotus position: medium-dark skin tone", +"🧘🏿‍♂️ : man in lotus position: dark skin tone", +"🧘🏿‍♂ : man in lotus position: dark skin tone", +"🛀 : person taking bath", +"🛀🏻 : person taking bath: light skin tone", +"🛀🏼 : person taking bath: medium-light skin tone", +"🛀🏽 : person taking bath: medium skin tone", +"🛀🏾 : person taking bath: medium-dark skin tone", +"🛀🏿 : person taking bath: dark skin tone", +"🛌 : person in bed", +"🛌🏻 : person in bed: light skin tone", +"🛌🏼 : person in bed: medium-light skin tone", +"🛌🏽 : person in bed: medium skin tone", +"🛌🏾 : person in bed: medium-dark skin tone", +"🛌🏿 : person in bed: dark skin tone", +"🕴️ : man in suit levitating", +"🕴 : man in suit levitating", +"🕴🏻 : man in suit levitating: light skin tone", +"🕴🏼 : man in suit levitating: medium-light skin tone", +"🕴🏽 : man in suit levitating: medium skin tone", +"🕴🏾 : man in suit levitating: medium-dark skin tone", +"🕴🏿 : man in suit levitating: dark skin tone", +"🗣️ : speaking head", +"🗣 : speaking head", +"👤 : bust in silhouette", +"👥 : busts in silhouette", +"🤺 : person fencing", +"🏇 : horse racing", +"🏇🏻 : horse racing: light skin tone", +"🏇🏼 : horse racing: medium-light skin tone", +"🏇🏽 : horse racing: medium skin tone", +"🏇🏾 : horse racing: medium-dark skin tone", +"🏇🏿 : horse racing: dark skin tone", +"⛷️ : skier", +"⛷ : skier", +"🏂 : snowboarder", +"🏂🏻 : snowboarder: light skin tone", +"🏂🏼 : snowboarder: medium-light skin tone", +"🏂🏽 : snowboarder: medium skin tone", +"🏂🏾 : snowboarder: medium-dark skin tone", +"🏂🏿 : snowboarder: dark skin tone", +"🏌️ : person golfing", +"🏌 : person golfing", +"🏌🏻 : person golfing: light skin tone", +"🏌🏼 : person golfing: medium-light skin tone", +"🏌🏽 : person golfing: medium skin tone", +"🏌🏾 : person golfing: medium-dark skin tone", +"🏌🏿 : person golfing: dark skin tone", +"🏌️‍♂️ : man golfing", +"🏌‍♂️ : man golfing", +"🏌️‍♂ : man golfing", +"🏌‍♂ : man golfing", +"🏌🏻‍♂️ : man golfing: light skin tone", +"🏌🏻‍♂ : man golfing: light skin tone", +"🏌🏼‍♂️ : man golfing: medium-light skin tone", +"🏌🏼‍♂ : man golfing: medium-light skin tone", +"🏌🏽‍♂️ : man golfing: medium skin tone", +"🏌🏽‍♂ : man golfing: medium skin tone", +"🏌🏾‍♂️ : man golfing: medium-dark skin tone", +"🏌🏾‍♂ : man golfing: medium-dark skin tone", +"🏌🏿‍♂️ : man golfing: dark skin tone", +"🏌🏿‍♂ : man golfing: dark skin tone", +"🏌️‍♀️ : woman golfing", +"🏌‍♀️ : woman golfing", +"🏌️‍♀ : woman golfing", +"🏌‍♀ : woman golfing", +"🏌🏻‍♀️ : woman golfing: light skin tone", +"🏌🏻‍♀ : woman golfing: light skin tone", +"🏌🏼‍♀️ : woman golfing: medium-light skin tone", +"🏌🏼‍♀ : woman golfing: medium-light skin tone", +"🏌🏽‍♀️ : woman golfing: medium skin tone", +"🏌🏽‍♀ : woman golfing: medium skin tone", +"🏌🏾‍♀️ : woman golfing: medium-dark skin tone", +"🏌🏾‍♀ : woman golfing: medium-dark skin tone", +"🏌🏿‍♀️ : woman golfing: dark skin tone", +"🏌🏿‍♀ : woman golfing: dark skin tone", +"🏄 : person surfing", +"🏄🏻 : person surfing: light skin tone", +"🏄🏼 : person surfing: medium-light skin tone", +"🏄🏽 : person surfing: medium skin tone", +"🏄🏾 : person surfing: medium-dark skin tone", +"🏄🏿 : person surfing: dark skin tone", +"🏄‍♂️ : man surfing", +"🏄‍♂ : man surfing", +"🏄🏻‍♂️ : man surfing: light skin tone", +"🏄🏻‍♂ : man surfing: light skin tone", +"🏄🏼‍♂️ : man surfing: medium-light skin tone", +"🏄🏼‍♂ : man surfing: medium-light skin tone", +"🏄🏽‍♂️ : man surfing: medium skin tone", +"🏄🏽‍♂ : man surfing: medium skin tone", +"🏄🏾‍♂️ : man surfing: medium-dark skin tone", +"🏄🏾‍♂ : man surfing: medium-dark skin tone", +"🏄🏿‍♂️ : man surfing: dark skin tone", +"🏄🏿‍♂ : man surfing: dark skin tone", +"🏄‍♀️ : woman surfing", +"🏄‍♀ : woman surfing", +"🏄🏻‍♀️ : woman surfing: light skin tone", +"🏄🏻‍♀ : woman surfing: light skin tone", +"🏄🏼‍♀️ : woman surfing: medium-light skin tone", +"🏄🏼‍♀ : woman surfing: medium-light skin tone", +"🏄🏽‍♀️ : woman surfing: medium skin tone", +"🏄🏽‍♀ : woman surfing: medium skin tone", +"🏄🏾‍♀️ : woman surfing: medium-dark skin tone", +"🏄🏾‍♀ : woman surfing: medium-dark skin tone", +"🏄🏿‍♀️ : woman surfing: dark skin tone", +"🏄🏿‍♀ : woman surfing: dark skin tone", +"🚣 : person rowing boat", +"🚣🏻 : person rowing boat: light skin tone", +"🚣🏼 : person rowing boat: medium-light skin tone", +"🚣🏽 : person rowing boat: medium skin tone", +"🚣🏾 : person rowing boat: medium-dark skin tone", +"🚣🏿 : person rowing boat: dark skin tone", +"🚣‍♂️ : man rowing boat", +"🚣‍♂ : man rowing boat", +"🚣🏻‍♂️ : man rowing boat: light skin tone", +"🚣🏻‍♂ : man rowing boat: light skin tone", +"🚣🏼‍♂️ : man rowing boat: medium-light skin tone", +"🚣🏼‍♂ : man rowing boat: medium-light skin tone", +"🚣🏽‍♂️ : man rowing boat: medium skin tone", +"🚣🏽‍♂ : man rowing boat: medium skin tone", +"🚣🏾‍♂️ : man rowing boat: medium-dark skin tone", +"🚣🏾‍♂ : man rowing boat: medium-dark skin tone", +"🚣🏿‍♂️ : man rowing boat: dark skin tone", +"🚣🏿‍♂ : man rowing boat: dark skin tone", +"🚣‍♀️ : woman rowing boat", +"🚣‍♀ : woman rowing boat", +"🚣🏻‍♀️ : woman rowing boat: light skin tone", +"🚣🏻‍♀ : woman rowing boat: light skin tone", +"🚣🏼‍♀️ : woman rowing boat: medium-light skin tone", +"🚣🏼‍♀ : woman rowing boat: medium-light skin tone", +"🚣🏽‍♀️ : woman rowing boat: medium skin tone", +"🚣🏽‍♀ : woman rowing boat: medium skin tone", +"🚣🏾‍♀️ : woman rowing boat: medium-dark skin tone", +"🚣🏾‍♀ : woman rowing boat: medium-dark skin tone", +"🚣🏿‍♀️ : woman rowing boat: dark skin tone", +"🚣🏿‍♀ : woman rowing boat: dark skin tone", +"🏊 : person swimming", +"🏊🏻 : person swimming: light skin tone", +"🏊🏼 : person swimming: medium-light skin tone", +"🏊🏽 : person swimming: medium skin tone", +"🏊🏾 : person swimming: medium-dark skin tone", +"🏊🏿 : person swimming: dark skin tone", +"🏊‍♂️ : man swimming", +"🏊‍♂ : man swimming", +"🏊🏻‍♂️ : man swimming: light skin tone", +"🏊🏻‍♂ : man swimming: light skin tone", +"🏊🏼‍♂️ : man swimming: medium-light skin tone", +"🏊🏼‍♂ : man swimming: medium-light skin tone", +"🏊🏽‍♂️ : man swimming: medium skin tone", +"🏊🏽‍♂ : man swimming: medium skin tone", +"🏊🏾‍♂️ : man swimming: medium-dark skin tone", +"🏊🏾‍♂ : man swimming: medium-dark skin tone", +"🏊🏿‍♂️ : man swimming: dark skin tone", +"🏊🏿‍♂ : man swimming: dark skin tone", +"🏊‍♀️ : woman swimming", +"🏊‍♀ : woman swimming", +"🏊🏻‍♀️ : woman swimming: light skin tone", +"🏊🏻‍♀ : woman swimming: light skin tone", +"🏊🏼‍♀️ : woman swimming: medium-light skin tone", +"🏊🏼‍♀ : woman swimming: medium-light skin tone", +"🏊🏽‍♀️ : woman swimming: medium skin tone", +"🏊🏽‍♀ : woman swimming: medium skin tone", +"🏊🏾‍♀️ : woman swimming: medium-dark skin tone", +"🏊🏾‍♀ : woman swimming: medium-dark skin tone", +"🏊🏿‍♀️ : woman swimming: dark skin tone", +"🏊🏿‍♀ : woman swimming: dark skin tone", +"⛹️ : person bouncing ball", +"⛹ : person bouncing ball", +"⛹🏻 : person bouncing ball: light skin tone", +"⛹🏼 : person bouncing ball: medium-light skin tone", +"⛹🏽 : person bouncing ball: medium skin tone", +"⛹🏾 : person bouncing ball: medium-dark skin tone", +"⛹🏿 : person bouncing ball: dark skin tone", +"⛹️‍♂️ : man bouncing ball", +"⛹‍♂️ : man bouncing ball", +"⛹️‍♂ : man bouncing ball", +"⛹‍♂ : man bouncing ball", +"⛹🏻‍♂️ : man bouncing ball: light skin tone", +"⛹🏻‍♂ : man bouncing ball: light skin tone", +"⛹🏼‍♂️ : man bouncing ball: medium-light skin tone", +"⛹🏼‍♂ : man bouncing ball: medium-light skin tone", +"⛹🏽‍♂️ : man bouncing ball: medium skin tone", +"⛹🏽‍♂ : man bouncing ball: medium skin tone", +"⛹🏾‍♂️ : man bouncing ball: medium-dark skin tone", +"⛹🏾‍♂ : man bouncing ball: medium-dark skin tone", +"⛹🏿‍♂️ : man bouncing ball: dark skin tone", +"⛹🏿‍♂ : man bouncing ball: dark skin tone", +"⛹️‍♀️ : woman bouncing ball", +"⛹‍♀️ : woman bouncing ball", +"⛹️‍♀ : woman bouncing ball", +"⛹‍♀ : woman bouncing ball", +"⛹🏻‍♀️ : woman bouncing ball: light skin tone", +"⛹🏻‍♀ : woman bouncing ball: light skin tone", +"⛹🏼‍♀️ : woman bouncing ball: medium-light skin tone", +"⛹🏼‍♀ : woman bouncing ball: medium-light skin tone", +"⛹🏽‍♀️ : woman bouncing ball: medium skin tone", +"⛹🏽‍♀ : woman bouncing ball: medium skin tone", +"⛹🏾‍♀️ : woman bouncing ball: medium-dark skin tone", +"⛹🏾‍♀ : woman bouncing ball: medium-dark skin tone", +"⛹🏿‍♀️ : woman bouncing ball: dark skin tone", +"⛹🏿‍♀ : woman bouncing ball: dark skin tone", +"🏋️ : person lifting weights", +"🏋 : person lifting weights", +"🏋🏻 : person lifting weights: light skin tone", +"🏋🏼 : person lifting weights: medium-light skin tone", +"🏋🏽 : person lifting weights: medium skin tone", +"🏋🏾 : person lifting weights: medium-dark skin tone", +"🏋🏿 : person lifting weights: dark skin tone", +"🏋️‍♂️ : man lifting weights", +"🏋‍♂️ : man lifting weights", +"🏋️‍♂ : man lifting weights", +"🏋‍♂ : man lifting weights", +"🏋🏻‍♂️ : man lifting weights: light skin tone", +"🏋🏻‍♂ : man lifting weights: light skin tone", +"🏋🏼‍♂️ : man lifting weights: medium-light skin tone", +"🏋🏼‍♂ : man lifting weights: medium-light skin tone", +"🏋🏽‍♂️ : man lifting weights: medium skin tone", +"🏋🏽‍♂ : man lifting weights: medium skin tone", +"🏋🏾‍♂️ : man lifting weights: medium-dark skin tone", +"🏋🏾‍♂ : man lifting weights: medium-dark skin tone", +"🏋🏿‍♂️ : man lifting weights: dark skin tone", +"🏋🏿‍♂ : man lifting weights: dark skin tone", +"🏋️‍♀️ : woman lifting weights", +"🏋‍♀️ : woman lifting weights", +"🏋️‍♀ : woman lifting weights", +"🏋‍♀ : woman lifting weights", +"🏋🏻‍♀️ : woman lifting weights: light skin tone", +"🏋🏻‍♀ : woman lifting weights: light skin tone", +"🏋🏼‍♀️ : woman lifting weights: medium-light skin tone", +"🏋🏼‍♀ : woman lifting weights: medium-light skin tone", +"🏋🏽‍♀️ : woman lifting weights: medium skin tone", +"🏋🏽‍♀ : woman lifting weights: medium skin tone", +"🏋🏾‍♀️ : woman lifting weights: medium-dark skin tone", +"🏋🏾‍♀ : woman lifting weights: medium-dark skin tone", +"🏋🏿‍♀️ : woman lifting weights: dark skin tone", +"🏋🏿‍♀ : woman lifting weights: dark skin tone", +"🚴 : person biking", +"🚴🏻 : person biking: light skin tone", +"🚴🏼 : person biking: medium-light skin tone", +"🚴🏽 : person biking: medium skin tone", +"🚴🏾 : person biking: medium-dark skin tone", +"🚴🏿 : person biking: dark skin tone", +"🚴‍♂️ : man biking", +"🚴‍♂ : man biking", +"🚴🏻‍♂️ : man biking: light skin tone", +"🚴🏻‍♂ : man biking: light skin tone", +"🚴🏼‍♂️ : man biking: medium-light skin tone", +"🚴🏼‍♂ : man biking: medium-light skin tone", +"🚴🏽‍♂️ : man biking: medium skin tone", +"🚴🏽‍♂ : man biking: medium skin tone", +"🚴🏾‍♂️ : man biking: medium-dark skin tone", +"🚴🏾‍♂ : man biking: medium-dark skin tone", +"🚴🏿‍♂️ : man biking: dark skin tone", +"🚴🏿‍♂ : man biking: dark skin tone", +"🚴‍♀️ : woman biking", +"🚴‍♀ : woman biking", +"🚴🏻‍♀️ : woman biking: light skin tone", +"🚴🏻‍♀ : woman biking: light skin tone", +"🚴🏼‍♀️ : woman biking: medium-light skin tone", +"🚴🏼‍♀ : woman biking: medium-light skin tone", +"🚴🏽‍♀️ : woman biking: medium skin tone", +"🚴🏽‍♀ : woman biking: medium skin tone", +"🚴🏾‍♀️ : woman biking: medium-dark skin tone", +"🚴🏾‍♀ : woman biking: medium-dark skin tone", +"🚴🏿‍♀️ : woman biking: dark skin tone", +"🚴🏿‍♀ : woman biking: dark skin tone", +"🚵 : person mountain biking", +"🚵🏻 : person mountain biking: light skin tone", +"🚵🏼 : person mountain biking: medium-light skin tone", +"🚵🏽 : person mountain biking: medium skin tone", +"🚵🏾 : person mountain biking: medium-dark skin tone", +"🚵🏿 : person mountain biking: dark skin tone", +"🚵‍♂️ : man mountain biking", +"🚵‍♂ : man mountain biking", +"🚵🏻‍♂️ : man mountain biking: light skin tone", +"🚵🏻‍♂ : man mountain biking: light skin tone", +"🚵🏼‍♂️ : man mountain biking: medium-light skin tone", +"🚵🏼‍♂ : man mountain biking: medium-light skin tone", +"🚵🏽‍♂️ : man mountain biking: medium skin tone", +"🚵🏽‍♂ : man mountain biking: medium skin tone", +"🚵🏾‍♂️ : man mountain biking: medium-dark skin tone", +"🚵🏾‍♂ : man mountain biking: medium-dark skin tone", +"🚵🏿‍♂️ : man mountain biking: dark skin tone", +"🚵🏿‍♂ : man mountain biking: dark skin tone", +"🚵‍♀️ : woman mountain biking", +"🚵‍♀ : woman mountain biking", +"🚵🏻‍♀️ : woman mountain biking: light skin tone", +"🚵🏻‍♀ : woman mountain biking: light skin tone", +"🚵🏼‍♀️ : woman mountain biking: medium-light skin tone", +"🚵🏼‍♀ : woman mountain biking: medium-light skin tone", +"🚵🏽‍♀️ : woman mountain biking: medium skin tone", +"🚵🏽‍♀ : woman mountain biking: medium skin tone", +"🚵🏾‍♀️ : woman mountain biking: medium-dark skin tone", +"🚵🏾‍♀ : woman mountain biking: medium-dark skin tone", +"🚵🏿‍♀️ : woman mountain biking: dark skin tone", +"🚵🏿‍♀ : woman mountain biking: dark skin tone", +"🏎️ : racing car", +"🏎 : racing car", +"🏍️ : motorcycle", +"🏍 : motorcycle", +"🤸 : person cartwheeling", +"🤸🏻 : person cartwheeling: light skin tone", +"🤸🏼 : person cartwheeling: medium-light skin tone", +"🤸🏽 : person cartwheeling: medium skin tone", +"🤸🏾 : person cartwheeling: medium-dark skin tone", +"🤸🏿 : person cartwheeling: dark skin tone", +"🤸‍♂️ : man cartwheeling", +"🤸‍♂ : man cartwheeling", +"🤸🏻‍♂️ : man cartwheeling: light skin tone", +"🤸🏻‍♂ : man cartwheeling: light skin tone", +"🤸🏼‍♂️ : man cartwheeling: medium-light skin tone", +"🤸🏼‍♂ : man cartwheeling: medium-light skin tone", +"🤸🏽‍♂️ : man cartwheeling: medium skin tone", +"🤸🏽‍♂ : man cartwheeling: medium skin tone", +"🤸🏾‍♂️ : man cartwheeling: medium-dark skin tone", +"🤸🏾‍♂ : man cartwheeling: medium-dark skin tone", +"🤸🏿‍♂️ : man cartwheeling: dark skin tone", +"🤸🏿‍♂ : man cartwheeling: dark skin tone", +"🤸‍♀️ : woman cartwheeling", +"🤸‍♀ : woman cartwheeling", +"🤸🏻‍♀️ : woman cartwheeling: light skin tone", +"🤸🏻‍♀ : woman cartwheeling: light skin tone", +"🤸🏼‍♀️ : woman cartwheeling: medium-light skin tone", +"🤸🏼‍♀ : woman cartwheeling: medium-light skin tone", +"🤸🏽‍♀️ : woman cartwheeling: medium skin tone", +"🤸🏽‍♀ : woman cartwheeling: medium skin tone", +"🤸🏾‍♀️ : woman cartwheeling: medium-dark skin tone", +"🤸🏾‍♀ : woman cartwheeling: medium-dark skin tone", +"🤸🏿‍♀️ : woman cartwheeling: dark skin tone", +"🤸🏿‍♀ : woman cartwheeling: dark skin tone", +"🤼 : people wrestling", +"🤼‍♂️ : men wrestling", +"🤼‍♂ : men wrestling", +"🤼‍♀️ : women wrestling", +"🤼‍♀ : women wrestling", +"🤽 : person playing water polo", +"🤽🏻 : person playing water polo: light skin tone", +"🤽🏼 : person playing water polo: medium-light skin tone", +"🤽🏽 : person playing water polo: medium skin tone", +"🤽🏾 : person playing water polo: medium-dark skin tone", +"🤽🏿 : person playing water polo: dark skin tone", +"🤽‍♂️ : man playing water polo", +"🤽‍♂ : man playing water polo", +"🤽🏻‍♂️ : man playing water polo: light skin tone", +"🤽🏻‍♂ : man playing water polo: light skin tone", +"🤽🏼‍♂️ : man playing water polo: medium-light skin tone", +"🤽🏼‍♂ : man playing water polo: medium-light skin tone", +"🤽🏽‍♂️ : man playing water polo: medium skin tone", +"🤽🏽‍♂ : man playing water polo: medium skin tone", +"🤽🏾‍♂️ : man playing water polo: medium-dark skin tone", +"🤽🏾‍♂ : man playing water polo: medium-dark skin tone", +"🤽🏿‍♂️ : man playing water polo: dark skin tone", +"🤽🏿‍♂ : man playing water polo: dark skin tone", +"🤽‍♀️ : woman playing water polo", +"🤽‍♀ : woman playing water polo", +"🤽🏻‍♀️ : woman playing water polo: light skin tone", +"🤽🏻‍♀ : woman playing water polo: light skin tone", +"🤽🏼‍♀️ : woman playing water polo: medium-light skin tone", +"🤽🏼‍♀ : woman playing water polo: medium-light skin tone", +"🤽🏽‍♀️ : woman playing water polo: medium skin tone", +"🤽🏽‍♀ : woman playing water polo: medium skin tone", +"🤽🏾‍♀️ : woman playing water polo: medium-dark skin tone", +"🤽🏾‍♀ : woman playing water polo: medium-dark skin tone", +"🤽🏿‍♀️ : woman playing water polo: dark skin tone", +"🤽🏿‍♀ : woman playing water polo: dark skin tone", +"🤾 : person playing handball", +"🤾🏻 : person playing handball: light skin tone", +"🤾🏼 : person playing handball: medium-light skin tone", +"🤾🏽 : person playing handball: medium skin tone", +"🤾🏾 : person playing handball: medium-dark skin tone", +"🤾🏿 : person playing handball: dark skin tone", +"🤾‍♂️ : man playing handball", +"🤾‍♂ : man playing handball", +"🤾🏻‍♂️ : man playing handball: light skin tone", +"🤾🏻‍♂ : man playing handball: light skin tone", +"🤾🏼‍♂️ : man playing handball: medium-light skin tone", +"🤾🏼‍♂ : man playing handball: medium-light skin tone", +"🤾🏽‍♂️ : man playing handball: medium skin tone", +"🤾🏽‍♂ : man playing handball: medium skin tone", +"🤾🏾‍♂️ : man playing handball: medium-dark skin tone", +"🤾🏾‍♂ : man playing handball: medium-dark skin tone", +"🤾🏿‍♂️ : man playing handball: dark skin tone", +"🤾🏿‍♂ : man playing handball: dark skin tone", +"🤾‍♀️ : woman playing handball", +"🤾‍♀ : woman playing handball", +"🤾🏻‍♀️ : woman playing handball: light skin tone", +"🤾🏻‍♀ : woman playing handball: light skin tone", +"🤾🏼‍♀️ : woman playing handball: medium-light skin tone", +"🤾🏼‍♀ : woman playing handball: medium-light skin tone", +"🤾🏽‍♀️ : woman playing handball: medium skin tone", +"🤾🏽‍♀ : woman playing handball: medium skin tone", +"🤾🏾‍♀️ : woman playing handball: medium-dark skin tone", +"🤾🏾‍♀ : woman playing handball: medium-dark skin tone", +"🤾🏿‍♀️ : woman playing handball: dark skin tone", +"🤾🏿‍♀ : woman playing handball: dark skin tone", +"🤹 : person juggling", +"🤹🏻 : person juggling: light skin tone", +"🤹🏼 : person juggling: medium-light skin tone", +"🤹🏽 : person juggling: medium skin tone", +"🤹🏾 : person juggling: medium-dark skin tone", +"🤹🏿 : person juggling: dark skin tone", +"🤹‍♂️ : man juggling", +"🤹‍♂ : man juggling", +"🤹🏻‍♂️ : man juggling: light skin tone", +"🤹🏻‍♂ : man juggling: light skin tone", +"🤹🏼‍♂️ : man juggling: medium-light skin tone", +"🤹🏼‍♂ : man juggling: medium-light skin tone", +"🤹🏽‍♂️ : man juggling: medium skin tone", +"🤹🏽‍♂ : man juggling: medium skin tone", +"🤹🏾‍♂️ : man juggling: medium-dark skin tone", +"🤹🏾‍♂ : man juggling: medium-dark skin tone", +"🤹🏿‍♂️ : man juggling: dark skin tone", +"🤹🏿‍♂ : man juggling: dark skin tone", +"🤹‍♀️ : woman juggling", +"🤹‍♀ : woman juggling", +"🤹🏻‍♀️ : woman juggling: light skin tone", +"🤹🏻‍♀ : woman juggling: light skin tone", +"🤹🏼‍♀️ : woman juggling: medium-light skin tone", +"🤹🏼‍♀ : woman juggling: medium-light skin tone", +"🤹🏽‍♀️ : woman juggling: medium skin tone", +"🤹🏽‍♀ : woman juggling: medium skin tone", +"🤹🏾‍♀️ : woman juggling: medium-dark skin tone", +"🤹🏾‍♀ : woman juggling: medium-dark skin tone", +"🤹🏿‍♀️ : woman juggling: dark skin tone", +"🤹🏿‍♀ : woman juggling: dark skin tone", +"👫 : man and woman holding hands", +"👬 : two men holding hands", +"👭 : two women holding hands", +"💏 : kiss", +"👩‍❤️‍💋‍👨 : kiss: woman, man", +"👩‍❤‍💋‍👨 : kiss: woman, man", +"👨‍❤️‍💋‍👨 : kiss: man, man", +"👨‍❤‍💋‍👨 : kiss: man, man", +"👩‍❤️‍💋‍👩 : kiss: woman, woman", +"👩‍❤‍💋‍👩 : kiss: woman, woman", +"💑 : couple with heart", +"👩‍❤️‍👨 : couple with heart: woman, man", +"👩‍❤‍👨 : couple with heart: woman, man", +"👨‍❤️‍👨 : couple with heart: man, man", +"👨‍❤‍👨 : couple with heart: man, man", +"👩‍❤️‍👩 : couple with heart: woman, woman", +"👩‍❤‍👩 : couple with heart: woman, woman", +"👪 : family", +"👨‍👩‍👦 : family: man, woman, boy", +"👨‍👩‍👧 : family: man, woman, girl", +"👨‍👩‍👧‍👦 : family: man, woman, girl, boy", +"👨‍👩‍👦‍👦 : family: man, woman, boy, boy", +"👨‍👩‍👧‍👧 : family: man, woman, girl, girl", +"👨‍👨‍👦 : family: man, man, boy", +"👨‍👨‍👧 : family: man, man, girl", +"👨‍👨‍👧‍👦 : family: man, man, girl, boy", +"👨‍👨‍👦‍👦 : family: man, man, boy, boy", +"👨‍👨‍👧‍👧 : family: man, man, girl, girl", +"👩‍👩‍👦 : family: woman, woman, boy", +"👩‍👩‍👧 : family: woman, woman, girl", +"👩‍👩‍👧‍👦 : family: woman, woman, girl, boy", +"👩‍👩‍👦‍👦 : family: woman, woman, boy, boy", +"👩‍👩‍👧‍👧 : family: woman, woman, girl, girl", +"👨‍👦 : family: man, boy", +"👨‍👦‍👦 : family: man, boy, boy", +"👨‍👧 : family: man, girl", +"👨‍👧‍👦 : family: man, girl, boy", +"👨‍👧‍👧 : family: man, girl, girl", +"👩‍👦 : family: woman, boy", +"👩‍👦‍👦 : family: woman, boy, boy", +"👩‍👧 : family: woman, girl", +"👩‍👧‍👦 : family: woman, girl, boy", +"👩‍👧‍👧 : family: woman, girl, girl", +"🤳 : selfie", +"🤳🏻 : selfie: light skin tone", +"🤳🏼 : selfie: medium-light skin tone", +"🤳🏽 : selfie: medium skin tone", +"🤳🏾 : selfie: medium-dark skin tone", +"🤳🏿 : selfie: dark skin tone", +"💪 : flexed biceps", +"💪🏻 : flexed biceps: light skin tone", +"💪🏼 : flexed biceps: medium-light skin tone", +"💪🏽 : flexed biceps: medium skin tone", +"💪🏾 : flexed biceps: medium-dark skin tone", +"💪🏿 : flexed biceps: dark skin tone", +"🦵 : leg", +"🦵🏻 : leg: light skin tone", +"🦵🏼 : leg: medium-light skin tone", +"🦵🏽 : leg: medium skin tone", +"🦵🏾 : leg: medium-dark skin tone", +"🦵🏿 : leg: dark skin tone", +"🦶 : foot", +"🦶🏻 : foot: light skin tone", +"🦶🏼 : foot: medium-light skin tone", +"🦶🏽 : foot: medium skin tone", +"🦶🏾 : foot: medium-dark skin tone", +"🦶🏿 : foot: dark skin tone", +"👈 : backhand index pointing left", +"👈🏻 : backhand index pointing left: light skin tone", +"👈🏼 : backhand index pointing left: medium-light skin tone", +"👈🏽 : backhand index pointing left: medium skin tone", +"👈🏾 : backhand index pointing left: medium-dark skin tone", +"👈🏿 : backhand index pointing left: dark skin tone", +"👉 : backhand index pointing right", +"👉🏻 : backhand index pointing right: light skin tone", +"👉🏼 : backhand index pointing right: medium-light skin tone", +"👉🏽 : backhand index pointing right: medium skin tone", +"👉🏾 : backhand index pointing right: medium-dark skin tone", +"👉🏿 : backhand index pointing right: dark skin tone", +"☝️ : index pointing up", +"☝ : index pointing up", +"☝🏻 : index pointing up: light skin tone", +"☝🏼 : index pointing up: medium-light skin tone", +"☝🏽 : index pointing up: medium skin tone", +"☝🏾 : index pointing up: medium-dark skin tone", +"☝🏿 : index pointing up: dark skin tone", +"👆 : backhand index pointing up", +"👆🏻 : backhand index pointing up: light skin tone", +"👆🏼 : backhand index pointing up: medium-light skin tone", +"👆🏽 : backhand index pointing up: medium skin tone", +"👆🏾 : backhand index pointing up: medium-dark skin tone", +"👆🏿 : backhand index pointing up: dark skin tone", +"🖕 : middle finger", +"🖕🏻 : middle finger: light skin tone", +"🖕🏼 : middle finger: medium-light skin tone", +"🖕🏽 : middle finger: medium skin tone", +"🖕🏾 : middle finger: medium-dark skin tone", +"🖕🏿 : middle finger: dark skin tone", +"👇 : backhand index pointing down", +"👇🏻 : backhand index pointing down: light skin tone", +"👇🏼 : backhand index pointing down: medium-light skin tone", +"👇🏽 : backhand index pointing down: medium skin tone", +"👇🏾 : backhand index pointing down: medium-dark skin tone", +"👇🏿 : backhand index pointing down: dark skin tone", +"✌️ : victory hand", +"✌ : victory hand", +"✌🏻 : victory hand: light skin tone", +"✌🏼 : victory hand: medium-light skin tone", +"✌🏽 : victory hand: medium skin tone", +"✌🏾 : victory hand: medium-dark skin tone", +"✌🏿 : victory hand: dark skin tone", +"🤞 : crossed fingers", +"🤞🏻 : crossed fingers: light skin tone", +"🤞🏼 : crossed fingers: medium-light skin tone", +"🤞🏽 : crossed fingers: medium skin tone", +"🤞🏾 : crossed fingers: medium-dark skin tone", +"🤞🏿 : crossed fingers: dark skin tone", +"🖖 : vulcan salute", +"🖖🏻 : vulcan salute: light skin tone", +"🖖🏼 : vulcan salute: medium-light skin tone", +"🖖🏽 : vulcan salute: medium skin tone", +"🖖🏾 : vulcan salute: medium-dark skin tone", +"🖖🏿 : vulcan salute: dark skin tone", +"🤘 : sign of the horns", +"🤘🏻 : sign of the horns: light skin tone", +"🤘🏼 : sign of the horns: medium-light skin tone", +"🤘🏽 : sign of the horns: medium skin tone", +"🤘🏾 : sign of the horns: medium-dark skin tone", +"🤘🏿 : sign of the horns: dark skin tone", +"🤙 : call me hand", +"🤙🏻 : call me hand: light skin tone", +"🤙🏼 : call me hand: medium-light skin tone", +"🤙🏽 : call me hand: medium skin tone", +"🤙🏾 : call me hand: medium-dark skin tone", +"🤙🏿 : call me hand: dark skin tone", +"🖐️ : hand with fingers splayed", +"🖐 : hand with fingers splayed", +"🖐🏻 : hand with fingers splayed: light skin tone", +"🖐🏼 : hand with fingers splayed: medium-light skin tone", +"🖐🏽 : hand with fingers splayed: medium skin tone", +"🖐🏾 : hand with fingers splayed: medium-dark skin tone", +"🖐🏿 : hand with fingers splayed: dark skin tone", +"✋ : raised hand", +"✋🏻 : raised hand: light skin tone", +"✋🏼 : raised hand: medium-light skin tone", +"✋🏽 : raised hand: medium skin tone", +"✋🏾 : raised hand: medium-dark skin tone", +"✋🏿 : raised hand: dark skin tone", +"👌 : ok hand", +"👌🏻 : ok hand: light skin tone", +"👌🏼 : ok hand: medium-light skin tone", +"👌🏽 : ok hand: medium skin tone", +"👌🏾 : ok hand: medium-dark skin tone", +"👌🏿 : ok hand: dark skin tone", +"👍 : thumbs up", +"👍🏻 : thumbs up: light skin tone", +"👍🏼 : thumbs up: medium-light skin tone", +"👍🏽 : thumbs up: medium skin tone", +"👍🏾 : thumbs up: medium-dark skin tone", +"👍🏿 : thumbs up: dark skin tone", +"👎 : thumbs down", +"👎🏻 : thumbs down: light skin tone", +"👎🏼 : thumbs down: medium-light skin tone", +"👎🏽 : thumbs down: medium skin tone", +"👎🏾 : thumbs down: medium-dark skin tone", +"👎🏿 : thumbs down: dark skin tone", +"✊ : raised fist", +"✊🏻 : raised fist: light skin tone", +"✊🏼 : raised fist: medium-light skin tone", +"✊🏽 : raised fist: medium skin tone", +"✊🏾 : raised fist: medium-dark skin tone", +"✊🏿 : raised fist: dark skin tone", +"👊 : oncoming fist", +"👊🏻 : oncoming fist: light skin tone", +"👊🏼 : oncoming fist: medium-light skin tone", +"👊🏽 : oncoming fist: medium skin tone", +"👊🏾 : oncoming fist: medium-dark skin tone", +"👊🏿 : oncoming fist: dark skin tone", +"🤛 : left-facing fist", +"🤛🏻 : left-facing fist: light skin tone", +"🤛🏼 : left-facing fist: medium-light skin tone", +"🤛🏽 : left-facing fist: medium skin tone", +"🤛🏾 : left-facing fist: medium-dark skin tone", +"🤛🏿 : left-facing fist: dark skin tone", +"🤜 : right-facing fist", +"🤜🏻 : right-facing fist: light skin tone", +"🤜🏼 : right-facing fist: medium-light skin tone", +"🤜🏽 : right-facing fist: medium skin tone", +"🤜🏾 : right-facing fist: medium-dark skin tone", +"🤜🏿 : right-facing fist: dark skin tone", +"🤚 : raised back of hand", +"🤚🏻 : raised back of hand: light skin tone", +"🤚🏼 : raised back of hand: medium-light skin tone", +"🤚🏽 : raised back of hand: medium skin tone", +"🤚🏾 : raised back of hand: medium-dark skin tone", +"🤚🏿 : raised back of hand: dark skin tone", +"👋 : waving hand", +"👋🏻 : waving hand: light skin tone", +"👋🏼 : waving hand: medium-light skin tone", +"👋🏽 : waving hand: medium skin tone", +"👋🏾 : waving hand: medium-dark skin tone", +"👋🏿 : waving hand: dark skin tone", +"🤟 : love-you gesture", +"🤟🏻 : love-you gesture: light skin tone", +"🤟🏼 : love-you gesture: medium-light skin tone", +"🤟🏽 : love-you gesture: medium skin tone", +"🤟🏾 : love-you gesture: medium-dark skin tone", +"🤟🏿 : love-you gesture: dark skin tone", +"✍️ : writing hand", +"✍ : writing hand", +"✍🏻 : writing hand: light skin tone", +"✍🏼 : writing hand: medium-light skin tone", +"✍🏽 : writing hand: medium skin tone", +"✍🏾 : writing hand: medium-dark skin tone", +"✍🏿 : writing hand: dark skin tone", +"👏 : clapping hands", +"👏🏻 : clapping hands: light skin tone", +"👏🏼 : clapping hands: medium-light skin tone", +"👏🏽 : clapping hands: medium skin tone", +"👏🏾 : clapping hands: medium-dark skin tone", +"👏🏿 : clapping hands: dark skin tone", +"👐 : open hands", +"👐🏻 : open hands: light skin tone", +"👐🏼 : open hands: medium-light skin tone", +"👐🏽 : open hands: medium skin tone", +"👐🏾 : open hands: medium-dark skin tone", +"👐🏿 : open hands: dark skin tone", +"🙌 : raising hands", +"🙌🏻 : raising hands: light skin tone", +"🙌🏼 : raising hands: medium-light skin tone", +"🙌🏽 : raising hands: medium skin tone", +"🙌🏾 : raising hands: medium-dark skin tone", +"🙌🏿 : raising hands: dark skin tone", +"🤲 : palms up together", +"🤲🏻 : palms up together: light skin tone", +"🤲🏼 : palms up together: medium-light skin tone", +"🤲🏽 : palms up together: medium skin tone", +"🤲🏾 : palms up together: medium-dark skin tone", +"🤲🏿 : palms up together: dark skin tone", +"🙏 : folded hands", +"🙏🏻 : folded hands: light skin tone", +"🙏🏼 : folded hands: medium-light skin tone", +"🙏🏽 : folded hands: medium skin tone", +"🙏🏾 : folded hands: medium-dark skin tone", +"🙏🏿 : folded hands: dark skin tone", +"🤝 : handshake", +"💅 : nail polish", +"💅🏻 : nail polish: light skin tone", +"💅🏼 : nail polish: medium-light skin tone", +"💅🏽 : nail polish: medium skin tone", +"💅🏾 : nail polish: medium-dark skin tone", +"💅🏿 : nail polish: dark skin tone", +"👂 : ear", +"👂🏻 : ear: light skin tone", +"👂🏼 : ear: medium-light skin tone", +"👂🏽 : ear: medium skin tone", +"👂🏾 : ear: medium-dark skin tone", +"👂🏿 : ear: dark skin tone", +"👃 : nose", +"👃🏻 : nose: light skin tone", +"👃🏼 : nose: medium-light skin tone", +"👃🏽 : nose: medium skin tone", +"👃🏾 : nose: medium-dark skin tone", +"👃🏿 : nose: dark skin tone", +"🦰 : red-haired", +"🦱 : curly-haired", +"🦲 : bald", +"🦳 : white-haired", +"👣 : footprints", +"👀 : eyes", +"👁️ : eye", +"👁 : eye", +"👁️‍🗨️ : eye in speech bubble", +"👁‍🗨️ : eye in speech bubble", +"👁️‍🗨 : eye in speech bubble", +"👁‍🗨 : eye in speech bubble", +"🧠 : brain", +"🦴 : bone", +"🦷 : tooth", +"👅 : tongue", +"👄 : mouth", +"💋 : kiss mark", +"💘 : heart with arrow", +"❤️ : red heart", +"❤ : red heart", +"💓 : beating heart", +"💔 : broken heart", +"💕 : two hearts", +"💖 : sparkling heart", +"💗 : growing heart", +"💙 : blue heart", +"💚 : green heart", +"💛 : yellow heart", +"🧡 : orange heart", +"💜 : purple heart", +"🖤 : black heart", +"💝 : heart with ribbon", +"💞 : revolving hearts", +"💟 : heart decoration", +"❣️ : heavy heart exclamation", +"❣ : heavy heart exclamation", +"💌 : love letter", +"💤 : zzz", +"💢 : anger symbol", +"💣 : bomb", +"💥 : collision", +"💦 : sweat droplets", +"💨 : dashing away", +"💫 : dizzy", +"💬 : speech balloon", +"🗨️ : left speech bubble", +"🗨 : left speech bubble", +"🗯️ : right anger bubble", +"🗯 : right anger bubble", +"💭 : thought balloon", +"🕳️ : hole", +"🕳 : hole", +"👓 : glasses", +"🕶️ : sunglasses", +"🕶 : sunglasses", +"🥽 : goggles", +"🥼 : lab coat", +"👔 : necktie", +"👕 : t-shirt", +"👖 : jeans", +"🧣 : scarf", +"🧤 : gloves", +"🧥 : coat", +"🧦 : socks", +"👗 : dress", +"👘 : kimono", +"👙 : bikini", +"👚 : woman’s clothes", +"👛 : purse", +"👜 : handbag", +"👝 : clutch bag", +"🛍️ : shopping bags", +"🛍 : shopping bags", +"🎒 : school backpack", +"👞 : man’s shoe", +"👟 : running shoe", +"🥾 : hiking boot", +"🥿 : woman’s flat shoe", +"👠 : high-heeled shoe", +"👡 : woman’s sandal", +"👢 : woman’s boot", +"👑 : crown", +"👒 : woman’s hat", +"🎩 : top hat", +"🎓 : graduation cap", +"🧢 : billed cap", +"⛑️ : rescue worker’s helmet", +"⛑ : rescue worker’s helmet", +"📿 : prayer beads", +"💄 : lipstick", +"💍 : ring", +"💎 : gem stone", +"🐵 : monkey face", +"🐒 : monkey", +"🦍 : gorilla", +"🐶 : dog face", +"🐕 : dog", +"🐩 : poodle", +"🐺 : wolf face", +"🦊 : fox face", +"🦝 : raccoon", +"🐱 : cat face", +"🐈 : cat", +"🦁 : lion face", +"🐯 : tiger face", +"🐅 : tiger", +"🐆 : leopard", +"🐴 : horse face", +"🐎 : horse", +"🦄 : unicorn face", +"🦓 : zebra", +"🦌 : deer", +"🐮 : cow face", +"🐂 : ox", +"🐃 : water buffalo", +"🐄 : cow", +"🐷 : pig face", +"🐖 : pig", +"🐗 : boar", +"🐽 : pig nose", +"🐏 : ram", +"🐑 : ewe", +"🐐 : goat", +"🐪 : camel", +"🐫 : two-hump camel", +"🦙 : llama", +"🦒 : giraffe", +"🐘 : elephant", +"🦏 : rhinoceros", +"🦛 : hippopotamus", +"🐭 : mouse face", +"🐁 : mouse", +"🐀 : rat", +"🐹 : hamster face", +"🐰 : rabbit face", +"🐇 : rabbit", +"🐿️ : chipmunk", +"🐿 : chipmunk", +"🦔 : hedgehog", +"🦇 : bat", +"🐻 : bear face", +"🐨 : koala", +"🐼 : panda face", +"🦘 : kangaroo", +"🦡 : badger", +"🐾 : paw prints", +"🦃 : turkey", +"🐔 : chicken", +"🐓 : rooster", +"🐣 : hatching chick", +"🐤 : baby chick", +"🐥 : front-facing baby chick", +"🐦 : bird", +"🐧 : penguin", +"🕊️ : dove", +"🕊 : dove", +"🦅 : eagle", +"🦆 : duck", +"🦢 : swan", +"🦉 : owl", +"🦚 : peacock", +"🦜 : parrot", +"🐸 : frog face", +"🐊 : crocodile", +"🐢 : turtle", +"🦎 : lizard", +"🐍 : snake", +"🐲 : dragon face", +"🐉 : dragon", +"🦕 : sauropod", +"🦖 : t-rex", +"🐳 : spouting whale", +"🐋 : whale", +"🐬 : dolphin", +"🐟 : fish", +"🐠 : tropical fish", +"🐡 : blowfish", +"🦈 : shark", +"🐙 : octopus", +"🐚 : spiral shell", +"🦀 : crab", +"🦞 : lobster", +"🦐 : shrimp", +"🦑 : squid", +"🐌 : snail", +"🦋 : butterfly", +"🐛 : bug", +"🐜 : ant", +"🐝 : honeybee", +"🐞 : lady beetle", +"🦗 : cricket", +"🕷️ : spider", +"🕷 : spider", +"🕸️ : spider web", +"🕸 : spider web", +"🦂 : scorpion", +"🦟 : mosquito", +"🦠 : microbe", +"💐 : bouquet", +"🌸 : cherry blossom", +"💮 : white flower", +"🏵️ : rosette", +"🏵 : rosette", +"🌹 : rose", +"🥀 : wilted flower", +"🌺 : hibiscus", +"🌻 : sunflower", +"🌼 : blossom", +"🌷 : tulip", +"🌱 : seedling", +"🌲 : evergreen tree", +"🌳 : deciduous tree", +"🌴 : palm tree", +"🌵 : cactus", +"🌾 : sheaf of rice", +"🌿 : herb", +"☘️ : shamrock", +"☘ : shamrock", +"🍀 : four leaf clover", +"🍁 : maple leaf", +"🍂 : fallen leaf", +"🍃 : leaf fluttering in wind", +"🍇 : grapes", +"🍈 : melon", +"🍉 : watermelon", +"🍊 : tangerine", +"🍋 : lemon", +"🍌 : banana", +"🍍 : pineapple", +"🥭 : mango", +"🍎 : red apple", +"🍏 : green apple", +"🍐 : pear", +"🍑 : peach", +"🍒 : cherries", +"🍓 : strawberry", +"🥝 : kiwi fruit", +"🍅 : tomato", +"🥥 : coconut", +"🥑 : avocado", +"🍆 : eggplant", +"🥔 : potato", +"🥕 : carrot", +"🌽 : ear of corn", +"🌶️ : hot pepper", +"🌶 : hot pepper", +"🥒 : cucumber", +"🥬 : leafy green", +"🥦 : broccoli", +"🍄 : mushroom", +"🥜 : peanuts", +"🌰 : chestnut", +"🍞 : bread", +"🥐 : croissant", +"🥖 : baguette bread", +"🥨 : pretzel", +"🥯 : bagel", +"🥞 : pancakes", +"🧀 : cheese wedge", +"🍖 : meat on bone", +"🍗 : poultry leg", +"🥩 : cut of meat", +"🥓 : bacon", +"🍔 : hamburger", +"🍟 : french fries", +"🍕 : pizza", +"🌭 : hot dog", +"🥪 : sandwich", +"🌮 : taco", +"🌯 : burrito", +"🥙 : stuffed flatbread", +"🥚 : egg", +"🍳 : cooking", +"🥘 : shallow pan of food", +"🍲 : pot of food", +"🥣 : bowl with spoon", +"🥗 : green salad", +"🍿 : popcorn", +"🧂 : salt", +"🥫 : canned food", +"🍱 : bento box", +"🍘 : rice cracker", +"🍙 : rice ball", +"🍚 : cooked rice", +"🍛 : curry rice", +"🍜 : steaming bowl", +"🍝 : spaghetti", +"🍠 : roasted sweet potato", +"🍢 : oden", +"🍣 : sushi", +"🍤 : fried shrimp", +"🍥 : fish cake with swirl", +"🥮 : moon cake", +"🍡 : dango", +"🥟 : dumpling", +"🥠 : fortune cookie", +"🥡 : takeout box", +"🍦 : soft ice cream", +"🍧 : shaved ice", +"🍨 : ice cream", +"🍩 : doughnut", +"🍪 : cookie", +"🎂 : birthday cake", +"🍰 : shortcake", +"🧁 : cupcake", +"🥧 : pie", +"🍫 : chocolate bar", +"🍬 : candy", +"🍭 : lollipop", +"🍮 : custard", +"🍯 : honey pot", +"🍼 : baby bottle", +"🥛 : glass of milk", +"☕ : hot beverage", +"🍵 : teacup without handle", +"🍶 : sake", +"🍾 : bottle with popping cork", +"🍷 : wine glass", +"🍸 : cocktail glass", +"🍹 : tropical drink", +"🍺 : beer mug", +"🍻 : clinking beer mugs", +"🥂 : clinking glasses", +"🥃 : tumbler glass", +"🥤 : cup with straw", +"🥢 : chopsticks", +"🍽️ : fork and knife with plate", +"🍽 : fork and knife with plate", +"🍴 : fork and knife", +"🥄 : spoon", +"🔪 : kitchen knife", +"🏺 : amphora", +"🌍 : globe showing europe-africa", +"🌎 : globe showing americas", +"🌏 : globe showing asia-australia", +"🌐 : globe with meridians", +"🗺️ : world map", +"🗺 : world map", +"🗾 : map of japan", +"🧭 : compass", +"🏔️ : snow-capped mountain", +"🏔 : snow-capped mountain", +"⛰️ : mountain", +"⛰ : mountain", +"🌋 : volcano", +"🗻 : mount fuji", +"🏕️ : camping", +"🏕 : camping", +"🏖️ : beach with umbrella", +"🏖 : beach with umbrella", +"🏜️ : desert", +"🏜 : desert", +"🏝️ : desert island", +"🏝 : desert island", +"🏞️ : national park", +"🏞 : national park", +"🏟️ : stadium", +"🏟 : stadium", +"🏛️ : classical building", +"🏛 : classical building", +"🏗️ : building construction", +"🏗 : building construction", +"🧱 : bricks", +"🏘️ : houses", +"🏘 : houses", +"🏚️ : derelict house", +"🏚 : derelict house", +"🏠 : house", +"🏡 : house with garden", +"🏢 : office building", +"🏣 : japanese post office", +"🏤 : post office", +"🏥 : hospital", +"🏦 : bank", +"🏨 : hotel", +"🏩 : love hotel", +"🏪 : convenience store", +"🏫 : school", +"🏬 : department store", +"🏭 : factory", +"🏯 : japanese castle", +"🏰 : castle", +"💒 : wedding", +"🗼 : tokyo tower", +"🗽 : statue of liberty", +"⛪ : church", +"🕌 : mosque", +"🕍 : synagogue", +"⛩️ : shinto shrine", +"⛩ : shinto shrine", +"🕋 : kaaba", +"⛲ : fountain", +"⛺ : tent", +"🌁 : foggy", +"🌃 : night with stars", +"🏙️ : cityscape", +"🏙 : cityscape", +"🌄 : sunrise over mountains", +"🌅 : sunrise", +"🌆 : cityscape at dusk", +"🌇 : sunset", +"🌉 : bridge at night", +"♨️ : hot springs", +"♨ : hot springs", +"🌌 : milky way", +"🎠 : carousel horse", +"🎡 : ferris wheel", +"🎢 : roller coaster", +"💈 : barber pole", +"🎪 : circus tent", +"🚂 : locomotive", +"🚃 : railway car", +"🚄 : high-speed train", +"🚅 : bullet train", +"🚆 : train", +"🚇 : metro", +"🚈 : light rail", +"🚉 : station", +"🚊 : tram", +"🚝 : monorail", +"🚞 : mountain railway", +"🚋 : tram car", +"🚌 : bus", +"🚍 : oncoming bus", +"🚎 : trolleybus", +"🚐 : minibus", +"🚑 : ambulance", +"🚒 : fire engine", +"🚓 : police car", +"🚔 : oncoming police car", +"🚕 : taxi", +"🚖 : oncoming taxi", +"🚗 : automobile", +"🚘 : oncoming automobile", +"🚙 : sport utility vehicle", +"🚚 : delivery truck", +"🚛 : articulated lorry", +"🚜 : tractor", +"🚲 : bicycle", +"🛴 : kick scooter", +"🛹 : skateboard", +"🛵 : motor scooter", +"🚏 : bus stop", +"🛣️ : motorway", +"🛣 : motorway", +"🛤️ : railway track", +"🛤 : railway track", +"🛢️ : oil drum", +"🛢 : oil drum", +"⛽ : fuel pump", +"🚨 : police car light", +"🚥 : horizontal traffic light", +"🚦 : vertical traffic light", +"🛑 : stop sign", +"🚧 : construction", +"⚓ : anchor", +"⛵ : sailboat", +"🛶 : canoe", +"🚤 : speedboat", +"🛳️ : passenger ship", +"🛳 : passenger ship", +"⛴️ : ferry", +"⛴ : ferry", +"🛥️ : motor boat", +"🛥 : motor boat", +"🚢 : ship", +"✈️ : airplane", +"✈ : airplane", +"🛩️ : small airplane", +"🛩 : small airplane", +"🛫 : airplane departure", +"🛬 : airplane arrival", +"💺 : seat", +"🚁 : helicopter", +"🚟 : suspension railway", +"🚠 : mountain cableway", +"🚡 : aerial tramway", +"🛰️ : satellite", +"🛰 : satellite", +"🚀 : rocket", +"🛸 : flying saucer", +"🛎️ : bellhop bell", +"🛎 : bellhop bell", +"🧳 : luggage", +"⌛ : hourglass done", +"⏳ : hourglass not done", +"⌚ : watch", +"⏰ : alarm clock", +"⏱️ : stopwatch", +"⏱ : stopwatch", +"⏲️ : timer clock", +"⏲ : timer clock", +"🕰️ : mantelpiece clock", +"🕰 : mantelpiece clock", +"🕛 : twelve o’clock", +"🕧 : twelve-thirty", +"🕐 : one o’clock", +"🕜 : one-thirty", +"🕑 : two o’clock", +"🕝 : two-thirty", +"🕒 : three o’clock", +"🕞 : three-thirty", +"🕓 : four o’clock", +"🕟 : four-thirty", +"🕔 : five o’clock", +"🕠 : five-thirty", +"🕕 : six o’clock", +"🕡 : six-thirty", +"🕖 : seven o’clock", +"🕢 : seven-thirty", +"🕗 : eight o’clock", +"🕣 : eight-thirty", +"🕘 : nine o’clock", +"🕤 : nine-thirty", +"🕙 : ten o’clock", +"🕥 : ten-thirty", +"🕚 : eleven o’clock", +"🕦 : eleven-thirty", +"🌑 : new moon", +"🌒 : waxing crescent moon", +"🌓 : first quarter moon", +"🌔 : waxing gibbous moon", +"🌕 : full moon", +"🌖 : waning gibbous moon", +"🌗 : last quarter moon", +"🌘 : waning crescent moon", +"🌙 : crescent moon", +"🌚 : new moon face", +"🌛 : first quarter moon face", +"🌜 : last quarter moon face", +"🌡️ : thermometer", +"🌡 : thermometer", +"☀️ : sun", +"☀ : sun", +"🌝 : full moon face", +"🌞 : sun with face", +"⭐ : star", +"🌟 : glowing star", +"🌠 : shooting star", +"☁️ : cloud", +"☁ : cloud", +"⛅ : sun behind cloud", +"⛈️ : cloud with lightning and rain", +"⛈ : cloud with lightning and rain", +"🌤️ : sun behind small cloud", +"🌤 : sun behind small cloud", +"🌥️ : sun behind large cloud", +"🌥 : sun behind large cloud", +"🌦️ : sun behind rain cloud", +"🌦 : sun behind rain cloud", +"🌧️ : cloud with rain", +"🌧 : cloud with rain", +"🌨️ : cloud with snow", +"🌨 : cloud with snow", +"🌩️ : cloud with lightning", +"🌩 : cloud with lightning", +"🌪️ : tornado", +"🌪 : tornado", +"🌫️ : fog", +"🌫 : fog", +"🌬️ : wind face", +"🌬 : wind face", +"🌀 : cyclone", +"🌈 : rainbow", +"🌂 : closed umbrella", +"☂️ : umbrella", +"☂ : umbrella", +"☔ : umbrella with rain drops", +"⛱️ : umbrella on ground", +"⛱ : umbrella on ground", +"⚡ : high voltage", +"❄️ : snowflake", +"❄ : snowflake", +"☃️ : snowman", +"☃ : snowman", +"⛄ : snowman without snow", +"☄️ : comet", +"☄ : comet", +"🔥 : fire", +"💧 : droplet", +"🌊 : water wave", +"🎃 : jack-o-lantern", +"🎄 : christmas tree", +"🎆 : fireworks", +"🎇 : sparkler", +"🧨 : firecracker", +"✨ : sparkles", +"🎈 : balloon", +"🎉 : party popper", +"🎊 : confetti ball", +"🎋 : tanabata tree", +"🎍 : pine decoration", +"🎎 : japanese dolls", +"🎏 : carp streamer", +"🎐 : wind chime", +"🎑 : moon viewing ceremony", +"🧧 : red envelope", +"🎀 : ribbon", +"🎁 : wrapped gift", +"🎗️ : reminder ribbon", +"🎗 : reminder ribbon", +"🎟️ : admission tickets", +"🎟 : admission tickets", +"🎫 : ticket", +"🎖️ : military medal", +"🎖 : military medal", +"🏆 : trophy", +"🏅 : sports medal", +"🥇 : 1st place medal", +"🥈 : 2nd place medal", +"🥉 : 3rd place medal", +"⚽ : soccer ball", +"⚾ : baseball", +"🥎 : softball", +"🏀 : basketball", +"🏐 : volleyball", +"🏈 : american football", +"🏉 : rugby football", +"🎾 : tennis", +"🥏 : flying disc", +"🎳 : bowling", +"🏏 : cricket game", +"🏑 : field hockey", +"🏒 : ice hockey", +"🥍 : lacrosse", +"🏓 : ping pong", +"🏸 : badminton", +"🥊 : boxing glove", +"🥋 : martial arts uniform", +"🥅 : goal net", +"⛳ : flag in hole", +"⛸️ : ice skate", +"⛸ : ice skate", +"🎣 : fishing pole", +"🎽 : running shirt", +"🎿 : skis", +"🛷 : sled", +"🥌 : curling stone", +"🎯 : direct hit", +"🎱 : pool 8 ball", +"🔮 : crystal ball", +"🧿 : nazar amulet", +"🎮 : video game", +"🕹️ : joystick", +"🕹 : joystick", +"🎰 : slot machine", +"🎲 : game die", +"🧩 : jigsaw", +"🧸 : teddy bear", +"♠️ : spade suit", +"♠ : spade suit", +"♥️ : heart suit", +"♥ : heart suit", +"♦️ : diamond suit", +"♦ : diamond suit", +"♣️ : club suit", +"♣ : club suit", +"♟️ : chess pawn", +"♟ : chess pawn", +"🃏 : joker", +"🀄 : mahjong red dragon", +"🎴 : flower playing cards", +"🎭 : performing arts", +"🖼️ : framed picture", +"🖼 : framed picture", +"🎨 : artist palette", +"🧵 : thread", +"🧶 : yarn", +"🔇 : muted speaker", +"🔈 : speaker low volume", +"🔉 : speaker medium volume", +"🔊 : speaker high volume", +"📢 : loudspeaker", +"📣 : megaphone", +"📯 : postal horn", +"🔔 : bell", +"🔕 : bell with slash", +"🎼 : musical score", +"🎵 : musical note", +"🎶 : musical notes", +"🎙️ : studio microphone", +"🎙 : studio microphone", +"🎚️ : level slider", +"🎚 : level slider", +"🎛️ : control knobs", +"🎛 : control knobs", +"🎤 : microphone", +"🎧 : headphone", +"📻 : radio", +"🎷 : saxophone", +"🎸 : guitar", +"🎹 : musical keyboard", +"🎺 : trumpet", +"🎻 : violin", +"🥁 : drum", +"📱 : mobile phone", +"📲 : mobile phone with arrow", +"☎️ : telephone", +"☎ : telephone", +"📞 : telephone receiver", +"📟 : pager", +"📠 : fax machine", +"🔋 : battery", +"🔌 : electric plug", +"💻 : laptop computer", +"🖥️ : desktop computer", +"🖥 : desktop computer", +"🖨️ : printer", +"🖨 : printer", +"⌨️ : keyboard", +"⌨ : keyboard", +"🖱️ : computer mouse", +"🖱 : computer mouse", +"🖲️ : trackball", +"🖲 : trackball", +"💽 : computer disk", +"💾 : floppy disk", +"💿 : optical disk", +"📀 : dvd", +"🧮 : abacus", +"🎥 : movie camera", +"🎞️ : film frames", +"🎞 : film frames", +"📽️ : film projector", +"📽 : film projector", +"🎬 : clapper board", +"📺 : television", +"📷 : camera", +"📸 : camera with flash", +"📹 : video camera", +"📼 : videocassette", +"🔍 : magnifying glass tilted left", +"🔎 : magnifying glass tilted right", +"🕯️ : candle", +"🕯 : candle", +"💡 : light bulb", +"🔦 : flashlight", +"🏮 : red paper lantern", +"📔 : notebook with decorative cover", +"📕 : closed book", +"📖 : open book", +"📗 : green book", +"📘 : blue book", +"📙 : orange book", +"📚 : books", +"📓 : notebook", +"📒 : ledger", +"📃 : page with curl", +"📜 : scroll", +"📄 : page facing up", +"📰 : newspaper", +"🗞️ : rolled-up newspaper", +"🗞 : rolled-up newspaper", +"📑 : bookmark tabs", +"🔖 : bookmark", +"🏷️ : label", +"🏷 : label", +"💰 : money bag", +"💴 : yen banknote", +"💵 : dollar banknote", +"💶 : euro banknote", +"💷 : pound banknote", +"💸 : money with wings", +"💳 : credit card", +"🧾 : receipt", +"💹 : chart increasing with yen", +"💱 : currency exchange", +"💲 : heavy dollar sign", +"✉️ : envelope", +"✉ : envelope", +"📧 : e-mail", +"📨 : incoming envelope", +"📩 : envelope with arrow", +"📤 : outbox tray", +"📥 : inbox tray", +"📦 : package", +"📫 : closed mailbox with raised flag", +"📪 : closed mailbox with lowered flag", +"📬 : open mailbox with raised flag", +"📭 : open mailbox with lowered flag", +"📮 : postbox", +"🗳️ : ballot box with ballot", +"🗳 : ballot box with ballot", +"✏️ : pencil", +"✏ : pencil", +"✒️ : black nib", +"✒ : black nib", +"🖋️ : fountain pen", +"🖋 : fountain pen", +"🖊️ : pen", +"🖊 : pen", +"🖌️ : paintbrush", +"🖌 : paintbrush", +"🖍️ : crayon", +"🖍 : crayon", +"📝 : memo", +"💼 : briefcase", +"📁 : file folder", +"📂 : open file folder", +"🗂️ : card index dividers", +"🗂 : card index dividers", +"📅 : calendar", +"📆 : tear-off calendar", +"🗒️ : spiral notepad", +"🗒 : spiral notepad", +"🗓️ : spiral calendar", +"🗓 : spiral calendar", +"📇 : card index", +"📈 : chart increasing", +"📉 : chart decreasing", +"📊 : bar chart", +"📋 : clipboard", +"📌 : pushpin", +"📍 : round pushpin", +"📎 : paperclip", +"🖇️ : linked paperclips", +"🖇 : linked paperclips", +"📏 : straight ruler", +"📐 : triangular ruler", +"✂️ : scissors", +"✂ : scissors", +"🗃️ : card file box", +"🗃 : card file box", +"🗄️ : file cabinet", +"🗄 : file cabinet", +"🗑️ : wastebasket", +"🗑 : wastebasket", +"🔒 : locked", +"🔓 : unlocked", +"🔏 : locked with pen", +"🔐 : locked with key", +"🔑 : key", +"🗝️ : old key", +"🗝 : old key", +"🔨 : hammer", +"⛏️ : pick", +"⛏ : pick", +"⚒️ : hammer and pick", +"⚒ : hammer and pick", +"🛠️ : hammer and wrench", +"🛠 : hammer and wrench", +"🗡️ : dagger", +"🗡 : dagger", +"⚔️ : crossed swords", +"⚔ : crossed swords", +"🔫 : pistol", +"🏹 : bow and arrow", +"🛡️ : shield", +"🛡 : shield", +"🔧 : wrench", +"🔩 : nut and bolt", +"⚙️ : gear", +"⚙ : gear", +"🗜️ : clamp", +"🗜 : clamp", +"⚖️ : balance scale", +"⚖ : balance scale", +"🔗 : link", +"⛓️ : chains", +"⛓ : chains", +"🧰 : toolbox", +"🧲 : magnet", +"⚗️ : alembic", +"⚗ : alembic", +"🧪 : test tube", +"🧫 : petri dish", +"🧬 : dna", +"🔬 : microscope", +"🔭 : telescope", +"📡 : satellite antenna", +"💉 : syringe", +"💊 : pill", +"🚪 : door", +"🛏️ : bed", +"🛏 : bed", +"🛋️ : couch and lamp", +"🛋 : couch and lamp", +"🚽 : toilet", +"🚿 : shower", +"🛁 : bathtub", +"🧴 : lotion bottle", +"🧷 : safety pin", +"🧹 : broom", +"🧺 : basket", +"🧻 : roll of paper", +"🧼 : soap", +"🧽 : sponge", +"🧯 : fire extinguisher", +"🛒 : shopping cart", +"🚬 : cigarette", +"⚰️ : coffin", +"⚰ : coffin", +"⚱️ : funeral urn", +"⚱ : funeral urn", +"🗿 : moai", +"🏧 : atm sign", +"🚮 : litter in bin sign", +"🚰 : potable water", +"♿ : wheelchair symbol", +"🚹 : men’s room", +"🚺 : women’s room", +"🚻 : restroom", +"🚼 : baby symbol", +"🚾 : water closet", +"🛂 : passport control", +"🛃 : customs", +"🛄 : baggage claim", +"🛅 : left luggage", +"⚠️ : warning", +"⚠ : warning", +"🚸 : children crossing", +"⛔ : no entry", +"🚫 : prohibited", +"🚳 : no bicycles", +"🚭 : no smoking", +"🚯 : no littering", +"🚱 : non-potable water", +"🚷 : no pedestrians", +"📵 : no mobile phones", +"🔞 : no one under eighteen", +"☢️ : radioactive", +"☢ : radioactive", +"☣️ : biohazard", +"☣ : biohazard", +"⬆️ : up arrow", +"⬆ : up arrow", +"↗️ : up-right arrow", +"↗ : up-right arrow", +"➡️ : right arrow", +"➡ : right arrow", +"↘️ : down-right arrow", +"↘ : down-right arrow", +"⬇️ : down arrow", +"⬇ : down arrow", +"↙️ : down-left arrow", +"↙ : down-left arrow", +"⬅️ : left arrow", +"⬅ : left arrow", +"↖️ : up-left arrow", +"↖ : up-left arrow", +"↕️ : up-down arrow", +"↕ : up-down arrow", +"↔️ : left-right arrow", +"↔ : left-right arrow", +"↩️ : right arrow curving left", +"↩ : right arrow curving left", +"↪️ : left arrow curving right", +"↪ : left arrow curving right", +"⤴️ : right arrow curving up", +"⤴ : right arrow curving up", +"⤵️ : right arrow curving down", +"⤵ : right arrow curving down", +"🔃 : clockwise vertical arrows", +"🔄 : counterclockwise arrows button", +"🔙 : back arrow", +"🔚 : end arrow", +"🔛 : on! arrow", +"🔜 : soon arrow", +"🔝 : top arrow", +"🛐 : place of worship", +"⚛️ : atom symbol", +"⚛ : atom symbol", +"🕉️ : om", +"🕉 : om", +"✡️ : star of david", +"✡ : star of david", +"☸️ : wheel of dharma", +"☸ : wheel of dharma", +"☯️ : yin yang", +"☯ : yin yang", +"✝️ : latin cross", +"✝ : latin cross", +"☦️ : orthodox cross", +"☦ : orthodox cross", +"☪️ : star and crescent", +"☪ : star and crescent", +"☮️ : peace symbol", +"☮ : peace symbol", +"🕎 : menorah", +"🔯 : dotted six-pointed star", +"♈ : aries", +"♉ : taurus", +"♊ : gemini", +"♋ : cancer", +"♌ : leo", +"♍ : virgo", +"♎ : libra", +"♏ : scorpio", +"♐ : sagittarius", +"♑ : capricorn", +"♒ : aquarius", +"♓ : pisces", +"⛎ : ophiuchus", +"🔀 : shuffle tracks button", +"🔁 : repeat button", +"🔂 : repeat single button", +"▶️ : play button", +"▶ : play button", +"⏩ : fast-forward button", +"⏭️ : next track button", +"⏭ : next track button", +"⏯️ : play or pause button", +"⏯ : play or pause button", +"◀️ : reverse button", +"◀ : reverse button", +"⏪ : fast reverse button", +"⏮️ : last track button", +"⏮ : last track button", +"🔼 : upwards button", +"⏫ : fast up button", +"🔽 : downwards button", +"⏬ : fast down button", +"⏸️ : pause button", +"⏸ : pause button", +"⏹️ : stop button", +"⏹ : stop button", +"⏺️ : record button", +"⏺ : record button", +"⏏️ : eject button", +"⏏ : eject button", +"🎦 : cinema", +"🔅 : dim button", +"🔆 : bright button", +"📶 : antenna bars", +"📳 : vibration mode", +"📴 : mobile phone off", +"♀️ : female sign", +"♀ : female sign", +"♂️ : male sign", +"♂ : male sign", +"⚕️ : medical symbol", +"⚕ : medical symbol", +"♾️ : infinity", +"♾ : infinity", +"♻️ : recycling symbol", +"♻ : recycling symbol", +"⚜️ : fleur-de-lis", +"⚜ : fleur-de-lis", +"🔱 : trident emblem", +"📛 : name badge", +"🔰 : japanese symbol for beginner", +"⭕ : heavy large circle", +"✅ : white heavy check mark", +"☑️ : ballot box with check", +"☑ : ballot box with check", +"✔️ : heavy check mark", +"✔ : heavy check mark", +"✖️ : heavy multiplication x", +"✖ : heavy multiplication x", +"❌ : cross mark", +"❎ : cross mark button", +"➕ : heavy plus sign", +"➖ : heavy minus sign", +"➗ : heavy division sign", +"➰ : curly loop", +"➿ : double curly loop", +"〽️ : part alternation mark", +"〽 : part alternation mark", +"✳️ : eight-spoked asterisk", +"✳ : eight-spoked asterisk", +"✴️ : eight-pointed star", +"✴ : eight-pointed star", +"❇️ : sparkle", +"❇ : sparkle", +"‼️ : double exclamation mark", +"‼ : double exclamation mark", +"⁉️ : exclamation question mark", +"⁉ : exclamation question mark", +"❓ : question mark", +"❔ : white question mark", +"❕ : white exclamation mark", +"❗ : exclamation mark", +"〰️ : wavy dash", +"〰 : wavy dash", +"©️ : copyright", +"© : copyright", +"®️ : registered", +"® : registered", +"™️ : trade mark", +"™ : trade mark", +"*️⃣ : keycap: *", +"*⃣ : keycap: *", +"0️⃣ : keycap: 0", +"0⃣ : keycap: 0", +"1️⃣ : keycap: 1", +"1⃣ : keycap: 1", +"2️⃣ : keycap: 2", +"2⃣ : keycap: 2", +"3️⃣ : keycap: 3", +"3⃣ : keycap: 3", +"4️⃣ : keycap: 4", +"4⃣ : keycap: 4", +"5️⃣ : keycap: 5", +"5⃣ : keycap: 5", +"6️⃣ : keycap: 6", +"6⃣ : keycap: 6", +"7️⃣ : keycap: 7", +"7⃣ : keycap: 7", +"8️⃣ : keycap: 8", +"8⃣ : keycap: 8", +"9️⃣ : keycap: 9", +"9⃣ : keycap: 9", +"🔟 : keycap: 10", +"💯 : hundred points", +"🔠 : input latin uppercase", +"🔡 : input latin lowercase", +"🔢 : input numbers", +"🔣 : input symbols", +"🔤 : input latin letters", +"🅰️ : a button (blood type)", +"🅰 : a button (blood type)", +"🆎 : ab button (blood type)", +"🅱️ : b button (blood type)", +"🅱 : b button (blood type)", +"🆑 : cl button", +"🆒 : cool button", +"🆓 : free button", +"ℹ️ : information", +"ℹ : information", +"🆔 : id button", +"ⓜ️ : circled m", +"ⓜ : circled m", +"🆕 : new button", +"🆖 : ng button", +"🅾️ : o button (blood type)", +"🅾 : o button (blood type)", +"🆗 : ok button", +"🅿️ : p button", +"🅿 : p button", +"🆘 : sos button", +"🆙 : up! button", +"🆚 : vs button", +"🈁 : japanese “here” button", +"🈂️ : japanese “service charge” button", +"🈂 : japanese “service charge” button", +"🈷️ : japanese “monthly amount” button", +"🈷 : japanese “monthly amount” button", +"🈶 : japanese “not free of charge” button", +"🈯 : japanese “reserved” button", +"🉐 : japanese “bargain” button", +"🈹 : japanese “discount” button", +"🈚 : japanese “free of charge” button", +"🈲 : japanese “prohibited” button", +"🉑 : japanese “acceptable” button", +"🈸 : japanese “application” button", +"🈴 : japanese “passing grade” button", +"🈳 : japanese “vacancy” button", +"㊗️ : japanese “congratulations” button", +"㊗ : japanese “congratulations” button", +"㊙️ : japanese “secret” button", +"㊙ : japanese “secret” button", +"🈺 : japanese “open for business” button", +"🈵 : japanese “no vacancy” button", +"▪️ : black small square", +"▪ : black small square", +"▫️ : white small square", +"▫ : white small square", +"◻️ : white medium square", +"◻ : white medium square", +"◼️ : black medium square", +"◼ : black medium square", +"◽ : white medium-small square", +"◾ : black medium-small square", +"⬛ : black large square", +"⬜ : white large square", +"🔶 : large orange diamond", +"🔷 : large blue diamond", +"🔸 : small orange diamond", +"🔹 : small blue diamond", +"🔺 : red triangle pointed up", +"🔻 : red triangle pointed down", +"💠 : diamond with a dot", +"🔘 : radio button", +"🔲 : black square button", +"🔳 : white square button", +"⚪ : white circle", +"⚫ : black circle", +"🔴 : red circle", +"🔵 : blue circle", +"🏁 : chequered flag", +"🚩 : triangular flag", +"🎌 : crossed flags", +"🏴 : black flag", +"🏳️ : white flag", +"🏳 : white flag", +"🏳️‍🌈 : rainbow flag", +"🏳‍🌈 : rainbow flag", +"🏴‍☠️ : pirate flag", +"🏴‍☠ : pirate flag", +"🇦🇨 : ascension island", +"🇦🇩 : andorra", +"🇦🇪 : united arab emirates", +"🇦🇫 : afghanistan", +"🇦🇬 : antigua & barbuda", +"🇦🇮 : anguilla", +"🇦🇱 : albania", +"🇦🇲 : armenia", +"🇦🇴 : angola", +"🇦🇶 : antarctica", +"🇦🇷 : argentina", +"🇦🇸 : american samoa", +"🇦🇹 : austria", +"🇦🇺 : australia", +"🇦🇼 : aruba", +"🇦🇽 : åland islands", +"🇦🇿 : azerbaijan", +"🇧🇦 : bosnia & herzegovina", +"🇧🇧 : barbados", +"🇧🇩 : bangladesh", +"🇧🇪 : belgium", +"🇧🇫 : burkina faso", +"🇧🇬 : bulgaria", +"🇧🇭 : bahrain", +"🇧🇮 : burundi", +"🇧🇯 : benin", +"🇧🇱 : st. barthélemy", +"🇧🇲 : bermuda", +"🇧🇳 : brunei", +"🇧🇴 : bolivia", +"🇧🇶 : caribbean netherlands", +"🇧🇷 : brazil", +"🇧🇸 : bahamas", +"🇧🇹 : bhutan", +"🇧🇻 : bouvet island", +"🇧🇼 : botswana", +"🇧🇾 : belarus", +"🇧🇿 : belize", +"🇨🇦 : canada", +"🇨🇨 : cocos (keeling) islands", +"🇨🇩 : congo - kinshasa", +"🇨🇫 : central african republic", +"🇨🇬 : congo - brazzaville", +"🇨🇭 : switzerland", +"🇨🇮 : côte d’ivoire", +"🇨🇰 : cook islands", +"🇨🇱 : chile", +"🇨🇲 : cameroon", +"🇨🇳 : china", +"🇨🇴 : colombia", +"🇨🇵 : clipperton island", +"🇨🇷 : costa rica", +"🇨🇺 : cuba", +"🇨🇻 : cape verde", +"🇨🇼 : curaçao", +"🇨🇽 : christmas island", +"🇨🇾 : cyprus", +"🇨🇿 : czechia", +"🇩🇪 : germany", +"🇩🇬 : diego garcia", +"🇩🇯 : djibouti", +"🇩🇰 : denmark", +"🇩🇲 : dominica", +"🇩🇴 : dominican republic", +"🇩🇿 : algeria", +"🇪🇦 : ceuta & melilla", +"🇪🇨 : ecuador", +"🇪🇪 : estonia", +"🇪🇬 : egypt", +"🇪🇭 : western sahara", +"🇪🇷 : eritrea", +"🇪🇸 : spain", +"🇪🇹 : ethiopia", +"🇪🇺 : european union", +"🇫🇮 : finland", +"🇫🇯 : fiji", +"🇫🇰 : falkland islands", +"🇫🇲 : micronesia", +"🇫🇴 : faroe islands", +"🇫🇷 : france", +"🇬🇦 : gabon", +"🇬🇧 : united kingdom", +"🇬🇩 : grenada", +"🇬🇪 : georgia", +"🇬🇫 : french guiana", +"🇬🇬 : guernsey", +"🇬🇭 : ghana", +"🇬🇮 : gibraltar", +"🇬🇱 : greenland", +"🇬🇲 : gambia", +"🇬🇳 : guinea", +"🇬🇵 : guadeloupe", +"🇬🇶 : equatorial guinea", +"🇬🇷 : greece", +"🇬🇸 : south georgia & south sandwich islands", +"🇬🇹 : guatemala", +"🇬🇺 : guam", +"🇬🇼 : guinea-bissau", +"🇬🇾 : guyana", +"🇭🇰 : hong kong sar china", +"🇭🇲 : heard & mcdonald islands", +"🇭🇳 : honduras", +"🇭🇷 : croatia", +"🇭🇹 : haiti", +"🇭🇺 : hungary", +"🇮🇨 : canary islands", +"🇮🇩 : indonesia", +"🇮🇪 : ireland", +"🇮🇱 : israel", +"🇮🇲 : isle of man", +"🇮🇳 : india", +"🇮🇴 : british indian ocean territory", +"🇮🇶 : iraq", +"🇮🇷 : iran", +"🇮🇸 : iceland", +"🇮🇹 : italy", +"🇯🇪 : jersey", +"🇯🇲 : jamaica", +"🇯🇴 : jordan", +"🇯🇵 : japan", +"🇰🇪 : kenya", +"🇰🇬 : kyrgyzstan", +"🇰🇭 : cambodia", +"🇰🇮 : kiribati", +"🇰🇲 : comoros", +"🇰🇳 : st. kitts & nevis", +"🇰🇵 : north korea", +"🇰🇷 : south korea", +"🇰🇼 : kuwait", +"🇰🇾 : cayman islands", +"🇰🇿 : kazakhstan", +"🇱🇦 : laos", +"🇱🇧 : lebanon", +"🇱🇨 : st. lucia", +"🇱🇮 : liechtenstein", +"🇱🇰 : sri lanka", +"🇱🇷 : liberia", +"🇱🇸 : lesotho", +"🇱🇹 : lithuania", +"🇱🇺 : luxembourg", +"🇱🇻 : latvia", +"🇱🇾 : libya", +"🇲🇦 : morocco", +"🇲🇨 : monaco", +"🇲🇩 : moldova", +"🇲🇪 : montenegro", +"🇲🇫 : st. martin", +"🇲🇬 : madagascar", +"🇲🇭 : marshall islands", +"🇲🇰 : macedonia", +"🇲🇱 : mali", +"🇲🇲 : myanmar (burma)", +"🇲🇳 : mongolia", +"🇲🇴 : macau sar china", +"🇲🇵 : northern mariana islands", +"🇲🇶 : martinique", +"🇲🇷 : mauritania", +"🇲🇸 : montserrat", +"🇲🇹 : malta", +"🇲🇺 : mauritius", +"🇲🇻 : maldives", +"🇲🇼 : malawi", +"🇲🇽 : mexico", +"🇲🇾 : malaysia", +"🇲🇿 : mozambique", +"🇳🇦 : namibia", +"🇳🇨 : new caledonia", +"🇳🇪 : niger", +"🇳🇫 : norfolk island", +"🇳🇬 : nigeria", +"🇳🇮 : nicaragua", +"🇳🇱 : netherlands", +"🇳🇴 : norway", +"🇳🇵 : nepal", +"🇳🇷 : nauru", +"🇳🇺 : niue", +"🇳🇿 : new zealand", +"🇴🇲 : oman", +"🇵🇦 : panama", +"🇵🇪 : peru", +"🇵🇫 : french polynesia", +"🇵🇬 : papua new guinea", +"🇵🇭 : philippines", +"🇵🇰 : pakistan", +"🇵🇱 : poland", +"🇵🇲 : st. pierre & miquelon", +"🇵🇳 : pitcairn islands", +"🇵🇷 : puerto rico", +"🇵🇸 : palestinian territories", +"🇵🇹 : portugal", +"🇵🇼 : palau", +"🇵🇾 : paraguay", +"🇶🇦 : qatar", +"🇷🇪 : réunion", +"🇷🇴 : romania", +"🇷🇸 : serbia", +"🇷🇺 : russia", +"🇷🇼 : rwanda", +"🇸🇦 : saudi arabia", +"🇸🇧 : solomon islands", +"🇸🇨 : seychelles", +"🇸🇩 : sudan", +"🇸🇪 : sweden", +"🇸🇬 : singapore", +"🇸🇭 : st. helena", +"🇸🇮 : slovenia", +"🇸🇯 : svalbard & jan mayen", +"🇸🇰 : slovakia", +"🇸🇱 : sierra leone", +"🇸🇲 : san marino", +"🇸🇳 : senegal", +"🇸🇴 : somalia", +"🇸🇷 : suriname", +"🇸🇸 : south sudan", +"🇸🇹 : são tomé & príncipe", +"🇸🇻 : el salvador", +"🇸🇽 : sint maarten", +"🇸🇾 : syria", +"🇸🇿 : swaziland", +"🇹🇦 : tristan da cunha", +"🇹🇨 : turks & caicos islands", +"🇹🇩 : chad", +"🇹🇫 : french southern territories", +"🇹🇬 : togo", +"🇹🇭 : thailand", +"🇹🇯 : tajikistan", +"🇹🇰 : tokelau", +"🇹🇱 : timor-leste", +"🇹🇲 : turkmenistan", +"🇹🇳 : tunisia", +"🇹🇴 : tonga", +"🇹🇷 : turkey", +"🇹🇹 : trinidad & tobago", +"🇹🇻 : tuvalu", +"🇹🇼 : taiwan", +"🇹🇿 : tanzania", +"🇺🇦 : ukraine", +"🇺🇬 : uganda", +"🇺🇲 : u.s. outlying islands", +"🇺🇳 : united nations", +"🇺🇸 : united states", +"🇺🇾 : uruguay", +"🇺🇿 : uzbekistan", +"🇻🇦 : vatican city", +"🇻🇨 : st. vincent & grenadines", +"🇻🇪 : venezuela", +"🇻🇬 : british virgin islands", +"🇻🇮 : u.s. virgin islands", +"🇻🇳 : vietnam", +"🇻🇺 : vanuatu", +"🇼🇫 : wallis & futuna", +"🇼🇸 : samoa", +"🇽🇰 : kosovo", +"🇾🇪 : yemen", +"🇾🇹 : mayotte", +"🇿🇦 : south africa", +"🇿🇲 : zambia", +"🇿🇼 : zimbabwe", +"🏴󠁧󠁢󠁥󠁮󠁧󠁿 : england", +"🏴󠁧󠁢󠁳󠁣󠁴󠁿 : scotland", +"🏴󠁧󠁢󠁷󠁬󠁳󠁿 : wales", +] +proc getEmoji*(): seq[string] = + return emoji_list diff --git a/fuzzytime/fuzzytime.nimble b/fuzzytime/fuzzytime.nimble new file mode 100644 index 0000000..3647fea --- /dev/null +++ b/fuzzytime/fuzzytime.nimble @@ -0,0 +1,13 @@ +# Package + +version = "0.1.0" +author = "Paul Wilde" +description = "Displays the fuzzy time in dmenu" +license = "MIT" +srcDir = "src" +bin = @["fuzzytime"] + + +# Dependencies + +requires "nim >= 1.6.6" diff --git a/fuzzytime/src/fuzzytime.nim b/fuzzytime/src/fuzzytime.nim new file mode 100644 index 0000000..a9af4c2 --- /dev/null +++ b/fuzzytime/src/fuzzytime.nim @@ -0,0 +1,92 @@ +import ../../base +import std/[times] + +const default_bg = lightblue +const default_fg = black + +proc getHour(hr: int): string +proc getMinute(min: int): string + +proc getFuzzyTime(): string = + let tm = now() + var hr = tm.hour() + let min = tm.minute() + var link = "past" + if min > 32 : + link = "to" + case hr: + of 23: + hr = 0 + else: + hr = hr + 1 + if min >= 58 or min <= 02: + return getHour(hr) & " " & getMinute(min) + else: + return getMinute(min) & " " & link & " " & getHour(hr) + +proc getHour(hr: int): string = + case hr: + of 1, 13: + return "one" + of 2, 14: + return "two" + of 3, 15: + return "three" + of 4, 16: + return "four" + of 5, 17: + return "five" + of 6, 18: + return "six" + of 7, 19: + return "seven" + of 8, 20: + return "eight" + of 9, 21: + return "nine" + of 10, 22: + return "ten" + of 11, 23: + return "eleven" + of 0, 12, 24: + return "twelve" + else: + return "error" + +proc getMinute(min: int): string = + case min: + of 58,59,0,1,2: + return "o'clock" + of 3,4,5,6,7,53,54,55,56,57: + return "five" + of 8,9,10,11,12,48,49,50,51,52: + return "ten" + of 13,14,15,16,17,43,44,45,46,47: + return "quarter" + of 18,19,20,21,22,38,39,40,41,42: + return "twenty" + of 23,24,25,26,27,33,34,35,36,37: + return "twenty-five" + of 28,29,30,31,32: + return "half" + else: + return "error" + +proc getObject(time: string): Info = + var data = newInfo("Fuzzy Time") + data.full_text = time + data.selected_bg = default_bg + data.selected_fg = default_fg + #i3bar stuff + data.color = default_fg + data.border = default_fg + return data + + +proc main() = + let time = getFuzzyTime() + let data = getObject(time) + outputData(data) + +if isMainModule: + main() diff --git a/i3_workspaces/i3_workspaces.nimble b/i3_workspaces/i3_workspaces.nimble new file mode 100644 index 0000000..38c0251 --- /dev/null +++ b/i3_workspaces/i3_workspaces.nimble @@ -0,0 +1,13 @@ +# Package + +version = "0.1.0" +author = "Paul Wilde" +description = "Displays open windows in i3 workspaces" +license = "MIT" +srcDir = "src" +bin = @["i3_workspaces"] + + +# Dependencies + +requires "nim >= 1.6.6" diff --git a/i3_workspaces/src/i3_workspaces.nim b/i3_workspaces/src/i3_workspaces.nim new file mode 100644 index 0000000..60e02bf --- /dev/null +++ b/i3_workspaces/src/i3_workspaces.nim @@ -0,0 +1,200 @@ +import ../../base +import std/[osproc,json,strutils] + +const I3_WORKSPACES = "i3-msg -t get_workspaces" +const I3_TREE = "i3-msg -t get_tree" +const VISIBLE = "#" +const URGENT = "!" +const FOCUSED = "%" + +type + Workspace = object + num: int + name: string + focused: bool + visible: bool + output: string + urgent: bool + display_string: string + apps: seq[string] + applications: seq[Application] + application: Application + Application = object + title: string + class: string + focused: bool + urgent: bool + +var my_workspaces: seq[Workspace] +var current_workspace: int = 0 + +proc showWorkspaces() + +proc buildString(ws: Workspace): string = + var str = $ws.num & " |" +# if ws.urgent or ws.application.urgent: + if ws.application.urgent: + str &= URGENT + else: + str &= " " + if ws.focused or ws.application.focused: + current_workspace = ws.num + str &= FOCUSED +# elif ws.visible: +# str &= VISIBLE + else: + str &= " " + str &= "| " & ws.output & " | " + if ws.application.class != "": + str &= ws.application.class & " " & ws.application.title & " | " + else: + str = "" +# for app in ws.applications: +# str &= app.class & " " & app.title & " | " + return str + +proc findWorkspace(workspace: string): Workspace = + for ws in my_workspaces: + if workspace == ws.display_string: + return ws + +proc switchWorkspace(workspace: string) = + if workspace.contains("%"): + return + let ws = findWorkspace(workspace) + if ws.num == current_workspace: + return + let cmd = "i3-msg workspace " & $ws.num + discard execCmd(cmd) + showWorkspaces() + +# proc getApplications(node: JsonNode): (seq[string],bool) = +# var apps: seq[string] = @[] +# var focused = false +# for item in node["nodes"].getElems(): +# var name = "" +# if item["focused"].getBool(): +# focused = true +# if item{"window_properties"} != nil : +# let prop = item["window_properties"] +# name = prop["class"].getStr() +# name &= " " & prop["title"].getStr() +# echo "Adding application : " & name +# apps.add(name) +# return (apps, focused) +# +proc getApplication(node: JsonNode, ws: Workspace = Workspace()): Application = + var app = Application() + let window = node["window_properties"] + app.title = window["title"].getStr() + app.class = window["class"].getStr() + app.focused = node["focused"].getBool() + app.urgent = node["urgent"].getBool() + #echo ws.num + #echo app.title & " " & app.class + return app + +# proc findWorkspaces(node: JsonNode) = +# for channel in node["nodes"].getElems(): +# case channel["type"].getStr(): +# of "workspace": +# if channel["output"].getStr() == "__i3": +# continue +# let w = channel +# let apps = getApplications(channel) +# var space = Workspace( +# num: w["num"].getInt(), +# name: w["name"].getStr(), +# focused: apps[1], +# #visible: w["visible"].getBool(), +# urgent: w["urgent"].getBool(), +# output: w["output"].getStr(), +# apps: apps[0] +# ) +# space.display_string = buildString(space) +# my_workspaces.add(space) +# else: +# echo "finding workspaces..." +# findWorkspaces(channel) +# return + +proc newWorkspace(node: JsonNode): Workspace = + return Workspace( + num: node["num"].getInt(), + name: node["name"].getStr(), + focused: node["focused"].getBool(), + #visible: w["visible"].getBool(), + urgent: node["urgent"].getBool(), + output: node["output"].getStr(), + ) + +proc findWorkspacesTree(node: JsonNode, parent: Workspace = Workspace()) = + for channel in node["nodes"].getElems(): + ### move this into for loop if want separate entry per window + var ws: Workspace = Workspace() + if parent.num > 0: + ws = parent + elif node{"type"}.getStr() == "workspace": + if node["output"].getStr() == "__i3": + return + ws = newWorkspace(node) + ### + if channel{"window_properties"} != nil: + let app = getApplication(channel,ws) + if ws.name != "": + #if app.focused: + # ws.focused = true + ws.applications.add(app) + ws.application = app + elif ws.num > 0 and len(channel{"nodes"}) > 0: + findWorkspacesTree(channel,ws) + else: + findWorkspacesTree(channel) + ### move this into for loop if want separate entry per window + if ws.name != "": + ws.display_string = ws.buildString() + if ws.display_string != "": + my_workspaces.add(ws) + ### + return + +proc getTree() = + let cur_workspaces = execCmdEx(I3_TREE) + if cur_workspaces.output != "": + let root = parseJson(cur_workspaces.output) + findWorkspacesTree(root) + return + +proc getWorkspaces(): seq[Workspace] = + let cur_workspaces = execCmdEx(I3_WORKSPACES) + if cur_workspaces.output != "": + let ws = parseJson(cur_workspaces.output) + for w in ws: + var space = Workspace( + num: w["num"].getInt(), + name: w["name"].getStr(), + focused: w["focused"].getBool(), + visible: w["visible"].getBool(), + urgent: w["urgent"].getBool(), + output: w["output"].getStr() + ) + space.display_string = buildString(space) + my_workspaces.add(space) + return my_workspaces + +proc showWorkspaces() = + my_workspaces = @[] + getTree() + var info = newInfo("Workspaces") + var args: seq[string] = @[] + for ws in my_workspaces: + args.add(ws.display_string) + let output = outputData(info,args) + if output in args: + switchWorkspace(output) + +proc main() = + showWorkspaces() + +if isMainModule: + main() diff --git a/nic/nic.nimble b/nic/nic.nimble new file mode 100644 index 0000000..d49ca6e --- /dev/null +++ b/nic/nic.nimble @@ -0,0 +1,13 @@ +# Package + +version = "0.1.0" +author = "Paul Wilde" +description = "Display NIC IP address and link to manage NICs" +license = "GPL-3.0-or-later" +srcDir = "src" +bin = @["nic"] + + +# Dependencies + +requires "nim >= 1.6.6" diff --git a/nic/src/nic.nim b/nic/src/nic.nim new file mode 100644 index 0000000..87b6b61 --- /dev/null +++ b/nic/src/nic.nim @@ -0,0 +1,66 @@ +import ../../base +import std/[os,osproc,strutils,sequtils] + +const default_fg = black +const default_bg = purple +const mng_cmd = "alacritty -e nmtui-connect" +const nics: seq[string] = @["wlan0","bridge0", "enp3s0","wlp2s0","enp0s20f0u3"] + +proc getIP(nic: string): string = + let cmd = "ifconfig " & nic & " | grep inet | awk -F\" \" '{print $2}' | head -1 | awk '{print $1}'" + let ip = execCmdEx(cmd) + return strip(ip.output) + +proc getOnlineState(nic: string): string = + try: + let oper = readFile("/sys/class/net/" & nic & "/operstate") + let state = strip(oper) + return "[" & state & "]" + except: + echo "Error getting operstate for " & nic & " : ", getCurrentExceptionMsg() + return "" + +proc getConnState(nic: string): (string, string) = + let state = getOnlineState(nic) + let ip = getIP(nic) + if state == "[down]" or ip == "": + return ("disconnected", state) + return (ip, state) + +proc getObject(): Info = + var data = newInfo("IP") + data.selected_bg = default_bg + data.selected_fg = default_fg + # i3bar stuff + data.border = default_bg + return data + +proc getNetInfo*(my_nics: seq[string]) = + var my_nic_states: seq[string] = @[] + for nic in my_nics: + let (ip, state) = getConnState(nic) + my_nic_states.add(nic & ":" & state & " " & ip) + let data = getObject() + let args = concat(my_nic_states,@["manage"]) + let option = outputData(data, args) + if option in my_nic_states: + discard execCmd(mng_cmd) + case option: + of "manage": + discard execCmd(mng_cmd) + +proc getNics*(): seq[string] = + var my_nics: seq[string] = @[] + for nic in os.walkDir("/sys/class/net/"): + let n = replace(nic.path, "/sys/class/net/", "") + my_nics.add(n) + + if len(my_nics) > 0: + return my_nics + return @["no-nic"] + +proc main() = + getNetInfo(getNics()) + +if isMainModule: + main() diff --git a/notes/notes.nimble b/notes/notes.nimble new file mode 100644 index 0000000..69711d5 --- /dev/null +++ b/notes/notes.nimble @@ -0,0 +1,13 @@ +# Package + +version = "0.1.0" +author = "Paul Wilde" +description = "A notes app for dmenu" +license = "GPL-3.0-or-later" +srcDir = "src" +bin = @["notes"] + + +# Dependencies + +requires "nim >= 1.6.6" diff --git a/notes/src/notes.nim b/notes/src/notes.nim new file mode 100644 index 0000000..8f06fff --- /dev/null +++ b/notes/src/notes.nim @@ -0,0 +1,167 @@ +import ../../base +import std/[os,strutils,sequtils,times] + +const note_dir = WM_TOOLS_DIR & ".notes.dmenu/" # Putting it in Nextcloud so it can sync :-) +const default_bg = white +const default_fg = black + +type + Note = object + id: string + text: string + +proc startNotes() + +proc displayOptionMenu(option: string) + +var notes: seq[Note] = @[] + +proc readNotes(): seq[Note] = + if len(notes) == 0: + if existsOrCreateDir(note_dir): + for note_file in walkDir(note_dir): + try: + var note = Note() + note.id = note_file[1] + note.text = stripQuotes(readFile(note_file[1])) + notes.add(note) + except: + echo "Unable to read note : ", note_file, " : ", getCurrentExceptionMsg() + return notes + +proc removeNote(note: Note) = + try: + removeFile(note.id) + for idx, a_note in notes: + if note.id == a_note.id: + notes.delete(idx) + except: + echo "Unable to delete file : ", note.id, " : ", getCurrentExceptionMsg() + +proc getNoteStrings(): seq[string] = + var note_list: seq[string] = @[] + if len(notes) == 0: + discard readNotes() + for note in notes: + note_list.add(note.text) + return note_list + +proc writeNote(note: Note, is_new: bool = false) = + if note.text == "": + return + try: + + writeFile(note.id, stripQuotes(note.text)) + if is_new: + var new_note = note + new_note.text = stripQuotes(new_note.text) + notes.add(note) + else: + for idx, a_note in notes: + if a_note.id == note.id: + notes[idx].text = stripQuotes(note.text) + except: + echo "write_note, Unable to write note : ", note.id, " : ", getCurrentExceptionMsg() + +proc getNotes(): (Info, seq[string]) = + var info = newInfo("Notes") + info.selected_bg = default_bg + info.selected_fg = default_fg + let notes = getNoteStrings() + return (info,notes) + +proc getNote(text: string): Note = + for note in notes: + if note.text == text: + return note + return Note() + +proc displayDeleteConfirmationMenu(note: string) = + var yes_no = newInfo("Confirm Delete note : " & note) + yes_no.selected_bg = default_bg + yes_no.selected_fg = default_fg + let args = @["yes", "no"] + let choice = outputData(yes_no, args) + case choice: + of "yes": + let rm_note = getNote(note) + if rm_note.text == note: + removeNote(rm_note) + of "no": + displayOptionMenu(note) + +proc replaceNoteConfirmationMenu(note_idx: int, new_text: string): bool = + let old_note = notes[note_idx] + var diag = newInfo("Replace Note : '" & old_note.text & "', with '" & new_text & "' ?") + diag.selected_bg = default_bg + diag.selected_fg = default_fg + let args = @["yes", "no"] + let choice = outputData(diag,args) + case choice: + of "yes": + echo "here" + return true + else: + return false + +proc replaceNote(new_text: string, old_text: string) = + for idx, note in notes: + if note.text == old_text: + if replaceNoteConfirmationMenu(idx,new_text): + var new_note = note + new_note.text = new_text + notes[idx] = new_note + writeNote(new_note) + return + +proc displayOptionMenu(option: string) = + var select = newInfo("Note") + select.selected_bg = default_bg + select.selected_fg = default_fg + let note_choices = @["rm","back"] + let args = concat(@[option],note_choices) + let chosen = outputData(select,args) + if chosen in note_choices: + case chosen: + of "rm": + displayDeleteConfirmationMenu(option) + startNotes() + of "back": + startNotes() + elif chosen != "" and chosen != option: + replaceNote(chosen, option) + displayOptionMenu(chosen) + else: + displayOptionMenu(option) + +proc newNote(text: string) = + var new_note = Note() + let note_id = times.now().format("'{'yyyyMMdd-HHmmss-ffffff'}'") + new_note.id = note_dir & note_id + new_note.text = text + writeNote(new_note, is_new = true) + +proc startNotes() = + let (info,all_notes) = getNotes() + let all_choices = @["exit"] + let args = concat(all_notes, all_choices) + let option = outputData(info, args) + if option in all_choices: + case option: + of "exit": + return + if option in all_notes: + displayOptionMenu(option) + elif option != "": + newNote(option) + startNotes() + +proc main() = + echo "Note dir : ", note_dir + if tool != "dmenu" and tool != "rofi": + echo "Can only be run in dmenu or rofi mode. Exiting..." + return + startNotes() + +if isMainModule: + main() diff --git a/pingclock/pingclock.nimble b/pingclock/pingclock.nimble new file mode 100644 index 0000000..6d8d20e --- /dev/null +++ b/pingclock/pingclock.nimble @@ -0,0 +1,13 @@ +# Package + +version = "0.1.0" +author = "Paul Wilde" +description = "A ping clock - display current ping time" +license = "GPL-3.0-or-later" +srcDir = "src" +bin = @["pingclock"] + + +# Dependencies + +requires "nim >= 1.6.6" diff --git a/pingclock/src/pingclock.nim b/pingclock/src/pingclock.nim new file mode 100644 index 0000000..5c5b1e7 --- /dev/null +++ b/pingclock/src/pingclock.nim @@ -0,0 +1,85 @@ +import ../../base +import std/[osproc, re, strutils] + +const host: string = "9.9.9.9" +const default_bg = blue +const default_fg = white +const medium_bg = alert +const medium_fg = black +const alert_bg = alert +const alert_fg = black +const warning_bg = red +const warning_fg = white + +let ping_re = re(r"time=[0-9.]+") +const ping_cmd: string = "ping -4 -c 1 " & host + +proc getPing(): float = + var ping: float = -1 + let cmdOut = execCmdEx(ping_cmd) + let lines = splitLines(cmdOut.output) + let ping_line = lines[1] + let bounds = findBounds(ping_line, ping_re) + if bounds.first > 0: + let png = ping_line[bounds.first+5..bounds.last] + ping = parseFloat(png) + return ping + +proc getObject(ping: float): Info = + let pingstr = split($ping,".") + let niceping = pingstr[0] & "." & pingstr[1][0] + var text = "🏓 " & niceping & " ms" + var state = 0 + if ping < 0: + text = "❌ No Pong" + state = 1 + else: + case ping: + of 0..100: + state = 0 + of 101..400: + state = 1 + of 401..1000: + state = 2 + else: + state = 9 + + var data = newInfo("Ping Clock") + data.full_text = text + # i3bar stuff + data.color = default_fg + data.border = default_bg + data.background = black + data.selected_bg = default_bg + data.selected_fg = default_fg + case state: + of 1: + data.selected_bg = medium_bg + data.selected_fg = medium_fg + # i3bar stuff + data.color = medium_bg + of 2: + data.selected_bg = alert_bg + data.selected_fg = alert_fg + # i3bar stuff + data.color = alert_bg + of 9: + data.selected_bg = warning_bg + data.selected_fg = warning_fg + # i3bar stuff + data.color = warning_bg + else: + #default options already set + let ok = true + return data + + +proc main() = + let ping = get_ping() + let data = getObject(ping) + let output = outputData(data) + if output == data.full_text: + main() + +if isMainModule: + main() diff --git a/remmina/remmina.nimble b/remmina/remmina.nimble new file mode 100644 index 0000000..3a16881 --- /dev/null +++ b/remmina/remmina.nimble @@ -0,0 +1,14 @@ +# Package + +version = "0.1.0" +author = "Paul Wilde" +description = "A Remmina client tool and opener" +license = "GPL-3.0-or-later" +srcDir = "src" +bin = @["remmina"] + + +# Dependencies + +requires "nim >= 1.6.6" +requires "configparser >= 0.1.0" diff --git a/remmina/src/remmina.nim b/remmina/src/remmina.nim new file mode 100644 index 0000000..670bb11 --- /dev/null +++ b/remmina/src/remmina.nim @@ -0,0 +1,74 @@ +import ../../base +import std/[os,osproc,tables,algorithm] +import configparser + +const REMMINA_DIR = getHomeDir() & ".local/share/remmina" +const REMMINA_WS = "4" + +var sessions = initTable[string,string]() +var names: seq[string] = @[] + +proc main() + +proc switchWorkspace() = + if REMMINA_WS != "": + discard execCmd("i3-msg workspace number " & REMMINA_WS) + discard execCmd("swaymsg workspace number " & REMMINA_WS) + +proc getRemminaFiles(): seq[string] = + if len(names) < 1: + for file in walkFiles(REMMINA_DIR & "/*.remmina"): + let content = readFile(file) + let ini = parseIni(content) + let group = ini.getProperty("remmina","group") + let name = ini.getProperty("remmina","name") + let server = ini.getProperty("remmina","server") + if name != "" and server != "": + let slug = group & " : " & name & " : (" & server & ")" + sessions[slug] = file + names.add(slug) + names.sort() + return names + +proc editRemmina(conn: string) = + let session = sessions[conn] + discard execCmd("remmina -e " & quote(session)) + +proc startRemmina(conn: string) = + let session = sessions[conn] + discard execCmd("remmina -c " & quote(session)) + +proc selectRemmina(conn: string) = + var info = newInfo("Remmina : " & conn) + let args = @["connect", "edit", "back"] + let output = outputData(info,args) + if output in args: + case output: + of "connect": + startRemmina(conn) + switchWorkspace() + of "edit": + editRemmina(conn) + switchWorkspace() + of "back": + main() + + + +proc main() = + var info = newInfo("Remmina") + var args: seq[string] = getRemminaFiles() + args.add("new") + args.add("exit") + let output = outputData(info,args) + if output == "exit" or output == "": + return + elif output == "new": + discard execCmd("remmina --new") + elif output in names: + selectRemmina(output) + return + return + +if isMainModule: + main() diff --git a/screenshot/screenshot.nimble b/screenshot/screenshot.nimble new file mode 100644 index 0000000..aef1cb2 --- /dev/null +++ b/screenshot/screenshot.nimble @@ -0,0 +1,13 @@ +# Package + +version = "0.1.0" +author = "Paul Wilde" +description = "A screenshot client, works on both X11 and Wayland" +license = "GPL-3.0-or-later" +srcDir = "src" +bin = @["screenshot"] + + +# Dependencies + +requires "nim >= 1.6.6" diff --git a/screenshot/src/screenshot.nim b/screenshot/src/screenshot.nim new file mode 100644 index 0000000..a4bd932 --- /dev/null +++ b/screenshot/src/screenshot.nim @@ -0,0 +1,102 @@ +import ../../base +import std/[times,os,osproc,strutils,sequtils] + +var screenshot_type = "" +const TYPES = @["region", "fullscreen", "window"] +const DATE_FORMAT = "yyyyMMdd-hhmmss" +const FILENAME = "Screenshot-%d.png" +const TEMP_DIR = "/tmp/" +const SCREENSHOT_CMD = "maim -u %s --format png %f" +const SCREENSHOT_CMD_WL = "grim %s %f" +var RUN_CMD = SCREENSHOT_CMD +let DATE_STR = now().format(DATE_FORMAT) +# where %s is an extra flag or process, i.e. xdotool for getting active window +const ACTIVE_WINDOW_CMD = "-i $(xdotool getactivewindow)" +const REGION_FLAG = "-s" +const REGION_FLAG_WL = "-g \"$(slurp)\"" +var REGION_CMD = REGION_FLAG +const CLIPBOARD_CMD = "xclip -selection clipboard -t image/png" +const CLIPBOARD_CMD_WL = "wl-copy" +var CLIP_CMD = CLIPBOARD_CMD + +proc saveToClipboard(filename: string) = + let cmd = "cat " & filename & " | " & CLIP_CMD + let status = execCmd(cmd) + if status == 0 and fileExists(filename): + removeFile(filename) + return + +proc saveToFile(filename: string) = + if fileExists(filename): + let new_filename = filename.replace("/tmp/", getHomeDir() & "Screenshots/") + copyFile(filename, new_filename) + if fileExists(new_filename): + removeFile(filename) + return + +proc openFile(filename: string) = + let cmd = "xdg-open " & filename + discard execCmd(cmd) + return + +proc showScreenshotSaveSel(filename: string) = + let info = newInfo("Save Screenshot") + let args = @["clipboard", "save", "open", "---", "exit"] + let choice = outputData(info,args) + if choice == "---": + showScreenshotSaveSel(filename) + elif choice == "exit": + return + elif choice in args: + case choice: + of "clipboard": + saveToClipboard(filename) + of "save": + saveToFile(filename) + of "open": + openFile(filename) + return + +proc showScreenshotTypeSel() = + let info = newInfo("Screenshot type") + let args = concat(TYPES,@["---","exit"]) + let choice = outputData(info,args) + if choice in TYPES: + screenshot_type = choice + elif choice == "---": + showScreenshotTypeSel() + elif choice == "exit": + return + return + +proc takeScreenshot() = + let filename = TEMP_DIR & FILENAME.replace("%d",DATE_STR) + var cmd = RUN_CMD.replace("%f",filename) + case screenshot_type: + of "window": + cmd = cmd.replace("%s",ACTIVE_WINDOW_CMD) + of "region": + cmd = cmd.replace("%s",REGION_CMD) + else: #fullscreen + cmd = cmd.replace("%s","") + # sleep for a bit otherwise the screen shot grabs dmenu as well + sleep(1*500) + + let status = execCmd(cmd) + if status == 0: + showScreenshotSaveSel(filename) + return + +if isMainModule: + if wayland: + RUN_CMD = SCREENSHOT_CMD_WL + REGION_CMD = REGION_FLAG_WL + CLIP_CMD = CLIPBOARD_CMD_WL + for arg in args: + if arg in TYPES: + screenshot_type = arg + break + if screenshot_type == "": + showScreenshotTypeSel() + if screenshot_type != "": + takeScreenshot() diff --git a/show_date/show_date.nimble b/show_date/show_date.nimble new file mode 100644 index 0000000..eff8fd0 --- /dev/null +++ b/show_date/show_date.nimble @@ -0,0 +1,13 @@ +# Package + +version = "0.1.0" +author = "Paul Wilde" +description = "Displays the date in dmenu" +license = "MIT" +srcDir = "src" +bin = @["date"] + + +# Dependencies + +requires "nim >= 1.6.6" diff --git a/show_date/src/show_date.nim b/show_date/src/show_date.nim new file mode 100644 index 0000000..8faace7 --- /dev/null +++ b/show_date/src/show_date.nim @@ -0,0 +1,52 @@ +import ../../base +import std/[times,osproc,re] + +const default_bg = blue +const default_fg = white +const default_format = "yyyy-MM-dd" +const cal_pos_x = "20" +const cal_pos_y = "20" + +proc getObject(date: string): Info = + var data = newInfo("Date") + data.full_text = date + data.border = default_bg + data.selected_bg = default_bg + data.selected_fg = default_fg + return data + +proc newCalendar(): string = + var c = """yad --calendar \ + --undecorated --fixed --close-on-unfocus --no-buttons \ + --width="222" --height="193" \ + --posx="%pos_x" --posy="%pos_y" \ + --title="yad-calendar" --borders 0 > /dev/null + """ + return c + +proc openCalendar*(input: i3barInput) = + var c = newCalendar() + c = replace(c,re"%pos_x", $(input.x - 111)) + c = replace(c,re"%pos_y", $input.y) + discard execCmd(c) + +proc dmenuCalendar() = + var c = newCalendar() + c = replace(c,re"%pos_x", cal_pos_x) + c = replace(c,re"%pos_y", cal_pos_y) + discard execCmd(c) + +proc getDate*() = + let date_today = times.now().format(default_format) + let data = getObject(date_today) + let output = outputData(data) + if output == date_today: + dmenuCalendar() + +proc main() = + getDate() + + +if isMainModule: + main() + diff --git a/temperature/src/temperature.nim b/temperature/src/temperature.nim new file mode 100644 index 0000000..a1ac8a4 --- /dev/null +++ b/temperature/src/temperature.nim @@ -0,0 +1,72 @@ +import ../../base +import std/[os,re,math,strutils] + +const default_bg = green +const default_fg = black +const alert_bg = yellow +const alert_fg = black +const warning_bg = red +const warning_fg = black + +proc getThermalZones(): seq[string] = + var zones: seq[string] = @[] + let dirname = re("thermal_zone[\\d]+") + for file in walkDir("/sys/class/thermal/"): + if contains(file.path,dirname): + let state = readFile(file.path & "/mode") + if contains(state,re"enabled"): + zones.add(file.path) + return zones + +proc getTemp(zone: string): int = + let temp = strip(readFile(zone & "/temp")) + return parseInt(temp) + +proc getAverageTemp(zones: seq[string]): int = + var temps: int = 0 + for zone in zones: + let temp = getTemp(zone) + temps += temp + let avgtemp = ceil((temps / len(zones))/1000) + return toInt(round(avgtemp,0)) + +proc getObject(temp: int): Info = + var icon = "" + var bg_col = default_bg + var fg_col = default_fg + case temp: + of 40..59: + bg_col = alert_bg + fg_col = alert_fg + icon = "" + of 60.. 200: + bg_col = warning_bg + fg_col = warning_fg + icon = "" + else: + bg_col = default_bg + fg_col = default_fg + icon = "" + let text = "" & icon & " " & $temp & "°C" + let main_text = icon & " " & $temp & "°C" + var data = newInfo("Temperature") + data.full_text = main_text + data.selected_bg = bg_col + data.selected_fg = fg_col + # i3bar stuff + data.html_text = text + data.color = bg_col + data.border = bg_col + return data + +proc main() = + let zones = getThermalZones() + let temp = getAverageTemp(zones) + let data = getObject(temp) + let option = outputData(data) + if option == data.full_text: + # Refresh + main() + +if isMainModule: + main() diff --git a/temperature/temperature.nimble b/temperature/temperature.nimble new file mode 100644 index 0000000..51ad626 --- /dev/null +++ b/temperature/temperature.nimble @@ -0,0 +1,13 @@ +# Package + +version = "0.1.0" +author = "Paul Wilde" +description = "Display temp in dmenu" +license = "GPL-3.0-or-later" +srcDir = "src" +bin = @["temperature"] + + +# Dependencies + +requires "nim >= 1.6.6" diff --git a/tides/nim.cfg b/tides/nim.cfg new file mode 100644 index 0000000..521e21d --- /dev/null +++ b/tides/nim.cfg @@ -0,0 +1 @@ +-d:ssl diff --git a/tides/src/tides.nim b/tides/src/tides.nim new file mode 100644 index 0000000..88be21b --- /dev/null +++ b/tides/src/tides.nim @@ -0,0 +1,106 @@ +#curl https://www.tidetimes.org.uk/exmouth-dock-tide-times-20190101 | grep -E -o ">((High|Low)|([0-9]+:[0-9]+)|([0-9]+\.[0-9]+m))" +import ../../base +import std/[re,httpclient,times,osproc,sequtils] + +# TODO: +# Pass location in as variable + +const url* = "https://www.tidetimes.org.uk/%LOC-tide-times" +const loc* = "exmouth-dock" +const icon: string = "🌊 " + +type + Tide = ref object + State: string + Time: string + Height: string + Tomorrow: bool + TideList = ref object + Tides: seq[Tide] + LastUpdated: DateTime + +proc sortTides(tides: seq[Tide], is_tomorrow: bool = false): seq[Tide] = + let timenow = now() + var reltides: seq[Tide] + for tide in tides: + if timenow.format("HH:MM") <= tide.Time and not is_tomorrow: + reltides.add(tide) + elif is_tomorrow: + reltides.add(tide) + return reltides + + +proc getTideData(get_tomorrow: bool = false): seq[Tide] = + var tides: seq[Tide] + let fnd = re">((High|Low)|([0-9]+:[0-9]+)|([0-9]+\.[0-9]+m))" + var client = newHttpClient() + var link = replace(url,re"\%LOC",loc) + if get_tomorrow: + let tomdate = now() + initTimeInterval(days = 1) + link &= "-" & tomdate.format("yyyyMMdd") + try: + # Remember to compile with -d:ssl else this won't work + let data = client.getContent(link) + let times = findAll(data,fnd) + var tide: Tide + var column = 0 + for idx,time in times: + if idx == 12: + break + let l = len(time) - 1 + if time == ">High" or time == ">Low": + tide = Tide() + tide.State = time[1..l] + column = 1 + continue + elif column == 1: + tide.Time = time[1..l] + column = 2 + continue + elif column == 2: + tide.Height = time[1..l] + tides.add(tide) + column = 0 + continue + except: + echo "Unable to get Tide Data : " & getCurrentExceptionMsg() + return tides + +proc getDesign(tides: seq[Tide]): Info = + var my_tides: seq[string] = @[] + for tide in tides: + let str = icon & tide.State[0] & " " & tide.Time & " " & tide.Height + my_tides.add(str) + var data = newInfo("Tides") + data.border = black + data.args = my_tides + return data + +proc getTides*(get_tomorrow: bool = false) = + var mytides = TideList() + mytides.Tides = getTideData(get_tomorrow) + mytides.Tides = sortTides(mytides.Tides, get_tomorrow) + if len(mytides.Tides) == 0: + getTides(true) + return + let data = getDesign(mytides.Tides) + var opt_tomorrow = "tomorrow" + if get_tomorrow: + opt_tomorrow = "back" + let args = concat(data.args,@["---",opt_tomorrow]) + let output = outputData(data,args) + if output == "tomorrow": + getTides(true) + elif output == "back": + getTides() + elif output == "---": + return + elif output in args: + let url = replace(url,re"\%LOC",loc) + discard execCmd("xdg-open " & url) + +proc main() = + getTides() + +if isMainModule: + main() diff --git a/tides/tides.nimble b/tides/tides.nimble new file mode 100644 index 0000000..78276fb --- /dev/null +++ b/tides/tides.nimble @@ -0,0 +1,13 @@ +# Package + +version = "0.1.0" +author = "Paul Wilde" +description = "Display local tides in dmenu" +license = "GPL-3.0-or-later" +srcDir = "src" +bin = @["tides"] + + +# Dependencies + +requires "nim >= 1.6.6" diff --git a/translate/nim.cfg b/translate/nim.cfg new file mode 100644 index 0000000..521e21d --- /dev/null +++ b/translate/nim.cfg @@ -0,0 +1 @@ +-d:ssl diff --git a/translate/src/translate.nim b/translate/src/translate.nim new file mode 100644 index 0000000..8b50e3a --- /dev/null +++ b/translate/src/translate.nim @@ -0,0 +1,126 @@ +import ../../base +import std/[re,httpclient,json,strutils,tables] + + +# TODO: +# Query available languages, maybe have selection panel +# Maybe store last used so future translations are more fluent + +const LIBRETRANSLATE_URL = "https://libretranslate.pussthecat.org/" +const HOME = "en" +let LANG_RE = re"\w+>\w+" +let DETECT_RE = re"\bd(etect)?\b" +var current = @["de",HOME] +var detected = {"detected":"0","confidence":"0","language":"en"}.toTable + +type + Request = object + source: string + target: string + q: string + format: string + +proc main(messages: varargs[string] = @[]) + +proc newRequest(): Request = + return Request(source:current[0], + target:current[1], + q: "", + format: "text",) + +proc parseReq(req: string): Request = + var langs = findAll(req,LANG_RE) + var r = newRequest() + let query = replace(req,LANG_RE,"") + r.q = query + if len(langs) > 0: + let lang = langs[0] + langs = lang.split(re">") + current[0] = langs[0].toLowerAscii() + current[1] = langs[1].toLowerAscii() + r.source = current[0].toLowerAscii() + r.target = current[1].toLowerAscii() + if query == "": + main() + return r + +proc answerTranslate(response: string, req: Request) = + let r = parseJson(response) + try: + let ans = r["translatedText"].getStr() + main(ans) + except: + main("Error : " & r["error"].getStr()) + +proc goTranslate(req: string) = + let r = parseReq(req) + if r.q != "": + var client = newHTTPClient() + client.headers = newHttpHeaders({"Content-Type":"application/json"}) + let body = %*r + let response = client.request(LIBRETRANSLATE_URL & "translate", httpMethod = HttpPost, body = $body) + if response.status != "": + answerTranslate(response.body, r) + +proc flipCurrent() = + current = @[current[1],current[0]] + main() + +proc detectLanguage(str: string) = + let term = replace(str,DETECT_RE,"") + echo "detecting ", term + if term != "": + var client = newHTTPClient() + client.headers = newHttpHeaders({"Content-Type":"application/json"}) + let body = %*Request(q:term) + let response = client.request(LIBRETRANSLATE_URL & "detect", httpMethod = HttpPost, body = $body) + if response.status != "": + let r = parseJson(response.body) + echo r + try: + detected["confidence"] = $r[0]["confidence"].getFloat() + detected["language"] = r[0]["language"].getStr() + detected["detected"] = "1" + current[0] = detected["language"] + current[1] = HOME + goTranslate(term) + except: + try: + main("Error : " & r["error"].getStr()) + except: + main("Error Parsing Json") + return + +proc main(messages:varargs[string] = @[]) = + var info = newInfo("Translate") + info.selected_bg = green + var args: seq[string] = @[] + for msg in messages: + if msg != "": + args.add(msg) + args.add(current[0] & " > " & current[1]) + if detected["detected"] == "1": + args.add("detected language : " & detected["language"]) + args.add("detected confidence : " & detected["confidence"]) + detected["detected"] = "0" + if len(messages) > 0: + args.add("back") + args.add("exit") + let output = outputData(info,args) + if output == "exit" or output == "": + return + elif output == "back": + main() + elif output == current[0] & " > " & current[1]: + flipCurrent() + elif re.startsWith(output,DETECT_RE): + detectLanguage(output) + elif output in messages: + copyToClipboard(output) + else: + goTranslate(output) + return + +if isMainModule: + main() + diff --git a/translate/translate.nimble b/translate/translate.nimble new file mode 100644 index 0000000..69bff6f --- /dev/null +++ b/translate/translate.nimble @@ -0,0 +1,13 @@ +# Package + +version = "0.1.0" +author = "Paul Wilde" +description = "Query libretranslate with dmenu" +license = "GPL-3.0-or-later" +srcDir = "src" +bin = @["translate"] + + +# Dependencies + +requires "nim >= 1.6.6" diff --git a/volume/src/volume.nim b/volume/src/volume.nim new file mode 100644 index 0000000..9c568d6 --- /dev/null +++ b/volume/src/volume.nim @@ -0,0 +1,126 @@ +import ../../base +import std/[os,strutils,sequtils,osproc] + +const audio_tools = @["ncpamixer", "pavucontrol"] +const vol_cmd = "pamixer" +const vol_up = vol_cmd & " -i %v" # where %v is amount by +const vol_down = vol_cmd & " -d %v" # where %v is amount by +const vol_set = vol_cmd & " --set-volume %v" # where %v is amount by +const vol_mute = vol_cmd & " -t" +const vol_default_by = "5" +const vol_get = vol_cmd & " --get-volume" +const vol_get_mute = vol_cmd & " --get-mute" +const default_bg = green +const default_fg = black + + +proc getCurrentVolume(): string {.gcsafe.} + +proc checkVolume(volume: string): string = + var vol = volume + if strip(vol) == "Connection error": + sleep(1000) + vol = getCurrentVolume() + vol = checkVolume(vol) + return vol + +proc getDesign(volume: string): (string,string) = + let vol = checkVolume(volume) + var icon = " " + if vol == "muted": + return (icon & "muted", icon & "muted") + let pcnt = parseInt(strip(vol)) + case pcnt: + of 85..100: + icon = " " + of 55..84: + icon = " " + of 35..54: + icon = " " + of 10..34: + icon = " " + else: + icon = " " + let main_text = icon & $pcnt & "%" + let text = "" & icon & "" & $pcnt & "%" + return (text, main_text) + +proc getCurrentVolume(): string = + let mute = execCmdEx(vol_get_mute) + if strip(mute.output) == "true": + return "muted" + let vol = execCmdEx(vol_get) + return vol.output + +proc volumeUp() = + let cmd = replace(vol_up, "%v", vol_default_by) + discard execCmd(cmd) + +proc volumeDown() = + let cmd = replace(vol_down, "%v", vol_default_by) + discard execCmd(cmd) + +proc volumeMute() = + discard execCmd(vol_mute) + +proc getVolume*(run_once: bool = false) = + let vol = getCurrentVolume() + let (text, main_text) = getDesign(vol) + var data = newInfo("Volume") + data.full_text = main_text + data.selected_bg = default_bg + data.selected_fg = default_fg + # i3bar stuff + data.html_text = text + data.color = foreground + data.border = green + data.background = black + let args = concat(@["up", "down", "mute", "---", "exit", "---"],audio_tools) + let option = outputData(data,args) + if option == "": + return + elif option in args: + if option in audio_tools: + discard(execCmd(option)) + return + case option: + of "up": + volumeUp() + getVolume() + of "down": + volumeDown() + getVolume() + of "mute": + volumeMute() + getVolume() + of "---": + getVolume() + of "exit": + return + else: + try: + let vol = parseInt(option) + let cmd = replace(vol_set, "%v", $vol) + let x = execCmd(cmd) + getVolume() + except: + echo getCurrentExceptionMsg() + getVolume() + +proc main() = + getVolume() + +if isMainModule: + block start: + for arg in args: + case arg: + of "up": + volumeUp() + break start + of "down": + volumeDown() + break start + of "mute": + volumeMute() + break start + main() diff --git a/volume/volume.nimble b/volume/volume.nimble new file mode 100644 index 0000000..366bb29 --- /dev/null +++ b/volume/volume.nimble @@ -0,0 +1,13 @@ +# Package + +version = "0.1.0" +author = "Paul Wilde" +description = "Display and control volume with dmenu" +license = "GPL-3.0-or-later" +srcDir = "src" +bin = @["volume"] + + +# Dependencies + +requires "nim >= 1.6.6" diff --git a/wlan/src/wlan.nim b/wlan/src/wlan.nim new file mode 100644 index 0000000..a7ebc51 --- /dev/null +++ b/wlan/src/wlan.nim @@ -0,0 +1,64 @@ +import ../../base +import std/[os,osproc,strutils,sequtils] + +const default_bg = purple +const default_fg = white +const wlan_nics: seq[string] = @["wlan0"] +const get_ssid_cmd = "iwgetid -r" +const mng_cmd = "alacritty -e nmtui-connect" + +proc getSsid(): string = + let ssid = execCmdEx(get_ssid_cmd) + return strip(ssid.output) + +proc getSignalQuality(): string = + let wl = readFile("/proc/net/wireless") + let ln = splitLines(wl)[2] + let links = split(ln," ") + var qual = strip(links[1]) + qual = replace(qual,".","") + return "[" & qual & "]" + +proc getWifi(nic: string): (string, string) = + let ssid = getSsid() + if ssid == "": + return ("disconnected", "disconnected") + let quality = getSignalQuality() + return (ssid, quality) + +proc getObject(): Info = + var data = newInfo("WiFi") + data.border = purple + data.selected_bg = default_bg + data.selected_fg = default_fg + return data + +proc getWifiInfo*(nics: seq[string]) = + var lst: seq[string] = @[] + for nic in nics: + let (essid, quality) = getWifi(nic) + lst.add(nic & ":" & quality & " " & essid) + let data = getObject() + let args = concat(lst,@["---", "manage","exit"]) + let output = outputData(data, args) + case output: + of "manage": + discard execCmd(mng_cmd) + of "exit": + return + of "---": + return + +proc main() = + var my_nics: seq[string] = @[] + for nic in wlan_nics: + if dirExists("/sys/class/net/" & nic): + my_nics.add(nic) + if len(my_nics) > 0: + getWifiInfo(my_nics) + else: + switchTwmMode() + echo "No WLAN" + +if isMainModule: + main() diff --git a/wlan/wlan.nimble b/wlan/wlan.nimble new file mode 100644 index 0000000..4f45963 --- /dev/null +++ b/wlan/wlan.nimble @@ -0,0 +1,13 @@ +# Package + +version = "0.1.0" +author = "Paul Wilde" +description = "Display and control WLAN state with dmenu" +license = "GPL-3.0-or-later" +srcDir = "src" +bin = @["wlan"] + + +# Dependencies + +requires "nim >= 1.6.6"