summaryrefslogtreecommitdiff
path: root/test/lisp
diff options
context:
space:
mode:
Diffstat (limited to 'test/lisp')
-rw-r--r--test/lisp/abbrev-tests.el64
-rw-r--r--test/lisp/ansi-color-tests.el112
-rw-r--r--test/lisp/auth-source-tests.el178
-rw-r--r--test/lisp/autoinsert-tests.el19
-rw-r--r--test/lisp/autorevert-tests.el865
-rw-r--r--test/lisp/bookmark-tests.el56
-rw-r--r--test/lisp/buff-menu-tests.el21
-rw-r--r--test/lisp/button-tests.el8
-rw-r--r--test/lisp/calc/calc-tests.el8
-rw-r--r--test/lisp/calendar/icalendar-tests.el140
-rw-r--r--test/lisp/calendar/iso8601-tests.el20
-rw-r--r--test/lisp/calendar/time-date-tests.el33
-rw-r--r--test/lisp/calendar/todo-mode-tests.el37
-rw-r--r--test/lisp/cedet/cedet-files-tests.el17
-rw-r--r--test/lisp/cedet/semantic-utest-ia-resources/teststruct.cpp2
-rw-r--r--test/lisp/cedet/semantic/bovine/gcc-tests.el12
-rw-r--r--test/lisp/cedet/srecode-utest-template.el2
-rw-r--r--test/lisp/cedet/srecode/document-tests.el2
-rw-r--r--test/lisp/cedet/srecode/fields-tests.el23
-rw-r--r--test/lisp/color-tests.el14
-rw-r--r--test/lisp/comint-tests.el1
-rw-r--r--test/lisp/cus-edit-tests.el9
-rw-r--r--test/lisp/custom-tests.el38
-rw-r--r--test/lisp/desktop-tests.el50
-rw-r--r--test/lisp/dired-aux-tests.el62
-rw-r--r--test/lisp/dired-resources/insert-directory/test_dir/bar0
-rw-r--r--test/lisp/dired-resources/insert-directory/test_dir/foo0
-rw-r--r--test/lisp/dired-resources/insert-directory/test_dir_other/bar0
-rw-r--r--test/lisp/dired-resources/insert-directory/test_dir_other/foo0
-rw-r--r--test/lisp/dired-tests.el439
-rw-r--r--test/lisp/dired-x-tests.el40
-rw-r--r--test/lisp/dnd-tests.el441
-rw-r--r--test/lisp/edmacro-tests.el48
-rw-r--r--test/lisp/electric-tests.el24
-rw-r--r--test/lisp/elide-head-tests.el191
-rw-r--r--test/lisp/emacs-lisp/backtrace-tests.el2
-rw-r--r--test/lisp/emacs-lisp/bindat-tests.el140
-rw-r--r--test/lisp/emacs-lisp/bytecomp-resources/fun-attr-warn.el266
-rw-r--r--test/lisp/emacs-lisp/bytecomp-resources/no-byte-compile.el1
-rw-r--r--test/lisp/emacs-lisp/bytecomp-resources/warn-variable-setq-nonvariable.el3
-rw-r--r--test/lisp/emacs-lisp/bytecomp-resources/warn-variable-setq-odd.el3
-rw-r--r--test/lisp/emacs-lisp/bytecomp-resources/warn-wide-docstring-ignore-substitutions.el17
-rw-r--r--test/lisp/emacs-lisp/bytecomp-tests.el351
-rw-r--r--test/lisp/emacs-lisp/cconv-tests.el168
-rw-r--r--test/lisp/emacs-lisp/check-declare-tests.el96
-rw-r--r--test/lisp/emacs-lisp/cl-generic-tests.el11
-rw-r--r--test/lisp/emacs-lisp/cl-lib-tests.el12
-rw-r--r--test/lisp/emacs-lisp/cl-macs-tests.el75
-rw-r--r--test/lisp/emacs-lisp/copyright-tests.el20
-rw-r--r--test/lisp/emacs-lisp/derived-tests.el25
-rw-r--r--test/lisp/emacs-lisp/easy-mmode-tests.el2
-rw-r--r--test/lisp/emacs-lisp/edebug-tests.el90
-rw-r--r--test/lisp/emacs-lisp/eieio-tests/eieio-test-methodinvoke.el286
-rw-r--r--test/lisp/emacs-lisp/eieio-tests/eieio-test-persist.el2
-rw-r--r--test/lisp/emacs-lisp/eieio-tests/eieio-tests.el536
-rw-r--r--test/lisp/emacs-lisp/ert-tests.el170
-rw-r--r--test/lisp/emacs-lisp/ert-x-tests.el108
-rw-r--r--test/lisp/emacs-lisp/find-func-tests.el7
-rw-r--r--test/lisp/emacs-lisp/generator-tests.el11
-rw-r--r--test/lisp/emacs-lisp/gv-tests.el19
-rw-r--r--test/lisp/emacs-lisp/let-alist-tests.el2
-rw-r--r--test/lisp/emacs-lisp/lisp-tests.el5
-rw-r--r--test/lisp/emacs-lisp/macroexp-resources/m1.el10
-rw-r--r--test/lisp/emacs-lisp/macroexp-resources/m2.el10
-rw-r--r--test/lisp/emacs-lisp/macroexp-resources/vk.el130
-rw-r--r--test/lisp/emacs-lisp/macroexp-tests.el67
-rw-r--r--test/lisp/emacs-lisp/map-tests.el15
-rw-r--r--test/lisp/emacs-lisp/multisession-tests.el207
-rw-r--r--test/lisp/emacs-lisp/nadvice-tests.el17
-rw-r--r--test/lisp/emacs-lisp/oclosure-tests.el166
-rw-r--r--test/lisp/emacs-lisp/package-resources/macro-builtin-package-1.0/macro-builtin-aux.el12
-rw-r--r--test/lisp/emacs-lisp/package-resources/macro-builtin-package-1.0/macro-builtin.el21
-rw-r--r--test/lisp/emacs-lisp/package-resources/macro-builtin-package-2.0/macro-builtin-aux.el16
-rw-r--r--test/lisp/emacs-lisp/package-resources/macro-builtin-package-2.0/macro-builtin.el30
-rw-r--r--test/lisp/emacs-lisp/package-tests.el168
-rw-r--r--test/lisp/emacs-lisp/pcase-tests.el7
-rw-r--r--test/lisp/emacs-lisp/pp-resources/code-formats.erts142
-rw-r--r--test/lisp/emacs-lisp/pp-tests.el4
-rw-r--r--test/lisp/emacs-lisp/range-tests.el65
-rw-r--r--test/lisp/emacs-lisp/ring-tests.el2
-rw-r--r--test/lisp/emacs-lisp/rmc-tests.el54
-rw-r--r--test/lisp/emacs-lisp/seq-tests.el43
-rw-r--r--test/lisp/emacs-lisp/shortdoc-tests.el11
-rw-r--r--test/lisp/emacs-lisp/subr-x-tests.el162
-rw-r--r--test/lisp/emacs-lisp/testcover-resources/testcases.el2
-rw-r--r--test/lisp/emacs-lisp/testcover-tests.el108
-rw-r--r--test/lisp/emacs-lisp/text-property-search-tests.el25
-rw-r--r--test/lisp/emacs-lisp/timer-tests.el3
-rw-r--r--test/lisp/emacs-lisp/vtable-tests.el42
-rw-r--r--test/lisp/emulation/viper-tests.el80
-rw-r--r--test/lisp/epg-tests.el77
-rw-r--r--test/lisp/erc/erc-dcc-tests.el167
-rw-r--r--test/lisp/erc/erc-join-tests.el361
-rw-r--r--test/lisp/erc/erc-networks-tests.el1707
-rw-r--r--test/lisp/erc/erc-scenarios-auth-source.el178
-rw-r--r--test/lisp/erc/erc-scenarios-base-association-nick.el163
-rw-r--r--test/lisp/erc/erc-scenarios-base-association-samenet.el144
-rw-r--r--test/lisp/erc/erc-scenarios-base-association.el192
-rw-r--r--test/lisp/erc/erc-scenarios-base-compat-rename-bouncer.el171
-rw-r--r--test/lisp/erc/erc-scenarios-base-misc-regressions.el126
-rw-r--r--test/lisp/erc/erc-scenarios-base-netid-bouncer-id.el34
-rw-r--r--test/lisp/erc/erc-scenarios-base-netid-bouncer-recon-base.el30
-rw-r--r--test/lisp/erc/erc-scenarios-base-netid-bouncer-recon-both.el32
-rw-r--r--test/lisp/erc/erc-scenarios-base-netid-bouncer-recon-id.el35
-rw-r--r--test/lisp/erc/erc-scenarios-base-netid-bouncer.el35
-rw-r--r--test/lisp/erc/erc-scenarios-base-netid-samenet.el147
-rw-r--r--test/lisp/erc/erc-scenarios-base-reconnect.el226
-rw-r--r--test/lisp/erc/erc-scenarios-base-renick.el305
-rw-r--r--test/lisp/erc/erc-scenarios-base-reuse-buffers.el238
-rw-r--r--test/lisp/erc/erc-scenarios-base-unstable.el134
-rw-r--r--test/lisp/erc/erc-scenarios-base-upstream-recon-soju.el43
-rw-r--r--test/lisp/erc/erc-scenarios-base-upstream-recon-znc.el43
-rw-r--r--test/lisp/erc/erc-scenarios-internal.el27
-rw-r--r--test/lisp/erc/erc-scenarios-join-auth-source.el67
-rw-r--r--test/lisp/erc/erc-scenarios-join-netid-newcmd-id.el50
-rw-r--r--test/lisp/erc/erc-scenarios-join-netid-newcmd.el37
-rw-r--r--test/lisp/erc/erc-scenarios-join-netid-recon-id.el46
-rw-r--r--test/lisp/erc/erc-scenarios-join-netid-recon.el36
-rw-r--r--test/lisp/erc/erc-scenarios-misc.el141
-rw-r--r--test/lisp/erc/erc-scenarios-services-misc.el86
-rw-r--r--test/lisp/erc/erc-services-tests.el574
-rw-r--r--test/lisp/erc/erc-tests.el681
-rw-r--r--test/lisp/erc/resources/base/assoc/bouncer-history/barnet.eld44
-rw-r--r--test/lisp/erc/resources/base/assoc/bouncer-history/foonet.eld48
-rw-r--r--test/lisp/erc/resources/base/assoc/bumped/again.eld30
-rw-r--r--test/lisp/erc/resources/base/assoc/bumped/foisted.eld30
-rw-r--r--test/lisp/erc/resources/base/assoc/bumped/refoisted.eld31
-rw-r--r--test/lisp/erc/resources/base/assoc/bumped/renicked.eld30
-rw-r--r--test/lisp/erc/resources/base/assoc/multi-net/barnet.eld42
-rw-r--r--test/lisp/erc/resources/base/assoc/multi-net/foonet.eld45
-rw-r--r--test/lisp/erc/resources/base/assoc/reconplay/again.eld42
-rw-r--r--test/lisp/erc/resources/base/assoc/reconplay/foonet.eld52
-rw-r--r--test/lisp/erc/resources/base/assoc/samenet/chester.eld40
-rw-r--r--test/lisp/erc/resources/base/assoc/samenet/tester.eld42
-rw-r--r--test/lisp/erc/resources/base/assoc/samenet/tester2.eld39
-rw-r--r--test/lisp/erc/resources/base/auth-source/foonet.eld23
-rw-r--r--test/lisp/erc/resources/base/auth-source/nopass.eld22
-rw-r--r--test/lisp/erc/resources/base/channel-buffer-revival/foonet.eld45
-rw-r--r--test/lisp/erc/resources/base/flood/soju.eld87
-rw-r--r--test/lisp/erc/resources/base/gapless-connect/barnet.eld40
-rw-r--r--test/lisp/erc/resources/base/gapless-connect/foonet.eld41
-rw-r--r--test/lisp/erc/resources/base/gapless-connect/pass-stub.eld4
-rw-r--r--test/lisp/erc/resources/base/mask-target-routing/foonet.eld45
-rw-r--r--test/lisp/erc/resources/base/netid/bouncer/barnet-again.eld50
-rw-r--r--test/lisp/erc/resources/base/netid/bouncer/barnet-drop.eld41
-rw-r--r--test/lisp/erc/resources/base/netid/bouncer/barnet.eld41
-rw-r--r--test/lisp/erc/resources/base/netid/bouncer/foonet-again.eld50
-rw-r--r--test/lisp/erc/resources/base/netid/bouncer/foonet-drop.eld46
-rw-r--r--test/lisp/erc/resources/base/netid/bouncer/foonet.eld46
-rw-r--r--test/lisp/erc/resources/base/netid/bouncer/stub-again.eld4
-rw-r--r--test/lisp/erc/resources/base/netid/samenet/chester.eld48
-rw-r--r--test/lisp/erc/resources/base/netid/samenet/tester.eld52
-rw-r--r--test/lisp/erc/resources/base/reconnect/aborted-dupe.eld28
-rw-r--r--test/lisp/erc/resources/base/reconnect/aborted.eld45
-rw-r--r--test/lisp/erc/resources/base/reconnect/options-again.eld45
-rw-r--r--test/lisp/erc/resources/base/reconnect/options.eld35
-rw-r--r--test/lisp/erc/resources/base/reconnect/timer-last.eld6
-rw-r--r--test/lisp/erc/resources/base/reconnect/timer.eld6
-rw-r--r--test/lisp/erc/resources/base/renick/queries/bouncer-barnet.eld54
-rw-r--r--test/lisp/erc/resources/base/renick/queries/bouncer-foonet.eld52
-rw-r--r--test/lisp/erc/resources/base/renick/queries/solo.eld55
-rw-r--r--test/lisp/erc/resources/base/renick/self/auto.eld46
-rw-r--r--test/lisp/erc/resources/base/renick/self/manual.eld50
-rw-r--r--test/lisp/erc/resources/base/renick/self/qual-chester.eld40
-rw-r--r--test/lisp/erc/resources/base/renick/self/qual-tester.eld46
-rw-r--r--test/lisp/erc/resources/base/reuse-buffers/channel/barnet.eld68
-rw-r--r--test/lisp/erc/resources/base/reuse-buffers/channel/foonet.eld66
-rw-r--r--test/lisp/erc/resources/base/reuse-buffers/server/barnet.eld24
-rw-r--r--test/lisp/erc/resources/base/reuse-buffers/server/foonet.eld24
-rw-r--r--test/lisp/erc/resources/base/upstream-reconnect/soju-barnet.eld64
-rw-r--r--test/lisp/erc/resources/base/upstream-reconnect/soju-foonet.eld72
-rw-r--r--test/lisp/erc/resources/base/upstream-reconnect/znc-barnet.eld93
-rw-r--r--test/lisp/erc/resources/base/upstream-reconnect/znc-foonet.eld86
-rw-r--r--test/lisp/erc/resources/erc-d/erc-d-i.el124
-rw-r--r--test/lisp/erc/resources/erc-d/erc-d-t.el170
-rw-r--r--test/lisp/erc/resources/erc-d/erc-d-tests.el1346
-rw-r--r--test/lisp/erc/resources/erc-d/erc-d-u.el213
-rw-r--r--test/lisp/erc/resources/erc-d/erc-d.el997
-rw-r--r--test/lisp/erc/resources/erc-d/resources/basic.eld32
-rw-r--r--test/lisp/erc/resources/erc-d/resources/depleted.eld12
-rw-r--r--test/lisp/erc/resources/erc-d/resources/drop-a.eld4
-rw-r--r--test/lisp/erc/resources/erc-d/resources/drop-b.eld4
-rw-r--r--test/lisp/erc/resources/erc-d/resources/dynamic-barnet.eld33
-rw-r--r--test/lisp/erc/resources/erc-d/resources/dynamic-foonet.eld32
-rw-r--r--test/lisp/erc/resources/erc-d/resources/dynamic-stub.eld4
-rw-r--r--test/lisp/erc/resources/erc-d/resources/dynamic.eld30
-rw-r--r--test/lisp/erc/resources/erc-d/resources/eof.eld33
-rw-r--r--test/lisp/erc/resources/erc-d/resources/fuzzy.eld42
-rw-r--r--test/lisp/erc/resources/erc-d/resources/incremental.eld43
-rw-r--r--test/lisp/erc/resources/erc-d/resources/irc-parser-tests.eld380
-rw-r--r--test/lisp/erc/resources/erc-d/resources/linger-multi-a.eld3
-rw-r--r--test/lisp/erc/resources/erc-d/resources/linger-multi-b.eld3
-rw-r--r--test/lisp/erc/resources/erc-d/resources/linger.eld33
-rw-r--r--test/lisp/erc/resources/erc-d/resources/no-block.eld55
-rw-r--r--test/lisp/erc/resources/erc-d/resources/no-match.eld32
-rw-r--r--test/lisp/erc/resources/erc-d/resources/no-pong.eld27
-rw-r--r--test/lisp/erc/resources/erc-d/resources/nonstandard.eld6
-rw-r--r--test/lisp/erc/resources/erc-d/resources/proxy-barnet.eld24
-rw-r--r--test/lisp/erc/resources/erc-d/resources/proxy-foonet.eld24
-rw-r--r--test/lisp/erc/resources/erc-d/resources/proxy-solo.eld9
-rw-r--r--test/lisp/erc/resources/erc-d/resources/proxy-subprocess.el45
-rw-r--r--test/lisp/erc/resources/erc-d/resources/timeout.eld27
-rw-r--r--test/lisp/erc/resources/erc-d/resources/unexpected.eld28
-rw-r--r--test/lisp/erc/resources/erc-scenarios-common.el516
-rw-r--r--test/lisp/erc/resources/join/auth-source/foonet.eld33
-rw-r--r--test/lisp/erc/resources/join/legacy/foonet.eld38
-rw-r--r--test/lisp/erc/resources/join/network-id/barnet.eld43
-rw-r--r--test/lisp/erc/resources/join/network-id/foonet-again.eld46
-rw-r--r--test/lisp/erc/resources/join/network-id/foonet.eld39
-rw-r--r--test/lisp/erc/resources/join/reconnect/foonet-again.eld45
-rw-r--r--test/lisp/erc/resources/join/reconnect/foonet.eld45
-rw-r--r--test/lisp/erc/resources/networks/announced-missing/foonet.eld8
-rw-r--r--test/lisp/erc/resources/services/auth-source/libera.eld49
-rw-r--r--test/lisp/erc/resources/services/password/libera.eld49
-rw-r--r--test/lisp/eshell/em-alias-tests.el87
-rw-r--r--test/lisp/eshell/em-basic-tests.el71
-rw-r--r--test/lisp/eshell/em-dirs-tests.el102
-rw-r--r--test/lisp/eshell/em-extpipe-tests.el205
-rw-r--r--test/lisp/eshell/em-glob-tests.el197
-rw-r--r--test/lisp/eshell/em-hist-tests.el17
-rw-r--r--test/lisp/eshell/em-ls-tests.el38
-rw-r--r--test/lisp/eshell/em-pred-tests.el566
-rw-r--r--test/lisp/eshell/em-script-tests.el62
-rw-r--r--test/lisp/eshell/em-tramp-tests.el88
-rw-r--r--test/lisp/eshell/esh-opt-tests.el289
-rw-r--r--test/lisp/eshell/esh-proc-tests.el96
-rw-r--r--test/lisp/eshell/esh-var-tests.el547
-rw-r--r--test/lisp/eshell/eshell-tests-helpers.el97
-rw-r--r--test/lisp/eshell/eshell-tests.el194
-rw-r--r--test/lisp/ffap-tests.el50
-rw-r--r--test/lisp/filenotify-tests.el73
-rw-r--r--test/lisp/files-resources/compile-utf8.el12
-rw-r--r--test/lisp/files-resources/file-mode3
-rw-r--r--test/lisp/files-resources/file-mode-multiple5
-rw-r--r--test/lisp/files-resources/file-mode-prop-line1
-rw-r--r--test/lisp/files-tests.el455
-rw-r--r--test/lisp/files-x-tests.el18
-rw-r--r--test/lisp/format-spec-tests.el4
-rw-r--r--test/lisp/gnus/gnus-group-tests.el52
-rw-r--r--test/lisp/gnus/gnus-icalendar-tests.el2
-rw-r--r--test/lisp/gnus/mml-sec-tests.el3
-rw-r--r--test/lisp/help-fns-tests.el14
-rw-r--r--test/lisp/help-mode-tests.el7
-rw-r--r--test/lisp/help-tests.el228
-rw-r--r--test/lisp/hi-lock-tests.el14
-rw-r--r--test/lisp/hl-line-tests.el114
-rw-r--r--test/lisp/htmlfontify-tests.el9
-rw-r--r--test/lisp/ibuffer-tests.el4
-rw-r--r--test/lisp/image-dired-tests.el37
-rw-r--r--test/lisp/image-tests.el83
-rw-r--r--test/lisp/image/exif-tests.el21
-rw-r--r--test/lisp/info-tests.el39
-rw-r--r--test/lisp/info-xref-tests.el80
-rw-r--r--test/lisp/international/textsec-tests.el214
-rw-r--r--test/lisp/isearch-tests.el80
-rw-r--r--test/lisp/json-tests.el4
-rw-r--r--test/lisp/kmacro-tests.el66
-rw-r--r--test/lisp/loadhist-resources/loadhist--bar.el27
-rw-r--r--test/lisp/loadhist-resources/loadhist--foo.el29
-rw-r--r--test/lisp/loadhist-tests.el47
-rw-r--r--test/lisp/ls-lisp-tests.el75
-rw-r--r--test/lisp/mail/ietf-drums-date-tests.el172
-rw-r--r--test/lisp/mail/ietf-drums-tests.el178
-rw-r--r--test/lisp/mail/mail-extr-tests.el41
-rw-r--r--test/lisp/mail/mail-utils-tests.el3
-rw-r--r--test/lisp/mail/undigest-tests.el359
-rw-r--r--test/lisp/mail/uudecode-tests.el26
-rw-r--r--test/lisp/mh-e/mh-thread-tests.el131
-rw-r--r--test/lisp/mh-e/mh-utils-tests.el116
-rwxr-xr-xtest/lisp/mh-e/test-all-mh-variants.sh6
-rw-r--r--test/lisp/minibuffer-tests.el136
-rw-r--r--test/lisp/misc-tests.el25
-rw-r--r--test/lisp/mouse-tests.el176
-rw-r--r--test/lisp/net/browse-url-tests.el21
-rw-r--r--test/lisp/net/gnutls-tests.el8
-rw-r--r--test/lisp/net/mailcap-resources/mailcap9
-rw-r--r--test/lisp/net/mailcap-resources/test.test1
-rw-r--r--test/lisp/net/mailcap-tests.el70
-rw-r--r--test/lisp/net/netrc-tests.el2
-rw-r--r--test/lisp/net/network-stream-tests.el2
-rw-r--r--test/lisp/net/ntlm-tests.el11
-rw-r--r--test/lisp/net/puny-resources/IdnaTestV2.txt6344
-rw-r--r--test/lisp/net/puny-tests.el13
-rw-r--r--test/lisp/net/secrets-tests.el11
-rw-r--r--test/lisp/net/shr-tests.el2
-rw-r--r--test/lisp/net/tramp-archive-tests.el57
-rw-r--r--test/lisp/net/tramp-resources/foo.tar.gzbin0 -> 274 bytes
-rw-r--r--test/lisp/net/tramp-tests.el1413
-rw-r--r--test/lisp/obsolete/cl-tests.el9
-rw-r--r--test/lisp/obsolete/inversion-tests.el1
-rw-r--r--test/lisp/paren-tests.el31
-rw-r--r--test/lisp/progmodes/autoconf-tests.el8
-rw-r--r--test/lisp/progmodes/bug-reference-tests.el128
-rw-r--r--test/lisp/progmodes/compile-tests.el6
-rw-r--r--test/lisp/progmodes/cperl-mode-resources/proto-and-attrs.pl50
-rw-r--r--test/lisp/progmodes/cperl-mode-tests.el54
-rw-r--r--test/lisp/progmodes/elisp-mode-resources/elisp-indents.erts88
-rw-r--r--test/lisp/progmodes/elisp-mode-resources/flet.erts353
-rw-r--r--test/lisp/progmodes/elisp-mode-resources/simple-shorthand-test.el2
-rw-r--r--test/lisp/progmodes/elisp-mode-tests.el89
-rw-r--r--test/lisp/progmodes/etags-tests.el31
-rw-r--r--test/lisp/progmodes/flymake-tests.el41
-rw-r--r--test/lisp/progmodes/perl-mode-tests.el2
-rw-r--r--test/lisp/progmodes/project-tests.el20
-rw-r--r--test/lisp/progmodes/python-tests.el509
-rw-r--r--test/lisp/progmodes/ruby-mode-resources/ruby.rb17
-rw-r--r--test/lisp/progmodes/ruby-mode-tests.el7
-rw-r--r--test/lisp/progmodes/sh-script-resources/sh-indents.erts40
-rw-r--r--test/lisp/progmodes/sh-script-tests.el21
-rw-r--r--test/lisp/progmodes/sql-tests.el180
-rw-r--r--test/lisp/repeat-tests.el24
-rw-r--r--test/lisp/replace-tests.el107
-rw-r--r--test/lisp/saveplace-tests.el67
-rw-r--r--test/lisp/ses-tests.el75
-rw-r--r--test/lisp/shadowfile-tests.el120
-rw-r--r--test/lisp/simple-tests.el59
-rw-r--r--test/lisp/so-long-tests/so-long-tests.el4
-rw-r--r--test/lisp/so-long-tests/spelling-tests.el42
-rw-r--r--test/lisp/subr-tests.el329
-rw-r--r--test/lisp/tar-mode-tests.el3
-rw-r--r--test/lisp/term-tests.el38
-rw-r--r--test/lisp/textmodes/css-mode-resources/css-selectors.txt56
-rw-r--r--test/lisp/textmodes/css-mode-resources/scss-selectors.txt10
-rw-r--r--test/lisp/textmodes/css-mode-tests.el69
-rw-r--r--test/lisp/textmodes/emacs-news-mode-resources/toggle-tag.erts131
-rw-r--r--test/lisp/textmodes/emacs-news-mode-tests.el32
-rw-r--r--test/lisp/textmodes/fill-tests.el22
-rw-r--r--test/lisp/textmodes/page-tests.el12
-rw-r--r--test/lisp/textmodes/reftex-tests.el101
-rw-r--r--test/lisp/textmodes/texinfo-resources/fill.erts70
-rw-r--r--test/lisp/textmodes/texinfo-tests.el33
-rw-r--r--test/lisp/thingatpt-tests.el10
-rw-r--r--test/lisp/thumbs-tests.el10
-rw-r--r--test/lisp/time-stamp-tests.el27
-rw-r--r--test/lisp/url/url-tramp-tests.el16
-rw-r--r--test/lisp/vc/diff-mode-tests.el56
-rw-r--r--test/lisp/vc/ediff-ptch-tests.el60
-rw-r--r--test/lisp/vc/vc-bzr-tests.el172
-rw-r--r--test/lisp/vc/vc-git-tests.el67
-rw-r--r--test/lisp/vc/vc-tests.el893
-rw-r--r--test/lisp/wdired-tests.el274
-rw-r--r--test/lisp/x-dnd-tests.el203
-rw-r--r--test/lisp/xml-tests.el2
-rw-r--r--test/lisp/yank-media-tests.el38
344 files changed, 34424 insertions, 4641 deletions
diff --git a/test/lisp/abbrev-tests.el b/test/lisp/abbrev-tests.el
index 95ffb4d2b04..947178473e4 100644
--- a/test/lisp/abbrev-tests.el
+++ b/test/lisp/abbrev-tests.el
@@ -28,6 +28,7 @@
;;; Code:
(require 'ert)
+(require 'ert-x)
(require 'abbrev)
(require 'seq)
@@ -236,44 +237,41 @@
(ert-deftest read-write-abbrev-file-test ()
"Test reading and writing abbrevs from file."
- (let ((temp-test-file (make-temp-file "ert-abbrev-test"))
- (ert-test-abbrevs (setup-test-abbrev-table)))
- (write-abbrev-file temp-test-file)
- (clear-abbrev-table ert-test-abbrevs)
- (should (abbrev-table-empty-p ert-test-abbrevs))
- (read-abbrev-file temp-test-file)
- (should (equal "abbrev-ert-test" (abbrev-expansion "a-e-t" ert-test-abbrevs)))
- (delete-file temp-test-file)))
+ (ert-with-temp-file temp-test-file
+ (let ((ert-test-abbrevs (setup-test-abbrev-table)))
+ (write-abbrev-file temp-test-file)
+ (clear-abbrev-table ert-test-abbrevs)
+ (should (abbrev-table-empty-p ert-test-abbrevs))
+ (read-abbrev-file temp-test-file)
+ (should (equal "abbrev-ert-test" (abbrev-expansion "a-e-t" ert-test-abbrevs))))))
(ert-deftest read-write-abbrev-file-test-with-props ()
"Test reading and writing abbrevs from file."
- (let ((temp-test-file (make-temp-file "ert-abbrev-test"))
- (ert-test-abbrevs (setup-test-abbrev-table-with-props)))
- (write-abbrev-file temp-test-file)
- (clear-abbrev-table ert-test-abbrevs)
- (should (abbrev-table-empty-p ert-test-abbrevs))
- (read-abbrev-file temp-test-file)
- (should (equal "fooBar" (abbrev-expansion "fb" ert-test-abbrevs)))
- (delete-file temp-test-file)))
+ (ert-with-temp-file temp-test-file
+ (let ((ert-test-abbrevs (setup-test-abbrev-table-with-props)))
+ (write-abbrev-file temp-test-file)
+ (clear-abbrev-table ert-test-abbrevs)
+ (should (abbrev-table-empty-p ert-test-abbrevs))
+ (read-abbrev-file temp-test-file)
+ (should (equal "fooBar" (abbrev-expansion "fb" ert-test-abbrevs))))))
(ert-deftest abbrev-edit-save-to-file-test ()
"Test saving abbrev definitions in buffer to file."
(defvar ert-save-test-table nil)
- (let ((temp-test-file (make-temp-file "ert-abbrev-test"))
- (ert-test-abbrevs (setup-test-abbrev-table)))
- (with-temp-buffer
- (goto-char (point-min))
- (insert "(ert-save-test-table)\n")
- (insert "\n" "\"s-a-t\"\t" "0\t" "\"save-abbrevs-test\"\n")
- (should (equal "abbrev-ert-test"
- (abbrev-expansion "a-e-t" ert-test-abbrevs)))
- ;; clears abbrev tables
- (abbrev-edit-save-to-file temp-test-file)
- (should-not (abbrev-expansion "a-e-t" ert-test-abbrevs))
- (read-abbrev-file temp-test-file)
- (should (equal "save-abbrevs-test"
- (abbrev-expansion "s-a-t" ert-save-test-table)))
- (delete-file temp-test-file))))
+ (ert-with-temp-file temp-test-file
+ (let ((ert-test-abbrevs (setup-test-abbrev-table)))
+ (with-temp-buffer
+ (goto-char (point-min))
+ (insert "(ert-save-test-table)\n")
+ (insert "\n" "\"s-a-t\"\t" "0\t" "\"save-abbrevs-test\"\n")
+ (should (equal "abbrev-ert-test"
+ (abbrev-expansion "a-e-t" ert-test-abbrevs)))
+ ;; clears abbrev tables
+ (abbrev-edit-save-to-file temp-test-file)
+ (should-not (abbrev-expansion "a-e-t" ert-test-abbrevs))
+ (read-abbrev-file temp-test-file)
+ (should (equal "save-abbrevs-test"
+ (abbrev-expansion "s-a-t" ert-save-test-table)))))))
(ert-deftest inverse-add-abbrev-skips-trailing-nonword ()
"Test that adding an inverse abbrev skips trailing nonword characters."
@@ -303,6 +301,10 @@
(inverse-add-abbrev table "Global" -1)))
(should (string= (abbrev-expansion "text" table) "bar"))))
+(ert-deftest test-abbrev-table-p ()
+ (should-not (abbrev-table-p translation-table-vector))
+ (should (abbrev-table-p (make-abbrev-table))))
+
(provide 'abbrev-tests)
;;; abbrev-tests.el ends here
diff --git a/test/lisp/ansi-color-tests.el b/test/lisp/ansi-color-tests.el
index fe97c27f032..1b04e8e9def 100644
--- a/test/lisp/ansi-color-tests.el
+++ b/test/lisp/ansi-color-tests.el
@@ -24,10 +24,12 @@
;;; Code:
(require 'ansi-color)
+(eval-when-compile (require 'cl-lib))
(defvar ansi-color-tests--strings
(let ((bright-yellow (face-foreground 'ansi-color-bright-yellow nil 'default))
- (yellow (face-foreground 'ansi-color-yellow nil 'default)))
+ (yellow (face-foreground 'ansi-color-yellow nil 'default))
+ (custom-color "#87FFFF"))
`(("Hello World" "Hello World")
("\e[33mHello World\e[0m" "Hello World"
(:foreground ,yellow))
@@ -51,7 +53,25 @@
(ansi-color-bold (:foreground ,bright-yellow)))
("\e[1m\e[3m\e[5mbold italics blink\e[0m" "bold italics blink"
(ansi-color-bold ansi-color-italic ansi-color-slow-blink))
- ("\e[10munrecognized\e[0m" "unrecognized"))))
+ ("\e[10munrecognized\e[0m" "unrecognized")
+ ("\e[38;5;3;1mHello World\e[0m" "Hello World"
+ (ansi-color-bold (:foreground ,yellow))
+ (ansi-color-bold (:foreground ,bright-yellow)))
+ ("\e[48;5;123;1mHello World\e[0m" "Hello World"
+ (ansi-color-bold (:background ,custom-color)))
+ ("\e[48;2;135;255;255;1mHello World\e[0m" "Hello World"
+ (ansi-color-bold (:background ,custom-color))))))
+
+(defun ansi-color-tests-equal-props (o1 o2)
+ "Return t if two Lisp objects have similar structure and contents.
+While `equal-including-properties' compares text properties of
+strings with `eq', this function compares them with `equal'."
+ (or (equal-including-properties o1 o2)
+ (and (stringp o1)
+ (equal o1 o2)
+ (cl-loop for i below (length o1)
+ always (equal (text-properties-at i o1)
+ (text-properties-at i o2))))))
(ert-deftest ansi-color-apply-on-region-test ()
(pcase-dolist (`(,input ,text ,face) ansi-color-tests--strings)
@@ -83,6 +103,94 @@
(ansi-color-apply-on-region (point-min) (point-max) t)
(should (equal (buffer-string) (car pair))))))
+(ert-deftest ansi-color-incomplete-sequences-test ()
+ (let* ((strs (list "\e[" "2;31m Hello World "
+ "\e" "[108;5;12" "3m" "Greetings"
+ "\e[0m\e[35;6m" "Hello"))
+ (complete-str (apply #'concat strs))
+ (filtered-str)
+ (propertized-str)
+ (ansi-color-apply-face-function
+ #'ansi-color-apply-text-property-face)
+ (ansi-filt (lambda (str) (ansi-color-filter-apply
+ (copy-sequence str))))
+ (ansi-app (lambda (str) (ansi-color-apply
+ (copy-sequence str)))))
+
+ (with-temp-buffer
+ (setq filtered-str
+ (replace-regexp-in-string "\e\\[.*?m" "" complete-str))
+ (setq propertized-str (funcall ansi-app complete-str))
+
+ (should-not (ansi-color-tests-equal-props
+ filtered-str propertized-str))
+ (should (equal filtered-str propertized-str)))
+
+ ;; Tests for `ansi-color-filter-apply'
+ (with-temp-buffer
+ (should (equal-including-properties
+ filtered-str
+ (funcall ansi-filt complete-str))))
+
+ (with-temp-buffer
+ (should (equal-including-properties
+ filtered-str
+ (mapconcat ansi-filt strs ""))))
+
+ ;; Tests for `ansi-color-filter-region'
+ (with-temp-buffer
+ (insert complete-str)
+ (ansi-color-filter-region (point-min) (point-max))
+ (should (equal-including-properties
+ filtered-str (buffer-string))))
+
+ (with-temp-buffer
+ (dolist (str strs)
+ (let ((opoint (point)))
+ (insert str)
+ (ansi-color-filter-region opoint (point))))
+ (should (equal-including-properties
+ filtered-str (buffer-string))))
+
+ ;; Test for `ansi-color-apply'
+ (with-temp-buffer
+ (should (ansi-color-tests-equal-props
+ propertized-str
+ (mapconcat ansi-app strs ""))))
+
+ ;; Tests for `ansi-color-apply-on-region'
+ (with-temp-buffer
+ (insert complete-str)
+ (ansi-color-apply-on-region (point-min) (point-max))
+ (should (ansi-color-tests-equal-props
+ propertized-str (buffer-string))))
+
+ (with-temp-buffer
+ (dolist (str strs)
+ (let ((opoint (point)))
+ (insert str)
+ (ansi-color-apply-on-region opoint (point))))
+ (should (ansi-color-tests-equal-props
+ propertized-str (buffer-string))))
+
+ ;; \e not followed by '[' and invalid ANSI escape sequences
+ (dolist (fun (list ansi-filt ansi-app))
+ (with-temp-buffer
+ (should (equal (funcall fun "\e") ""))
+ (should (equal (funcall fun "\e[33m test \e[0m")
+ (with-temp-buffer
+ (concat "\e" (funcall fun "\e[33m test \e[0m"))))))
+ (with-temp-buffer
+ (should (equal (funcall fun "\e[") ""))
+ (should (equal (funcall fun "\e[33m Z \e[0m")
+ (with-temp-buffer
+ (concat "\e[" (funcall fun "\e[33m Z \e[0m"))))))
+ (with-temp-buffer
+ (should (equal (funcall fun "\e a \e\e[\e[") "\e a \e\e["))
+ (should (equal (funcall fun "\e[33m Z \e[0m")
+ (with-temp-buffer
+ (concat "\e[" (funcall fun "\e[33m Z \e[0m")))))))))
+
(provide 'ansi-color-tests)
;;; ansi-color-tests.el ends here
diff --git a/test/lisp/auth-source-tests.el b/test/lisp/auth-source-tests.el
index 900c99ccc61..41f8b6d8c9d 100644
--- a/test/lisp/auth-source-tests.el
+++ b/test/lisp/auth-source-tests.el
@@ -27,6 +27,7 @@
;;; Code:
(require 'ert)
+(eval-when-compile (require 'ert-x))
(require 'cl-lib)
(require 'auth-source)
(require 'secrets)
@@ -277,34 +278,29 @@
"((:host \"a1\" :port \"a2\" :user \"a3\" :secret \"a4\") (:host \"b1\" :port \"b2\" :user \"b3\" :secret \"b4\") (:host \"c1\" :port \"c2\" :user \"c3\" :secret \"c4\"))"
:host t :max 4)
("host b1, default max is 1"
- "((:host \"b1\" :port \"b2\" :user \"b3\" :secret \"b4\"))"
+ "((:host \"b1\" :port \"b2\" :user \"b3\" :secret \"b4\"))"
:host "b1")
("host b1, port b2, user b3, default max is 1"
- "((:host \"b1\" :port \"b2\" :user \"b3\" :secret \"b4\"))"
+ "((:host \"b1\" :port \"b2\" :user \"b3\" :secret \"b4\"))"
:host "b1" :port "b2" :user "b3")
- ))
-
- (netrc-file (make-temp-file "auth-source-test" nil nil
- (mapconcat 'identity entries "\n")))
- (auth-sources (list netrc-file))
- (auth-source-do-cache nil)
- found found-as-string)
-
- (dolist (test tests)
- (cl-destructuring-bind (testname needed &rest parameters) test
- (setq found (apply #'auth-source-search parameters))
- (when (listp found)
- (dolist (f found)
- (setf f (plist-put f :secret
- (let ((secret (plist-get f :secret)))
- (if (functionp secret)
- (funcall secret)
- secret))))))
-
- (setq found-as-string (format "%s: %S" testname found))
- ;; (message "With parameters %S found: [%s] needed: [%s]" parameters found-as-string needed)
- (should (equal found-as-string (concat testname ": " needed)))))
- (delete-file netrc-file)))
+ )))
+ (ert-with-temp-file netrc-file
+ :text (mapconcat 'identity entries "\n")
+ (let ((auth-sources (list netrc-file))
+ (auth-source-do-cache nil)
+ found found-as-string)
+
+ (dolist (test tests)
+ (cl-destructuring-bind (testname needed &rest parameters) test
+ (setq found (apply #'auth-source-search parameters))
+ (when (listp found)
+ (dolist (f found)
+ (setf f (plist-put f :secret (auth-info-password f)))))
+
+ (setq found-as-string (format "%s: %S" testname found))
+ ;; (message "With parameters %S found: [%s] needed: [%s]"
+ ;; parameters found-as-string needed)
+ (should (equal found-as-string (concat testname ": " needed)))))))))
(ert-deftest auth-source-test-secrets-create-secret ()
(skip-unless secrets-enabled)
@@ -326,10 +322,7 @@
auth-info
(car (auth-source-search
:max 1 :host host :require '(:user :secret) :create t))
- auth-passwd (plist-get auth-info :secret)
- auth-passwd (if (functionp auth-passwd)
- (funcall auth-passwd)
- auth-passwd))
+ auth-passwd (auth-info-password auth-info))
(should (string-equal (plist-get auth-info :user) (user-login-name)))
(should (string-equal (plist-get auth-info :host) host))
(should (equal auth-passwd passwd))
@@ -339,10 +332,7 @@
;; Check, that the item has been created indeed.
(auth-source-forget+ :host t)
(setq auth-info (car (auth-source-search :host host))
- auth-passwd (plist-get auth-info :secret)
- auth-passwd (if (functionp auth-passwd)
- (funcall auth-passwd)
- auth-passwd))
+ auth-passwd (auth-info-password auth-info))
(if (zerop (length passwd))
(progn
(should-not (plist-get auth-info :user))
@@ -360,77 +350,65 @@
(format "%s@%s" (plist-get auth-info :user) (plist-get auth-info :host))))))
(ert-deftest auth-source-test-netrc-create-secret ()
- (let* ((netrc-file (make-temp-file "auth-source-test"))
- (auth-sources (list netrc-file))
- (auth-source-save-behavior t)
- host auth-info auth-passwd)
- (unwind-protect
- (dolist (passwd '("foo" "" nil))
- ;; Redefine `read-*' in order to avoid interactive input.
- (cl-letf (((symbol-function 'read-passwd) (lambda (_) passwd))
- ((symbol-function 'read-string)
- (lambda (_prompt &optional _initial _history default
- _inherit-input-method)
- default)))
- (setq host
- (md5 (concat (prin1-to-string process-environment) passwd))
- auth-info
- (car (auth-source-search
- :max 1 :host host :require '(:user :secret) :create t))
- auth-passwd (plist-get auth-info :secret)
- auth-passwd (if (functionp auth-passwd)
- (funcall auth-passwd)
- auth-passwd))
- (should (string-equal (plist-get auth-info :user) (user-login-name)))
- (should (string-equal (plist-get auth-info :host) host))
- (should (equal auth-passwd passwd))
- (when (functionp (plist-get auth-info :save-function))
- (funcall (plist-get auth-info :save-function)))
-
- ;; Check, that the item has been created indeed.
- (auth-source-forget+ :host t)
- (setq auth-source-netrc-cache nil)
- (setq auth-info (car (auth-source-search :host host))
- auth-passwd (plist-get auth-info :secret)
- auth-passwd (if (functionp auth-passwd)
- (funcall auth-passwd)
- auth-passwd))
- (with-temp-buffer
- (insert-file-contents netrc-file)
- (if (zerop (length passwd))
- (progn
- (should-not (plist-get auth-info :user))
- (should-not (plist-get auth-info :host))
- (should-not auth-passwd)
- (should-not (search-forward host nil 'noerror)))
- (should
- (string-equal (plist-get auth-info :user) (user-login-name)))
- (should (string-equal (plist-get auth-info :host) host))
- (should (string-equal auth-passwd passwd))
- (should (search-forward host nil 'noerror))))))
-
- ;; Cleanup.
- (delete-file netrc-file))))
+ (ert-with-temp-file netrc-file
+ :suffix "auth-source-test"
+ (let* ((auth-sources (list netrc-file))
+ (auth-source-save-behavior t)
+ host auth-info auth-passwd)
+ (dolist (passwd '("foo" "" nil))
+ ;; Redefine `read-*' in order to avoid interactive input.
+ (cl-letf (((symbol-function 'read-passwd) (lambda (_) passwd))
+ ((symbol-function 'read-string)
+ (lambda (_prompt &optional _initial _history default
+ _inherit-input-method)
+ default)))
+ (setq host
+ (md5 (concat (prin1-to-string process-environment) passwd))
+ auth-info
+ (car (auth-source-search
+ :max 1 :host host :require '(:user :secret) :create t))
+ auth-passwd (auth-info-password auth-info))
+ (should (string-equal (plist-get auth-info :user) (user-login-name)))
+ (should (string-equal (plist-get auth-info :host) host))
+ (should (equal auth-passwd passwd))
+ (when (functionp (plist-get auth-info :save-function))
+ (funcall (plist-get auth-info :save-function)))
+
+ ;; Check, that the item has been created indeed.
+ (auth-source-forget+ :host t)
+ (setq auth-source-netrc-cache nil)
+ (setq auth-info (car (auth-source-search :host host))
+ auth-passwd (auth-info-password auth-info))
+ (with-temp-buffer
+ (insert-file-contents netrc-file)
+ (if (zerop (length passwd))
+ (progn
+ (should-not (plist-get auth-info :user))
+ (should-not (plist-get auth-info :host))
+ (should-not auth-passwd)
+ (should-not (search-forward host nil 'noerror)))
+ (should
+ (string-equal (plist-get auth-info :user) (user-login-name)))
+ (should (string-equal (plist-get auth-info :host) host))
+ (should (string-equal auth-passwd passwd))
+ (should (search-forward host nil 'noerror)))))))))
(ert-deftest auth-source-delete ()
- (let* ((netrc-file (make-temp-file "auth-source-test" nil nil "\
+ (ert-with-temp-file netrc-file
+ :suffix "auth-source-test" :text "\
machine a1 port a2 user a3 password a4
machine b1 port b2 user b3 password b4
-machine c1 port c2 user c3 password c4\n"))
- (auth-sources (list netrc-file))
- (auth-source-do-cache nil)
- (expected '((:host "a1" :port "a2" :user "a3" :secret "a4")))
- (parameters '(:max 1 :host t)))
- (unwind-protect
- (let ((found (apply #'auth-source-delete parameters)))
- (dolist (f found)
- (let ((s (plist-get f :secret)))
- (setf f (plist-put f :secret
- (if (functionp s) (funcall s) s)))))
- ;; Note: The netrc backend doesn't delete anything, so
- ;; this is actually the same as `auth-source-search'.
- (should (equal found expected)))
- (delete-file netrc-file))))
+machine c1 port c2 user c3 password c4\n"
+ (let* ((auth-sources (list netrc-file))
+ (auth-source-do-cache nil)
+ (expected '((:host "a1" :port "a2" :user "a3" :secret "a4")))
+ (parameters '(:max 1 :host t))
+ (found (apply #'auth-source-delete parameters)))
+ (dolist (f found)
+ (setf f (plist-put f :secret (auth-info-password f))))
+ ;; Note: The netrc backend doesn't delete anything, so
+ ;; this is actually the same as `auth-source-search'.
+ (should (equal found expected)))))
(provide 'auth-source-tests)
;;; auth-source-tests.el ends here
diff --git a/test/lisp/autoinsert-tests.el b/test/lisp/autoinsert-tests.el
index 3f7ff0d000c..722215cb7e4 100644
--- a/test/lisp/autoinsert-tests.el
+++ b/test/lisp/autoinsert-tests.el
@@ -28,6 +28,7 @@
(require 'autoinsert)
(require 'ert)
+(require 'ert-x)
(ert-deftest autoinsert-tests-auto-insert-skeleton ()
(let ((auto-insert-alist '((text-mode nil "f" _ "oo")))
@@ -39,16 +40,14 @@
(should (equal (point) (+ (point-min) 1))))))
(ert-deftest autoinsert-tests-auto-insert-file ()
- (let ((temp-file (make-temp-file "autoinsert-tests" nil nil "foo")))
- (unwind-protect
- (let ((auto-insert-alist `((text-mode . ,temp-file)))
- (auto-insert-query nil))
- (with-temp-buffer
- (text-mode)
- (auto-insert)
- (should (equal (buffer-string) "foo"))))
- (when (file-exists-p temp-file)
- (delete-file temp-file)))))
+ (ert-with-temp-file temp-file
+ :text "foo"
+ (let ((auto-insert-alist `((text-mode . ,temp-file)))
+ (auto-insert-query nil))
+ (with-temp-buffer
+ (text-mode)
+ (auto-insert)
+ (should (equal (buffer-string) "foo"))))))
(ert-deftest autoinsert-tests-auto-insert-function ()
(let ((auto-insert-alist '((text-mode . (lambda () (insert "foo")))))
diff --git a/test/lisp/autorevert-tests.el b/test/lisp/autorevert-tests.el
index b058f19a26c..54b1a16b5db 100644
--- a/test/lisp/autorevert-tests.el
+++ b/test/lisp/autorevert-tests.el
@@ -52,10 +52,9 @@
;;; Code:
-(require 'ert)
+(require 'tramp)
(require 'ert-x)
(require 'autorevert)
-(require 'tramp)
(setq auto-revert-debug nil
auto-revert-notify-exclude-dir-regexp "nothing-to-be-excluded"
@@ -70,30 +69,6 @@
(defvar auto-revert--messages nil
"Used to collect messages issued during a section of a test.")
-;; There is no default value on w32 systems, which could work out of the box.
-(defconst auto-revert-test-remote-temporary-file-directory
- (cond
- ((getenv "REMOTE_TEMPORARY_FILE_DIRECTORY"))
- ((eq system-type 'windows-nt) null-device)
- (t (add-to-list
- 'tramp-methods
- '("mock"
- (tramp-login-program "sh")
- (tramp-login-args (("-i")))
- (tramp-remote-shell "/bin/sh")
- (tramp-remote-shell-args ("-c"))
- (tramp-connection-timeout 10)))
- (add-to-list
- 'tramp-default-host-alist
- `("\\`mock\\'" nil ,(system-name)))
- ;; Emacs' Makefile sets $HOME to a nonexistent value. Needed in
- ;; batch mode only, therefore. `temporary-file-directory' might
- ;; be quoted, so we unquote it just in case.
- (unless (and (null noninteractive) (file-directory-p "~/"))
- (setenv "HOME" (file-name-unquote temporary-file-directory)))
- (format "/mock::%s" temporary-file-directory)))
- "Temporary directory for Tramp tests.")
-
;; Filter suppressed remote file-notify libraries.
(when (stringp (getenv "REMOTE_FILE_NOTIFY_LIBRARY"))
(dolist (lib '("inotifywait" "gio-monitor" "gvfs-monitor-dir"))
@@ -114,10 +89,9 @@ being the result.")
t (ignore-errors
(and
(not (getenv "EMACS_HYDRA_CI"))
- (file-remote-p auto-revert-test-remote-temporary-file-directory)
- (file-directory-p auto-revert-test-remote-temporary-file-directory)
- (file-writable-p
- auto-revert-test-remote-temporary-file-directory))))))
+ (file-remote-p ert-remote-temporary-file-directory)
+ (file-directory-p ert-remote-temporary-file-directory)
+ (file-writable-p ert-remote-temporary-file-directory))))))
;; Return result.
(cdr auto-revert--test-enabled-remote-checked))
@@ -127,7 +101,7 @@ This expects `auto-revert--messages' to be bound by
`ert-with-message-capture' before calling."
;; Remote files do not cooperate well with timers. So we count ourselves.
(let ((ct (current-time)))
- (while (and (< (float-time (time-subtract (current-time) ct))
+ (while (and (< (float-time (time-subtract nil ct))
(auto-revert--timeout))
(null (string-match
(format-message
@@ -146,7 +120,7 @@ This expects `auto-revert--messages' to be bound by
,docstring
:tags '(:expensive-test :unstable)
(let ((temporary-file-directory
- auto-revert-test-remote-temporary-file-directory)
+ ert-remote-temporary-file-directory)
(auto-revert-remote-files t)
(ert-test (ert-get-test ',test))
vc-handled-backends)
@@ -167,49 +141,48 @@ This expects `auto-revert--messages' to be bound by
(defun auto-revert-tests--write-file (text file time-delta &optional append)
(write-region text nil file append 'no-message)
- (set-file-times file (time-subtract (current-time) time-delta)))
+ (set-file-times file (time-subtract nil time-delta)))
(ert-deftest auto-revert-test00-auto-revert-mode ()
"Check autorevert for a file."
;; `auto-revert-buffers' runs every 5". And we must wait, until the
;; file has been reverted.
(with-auto-revert-test
- (let ((tmpfile (make-temp-file "auto-revert-test"))
- (times '(60 30 15))
- buf)
- (unwind-protect
- (progn
- (auto-revert-tests--write-file "any text" tmpfile (pop times))
- (setq buf (find-file-noselect tmpfile))
- (with-current-buffer buf
- (ert-with-message-capture auto-revert--messages
- (should (string-equal (buffer-string) "any text"))
- ;; `buffer-stale--default-function' checks for
- ;; `verify-visited-file-modtime'. We must ensure that it
- ;; returns nil.
- (auto-revert-mode 1)
- (should auto-revert-mode)
-
- (auto-revert-tests--write-file "another text" tmpfile (pop times))
-
- ;; Check, that the buffer has been reverted.
- (auto-revert--wait-for-revert buf))
- (should (string-match "another text" (buffer-string)))
-
- ;; When the buffer is modified, it shall not be reverted.
- (ert-with-message-capture auto-revert--messages
- (set-buffer-modified-p t)
- (auto-revert-tests--write-file "any text" tmpfile (pop times))
-
- ;; Check, that the buffer hasn't been reverted.
- (auto-revert--wait-for-revert buf))
- (should-not (string-match "any text" (buffer-string)))))
-
- ;; Exit.
- (ignore-errors
- (with-current-buffer buf (set-buffer-modified-p nil))
- (kill-buffer buf))
- (ignore-errors (delete-file tmpfile))))))
+ (ert-with-temp-file tmpfile
+ (let ((times '(60 30 15))
+ buf)
+ (unwind-protect
+ (progn
+ (auto-revert-tests--write-file "any text" tmpfile (pop times))
+ (setq buf (find-file-noselect tmpfile))
+ (with-current-buffer buf
+ (ert-with-message-capture auto-revert--messages
+ (should (string-equal (buffer-string) "any text"))
+ ;; `buffer-stale--default-function' checks for
+ ;; `verify-visited-file-modtime'. We must ensure that it
+ ;; returns nil.
+ (auto-revert-mode 1)
+ (should auto-revert-mode)
+
+ (auto-revert-tests--write-file "another text" tmpfile (pop times))
+
+ ;; Check, that the buffer has been reverted.
+ (auto-revert--wait-for-revert buf))
+ (should (string-match "another text" (buffer-string)))
+
+ ;; When the buffer is modified, it shall not be reverted.
+ (ert-with-message-capture auto-revert--messages
+ (set-buffer-modified-p t)
+ (auto-revert-tests--write-file "any text" tmpfile (pop times))
+
+ ;; Check, that the buffer hasn't been reverted.
+ (auto-revert--wait-for-revert buf))
+ (should-not (string-match "any text" (buffer-string)))))
+
+ ;; Exit.
+ (ignore-errors
+ (with-current-buffer buf (set-buffer-modified-p nil))
+ (kill-buffer buf)))))))
(auto-revert--deftest-remote auto-revert-test00-auto-revert-mode
"Check autorevert for a remote file.")
@@ -219,63 +192,61 @@ This expects `auto-revert--messages' to be bound by
"Check autorevert for several files at once."
(skip-unless (executable-find "cp" (file-remote-p temporary-file-directory)))
- (with-auto-revert-test
- (let* ((cp (executable-find "cp" (file-remote-p temporary-file-directory)))
- (tmpdir1 (make-temp-file "auto-revert-test" 'dir))
- (tmpdir2 (make-temp-file "auto-revert-test" 'dir))
- (tmpfile1
- (make-temp-file (expand-file-name "auto-revert-test" tmpdir1)))
- (tmpfile2
- (make-temp-file (expand-file-name "auto-revert-test" tmpdir1)))
- (times '(120 60 30 15))
- buf1 buf2)
- (unwind-protect
- (ert-with-message-capture auto-revert--messages
- (auto-revert-tests--write-file "any text" tmpfile1 (pop times))
- (setq buf1 (find-file-noselect tmpfile1))
- (auto-revert-tests--write-file "any text" tmpfile2 (pop times))
- (setq buf2 (find-file-noselect tmpfile2))
-
- (dolist (buf (list buf1 buf2))
- (with-current-buffer buf
- (should (string-equal (buffer-string) "any text"))
- ;; `buffer-stale--default-function' checks for
- ;; `verify-visited-file-modtime'. We must ensure that
- ;; it returns nil.
- (auto-revert-mode 1)
- (should auto-revert-mode)))
-
- ;; Modify files. We wait for a second, in order to have
- ;; another timestamp.
- (auto-revert-tests--write-file
- "another text"
- (expand-file-name (file-name-nondirectory tmpfile1) tmpdir2)
- (pop times))
- (auto-revert-tests--write-file
- "another text"
- (expand-file-name (file-name-nondirectory tmpfile2) tmpdir2)
- (pop times))
- ;;(copy-directory tmpdir2 tmpdir1 nil 'copy-contents)
- ;; Strange, that `copy-directory' does not work as expected.
- ;; The following shell command is not portable on all
- ;; platforms, unfortunately.
- (shell-command
- (format "%s -f %s/* %s"
- cp (file-local-name tmpdir2) (file-local-name tmpdir1)))
-
- ;; Check, that the buffers have been reverted.
- (dolist (buf (list buf1 buf2))
- (with-current-buffer buf
- (auto-revert--wait-for-revert buf)
- (should (string-match "another text" (buffer-string))))))
-
- ;; Exit.
- (ignore-errors
- (dolist (buf (list buf1 buf2))
- (with-current-buffer buf (set-buffer-modified-p nil))
- (kill-buffer buf)))
- (ignore-errors (delete-directory tmpdir1 'recursive))
- (ignore-errors (delete-directory tmpdir2 'recursive))))))
+ (ert-with-temp-directory tmpdir1
+ (ert-with-temp-directory tmpdir2
+ (ert-with-temp-file tmpfile1
+ :prefix (expand-file-name "auto-revert-test" tmpdir1)
+ (ert-with-temp-file tmpfile2
+ :prefix (expand-file-name "auto-revert-test" tmpdir1)
+ (with-auto-revert-test
+ (let* ((cp (executable-find "cp" (file-remote-p temporary-file-directory)))
+ (times '(120 60 30 15))
+ buf1 buf2)
+ (unwind-protect
+ (ert-with-message-capture auto-revert--messages
+ (auto-revert-tests--write-file "any text" tmpfile1 (pop times))
+ (setq buf1 (find-file-noselect tmpfile1))
+ (auto-revert-tests--write-file "any text" tmpfile2 (pop times))
+ (setq buf2 (find-file-noselect tmpfile2))
+
+ (dolist (buf (list buf1 buf2))
+ (with-current-buffer buf
+ (should (string-equal (buffer-string) "any text"))
+ ;; `buffer-stale--default-function' checks for
+ ;; `verify-visited-file-modtime'. We must ensure that
+ ;; it returns nil.
+ (auto-revert-mode 1)
+ (should auto-revert-mode)))
+
+ ;; Modify files. We wait for a second, in order to have
+ ;; another timestamp.
+ (auto-revert-tests--write-file
+ "another text"
+ (expand-file-name (file-name-nondirectory tmpfile1) tmpdir2)
+ (pop times))
+ (auto-revert-tests--write-file
+ "another text"
+ (expand-file-name (file-name-nondirectory tmpfile2) tmpdir2)
+ (pop times))
+ ;;(copy-directory tmpdir2 tmpdir1 nil 'copy-contents)
+ ;; Strange, that `copy-directory' does not work as expected.
+ ;; The following shell command is not portable on all
+ ;; platforms, unfortunately.
+ (shell-command
+ (format "%s -f %s/* %s"
+ cp (file-local-name tmpdir2) (file-local-name tmpdir1)))
+
+ ;; Check, that the buffers have been reverted.
+ (dolist (buf (list buf1 buf2))
+ (with-current-buffer buf
+ (auto-revert--wait-for-revert buf)
+ (should (string-match "another text" (buffer-string))))))
+
+ ;; Exit.
+ (ignore-errors
+ (dolist (buf (list buf1 buf2))
+ (with-current-buffer buf (set-buffer-modified-p nil))
+ (kill-buffer buf)))))))))))
(auto-revert--deftest-remote auto-revert-test01-auto-revert-several-files
"Check autorevert for several remote files at once.")
@@ -284,80 +255,79 @@ This expects `auto-revert--messages' to be bound by
(ert-deftest auto-revert-test02-auto-revert-deleted-file ()
"Check autorevert for a deleted file."
;; Repeated unpredictable failures, bug#32645.
- ;; Unlikely to be hydra-specific?
-; (skip-unless (not (getenv "EMACS_HYDRA_CI")))
:tags '(:unstable)
+ ;; Unlikely to be hydra-specific?
+ ;; (skip-unless (not (getenv "EMACS_HYDRA_CI")))
(with-auto-revert-test
- (let ((tmpfile (make-temp-file "auto-revert-test"))
- ;; Try to catch bug#32645.
- (auto-revert-debug (getenv "EMACS_HYDRA_CI"))
- (file-notify-debug (getenv "EMACS_HYDRA_CI"))
- (times '(120 60 30 15))
- buf desc)
- (unwind-protect
- (progn
- (auto-revert-tests--write-file "any text" tmpfile (pop times))
- (setq buf (find-file-noselect tmpfile))
- (with-current-buffer buf
- (should-not
- (file-notify-valid-p auto-revert-notify-watch-descriptor))
- (should (string-equal (buffer-string) "any text"))
- ;; `buffer-stale--default-function' checks for
- ;; `verify-visited-file-modtime'. We must ensure that
- ;; it returns nil.
- (auto-revert-mode 1)
- (should auto-revert-mode)
- (setq desc auto-revert-notify-watch-descriptor)
-
- ;; Remove file while reverting. We simulate this by
- ;; modifying `before-revert-hook'.
- (add-hook
- 'before-revert-hook
- (lambda ()
- (when auto-revert-debug
- (message "%s deleted" buffer-file-name))
- (delete-file buffer-file-name))
- nil t)
-
- (ert-with-message-capture auto-revert--messages
- (auto-revert-tests--write-file "another text" tmpfile (pop times))
- (auto-revert--wait-for-revert buf))
- ;; Check, that the buffer hasn't been reverted. File
- ;; notification should be disabled, falling back to
- ;; polling.
- (should (string-match "any text" (buffer-string)))
- ;; With w32notify, and on emba, the `stopped' events are not sent.
- (or (eq file-notify--library 'w32notify)
- (getenv "EMACS_EMBA_CI")
- (should-not
- (file-notify-valid-p auto-revert-notify-watch-descriptor)))
-
- ;; Once the file has been recreated, the buffer shall be
- ;; reverted.
- (kill-local-variable 'before-revert-hook)
- (ert-with-message-capture auto-revert--messages
- (auto-revert-tests--write-file "another text" tmpfile (pop times))
- (auto-revert--wait-for-revert buf))
- ;; Check, that the buffer has been reverted.
- (should (string-match "another text" (buffer-string)))
- ;; When file notification is used, it must be reenabled
- ;; after recreation of the file. We cannot expect that
- ;; the descriptor is the same, so we just check the
- ;; existence.
- (should (eq (null desc) (null auto-revert-notify-watch-descriptor)))
-
- ;; An empty file shall still be reverted.
- (ert-with-message-capture auto-revert--messages
- (auto-revert-tests--write-file "" tmpfile (pop times))
- (auto-revert--wait-for-revert buf))
- ;; Check, that the buffer has been reverted.
- (should (string-equal "" (buffer-string)))))
-
- ;; Exit.
- (ignore-errors
- (with-current-buffer buf (set-buffer-modified-p nil))
- (kill-buffer buf))
- (ignore-errors (delete-file tmpfile))))))
+ (ert-with-temp-file tmpfile
+ (let (;; Try to catch bug#32645.
+ (auto-revert-debug (getenv "EMACS_HYDRA_CI"))
+ (file-notify-debug (getenv "EMACS_HYDRA_CI"))
+ (times '(120 60 30 15))
+ buf desc)
+ (unwind-protect
+ (progn
+ (auto-revert-tests--write-file "any text" tmpfile (pop times))
+ (setq buf (find-file-noselect tmpfile))
+ (with-current-buffer buf
+ (should-not
+ (file-notify-valid-p auto-revert-notify-watch-descriptor))
+ (should (string-equal (buffer-string) "any text"))
+ ;; `buffer-stale--default-function' checks for
+ ;; `verify-visited-file-modtime'. We must ensure that
+ ;; it returns nil.
+ (auto-revert-mode 1)
+ (should auto-revert-mode)
+ (setq desc auto-revert-notify-watch-descriptor)
+
+ ;; Remove file while reverting. We simulate this by
+ ;; modifying `before-revert-hook'.
+ (add-hook
+ 'before-revert-hook
+ (lambda ()
+ (when auto-revert-debug
+ (message "%s deleted" buffer-file-name))
+ (delete-file buffer-file-name))
+ nil t)
+
+ (ert-with-message-capture auto-revert--messages
+ (auto-revert-tests--write-file "another text" tmpfile (pop times))
+ (auto-revert--wait-for-revert buf))
+ ;; Check, that the buffer hasn't been reverted. File
+ ;; notification should be disabled, falling back to
+ ;; polling.
+ (should (string-match "any text" (buffer-string)))
+ ;; With w32notify, and on emba, the `stopped' events are not sent.
+ (or (eq file-notify--library 'w32notify)
+ (getenv "EMACS_EMBA_CI")
+ (should-not
+ (file-notify-valid-p auto-revert-notify-watch-descriptor)))
+
+ ;; Once the file has been recreated, the buffer shall be
+ ;; reverted.
+ (kill-local-variable 'before-revert-hook)
+ (ert-with-message-capture auto-revert--messages
+ (auto-revert-tests--write-file "another text" tmpfile (pop times))
+ (auto-revert--wait-for-revert buf))
+ ;; Check, that the buffer has been reverted.
+ (should (string-match "another text" (buffer-string)))
+ ;; When file notification is used, it must be reenabled
+ ;; after recreation of the file. We cannot expect that
+ ;; the descriptor is the same, so we just check the
+ ;; existence.
+ (should (eq (null desc) (null auto-revert-notify-watch-descriptor)))
+
+ ;; An empty file shall still be reverted.
+ (ert-with-message-capture auto-revert--messages
+ (auto-revert-tests--write-file "" tmpfile (pop times))
+ (auto-revert--wait-for-revert buf))
+ ;; Check, that the buffer has been reverted.
+ (should (string-equal "" (buffer-string)))))
+
+ ;; Exit.
+ (ignore-errors
+ (with-current-buffer buf (set-buffer-modified-p nil))
+ (kill-buffer buf)))))))
(auto-revert--deftest-remote auto-revert-test02-auto-revert-deleted-file
"Check autorevert for a deleted remote file.")
@@ -366,34 +336,33 @@ This expects `auto-revert--messages' to be bound by
"Check autorevert tail mode."
;; `auto-revert-buffers' runs every 5". And we must wait, until the
;; file has been reverted.
- (let ((tmpfile (make-temp-file "auto-revert-test"))
- (times '(30 15))
- buf)
- (unwind-protect
- (ert-with-message-capture auto-revert--messages
- (auto-revert-tests--write-file "any text" tmpfile (pop times))
- (setq buf (find-file-noselect tmpfile))
- (with-current-buffer buf
- ;; `buffer-stale--default-function' checks for
- ;; `verify-visited-file-modtime'. We must ensure that it
- ;; returns nil.
- (auto-revert-tail-mode 1)
- (should auto-revert-tail-mode)
- (erase-buffer)
- (insert "modified text\n")
- (set-buffer-modified-p nil)
-
- ;; Modify file.
- (auto-revert-tests--write-file "another text" tmpfile (pop times) 'append)
-
- ;; Check, that the buffer has been reverted.
- (auto-revert--wait-for-revert buf)
- (should
- (string-match "modified text\nanother text" (buffer-string)))))
-
- ;; Exit.
- (ignore-errors (kill-buffer buf))
- (ignore-errors (delete-file tmpfile)))))
+ (ert-with-temp-file tmpfile
+ (let ((times '(30 15))
+ buf)
+ (unwind-protect
+ (ert-with-message-capture auto-revert--messages
+ (auto-revert-tests--write-file "any text" tmpfile (pop times))
+ (setq buf (find-file-noselect tmpfile))
+ (with-current-buffer buf
+ ;; `buffer-stale--default-function' checks for
+ ;; `verify-visited-file-modtime'. We must ensure that it
+ ;; returns nil.
+ (auto-revert-tail-mode 1)
+ (should auto-revert-tail-mode)
+ (erase-buffer)
+ (insert "modified text\n")
+ (set-buffer-modified-p nil)
+
+ ;; Modify file.
+ (auto-revert-tests--write-file "another text" tmpfile (pop times) 'append)
+
+ ;; Check, that the buffer has been reverted.
+ (auto-revert--wait-for-revert buf)
+ (should
+ (string-match "modified text\nanother text" (buffer-string)))))
+
+ ;; Exit.
+ (ignore-errors (kill-buffer buf))))))
(auto-revert--deftest-remote auto-revert-test03-auto-revert-tail-mode
"Check remote autorevert tail mode.")
@@ -403,46 +372,45 @@ This expects `auto-revert--messages' to be bound by
;; `auto-revert-buffers' runs every 5". And we must wait, until the
;; file has been reverted.
(with-auto-revert-test
- (let* ((tmpfile (make-temp-file "auto-revert-test"))
- (name (file-name-nondirectory tmpfile))
- (times '(30))
- buf)
- (unwind-protect
- (progn
- (setq buf (dired-noselect temporary-file-directory))
- (with-current-buffer buf
- ;; `buffer-stale--default-function' checks for
- ;; `verify-visited-file-modtime'. We must ensure that it
- ;; returns nil.
- (auto-revert-mode 1)
- (should auto-revert-mode)
- (should
- (string-match name (substring-no-properties (buffer-string))))
-
- (ert-with-message-capture auto-revert--messages
- ;; Delete file.
- (delete-file tmpfile)
- (auto-revert--wait-for-revert buf))
- ;; Check, that the buffer has been reverted.
- (should-not
- (string-match name (substring-no-properties (buffer-string))))
-
- (ert-with-message-capture auto-revert--messages
- ;; Make dired buffer modified. Check, that the buffer has
- ;; been still reverted.
- (set-buffer-modified-p t)
- (auto-revert-tests--write-file "any text" tmpfile (pop times))
-
- (auto-revert--wait-for-revert buf))
- ;; Check, that the buffer has been reverted.
- (should
- (string-match name (substring-no-properties (buffer-string))))))
-
- ;; Exit.
- (ignore-errors
- (with-current-buffer buf (set-buffer-modified-p nil))
- (kill-buffer buf))
- (ignore-errors (delete-file tmpfile))))))
+ (ert-with-temp-file tmpfile
+ (let* ((name (file-name-nondirectory tmpfile))
+ (times '(30))
+ buf)
+ (unwind-protect
+ (progn
+ (setq buf (dired-noselect temporary-file-directory))
+ (with-current-buffer buf
+ ;; `buffer-stale--default-function' checks for
+ ;; `verify-visited-file-modtime'. We must ensure that it
+ ;; returns nil.
+ (auto-revert-mode 1)
+ (should auto-revert-mode)
+ (should
+ (string-match name (substring-no-properties (buffer-string))))
+
+ (ert-with-message-capture auto-revert--messages
+ ;; Delete file.
+ (delete-file tmpfile)
+ (auto-revert--wait-for-revert buf))
+ ;; Check, that the buffer has been reverted.
+ (should-not
+ (string-match name (substring-no-properties (buffer-string))))
+
+ (ert-with-message-capture auto-revert--messages
+ ;; Make dired buffer modified. Check, that the buffer has
+ ;; been still reverted.
+ (set-buffer-modified-p t)
+ (auto-revert-tests--write-file "any text" tmpfile (pop times))
+
+ (auto-revert--wait-for-revert buf))
+ ;; Check, that the buffer has been reverted.
+ (should
+ (string-match name (substring-no-properties (buffer-string))))))
+
+ ;; Exit.
+ (ignore-errors
+ (with-current-buffer buf (set-buffer-modified-p nil))
+ (kill-buffer buf)))))))
(auto-revert--deftest-remote auto-revert-test04-auto-revert-mode-dired
"Check remote autorevert for dired.")
@@ -459,7 +427,7 @@ This expects `auto-revert--messages' to be bound by
(defun auto-revert-test--wait-for (pred max-wait)
"Wait until PRED is true, or MAX-WAIT seconds elapsed."
(let ((ct (current-time)))
- (while (and (< (float-time (time-subtract (current-time) ct)) max-wait)
+ (while (and (< (float-time (time-subtract nil ct)) max-wait)
(not (funcall pred)))
(read-event nil nil 0.1))))
@@ -485,99 +453,84 @@ This expects `auto-revert--messages' to be bound by
(skip-unless (or file-notify--library
(file-remote-p temporary-file-directory)))
(with-auto-revert-test
- (let* ((auto-revert-use-notify t)
- (auto-revert-avoid-polling t)
- (auto-revert-debug (getenv "EMACS_EMBA_CI"))
- (file-notify-debug (getenv "EMACS_EMBA_CI"))
- (was-in-global-auto-revert-mode global-auto-revert-mode)
- (file-1 (make-temp-file "global-auto-revert-test-1"))
- (file-2 (make-temp-file "global-auto-revert-test-2"))
- (file-3 (make-temp-file "global-auto-revert-test-3"))
- (file-2b (concat file-2 "-b"))
- require-final-newline buf-1 buf-2 buf-3)
- (unwind-protect
- (progn
- (setq buf-1 (find-file-noselect file-1))
- (auto-revert-test--instrument-kill-buffer-hook buf-1)
- (setq buf-2 (find-file-noselect file-2))
- (auto-revert-test--instrument-kill-buffer-hook buf-2)
- (auto-revert-test--write-file "1-a" file-1)
- (should (equal (auto-revert-test--buffer-string buf-1) ""))
-
- (global-auto-revert-mode 1) ; Turn it on.
-
- (should (buffer-local-value
- 'auto-revert-notify-watch-descriptor buf-1))
- (should (buffer-local-value
- 'auto-revert-notify-watch-descriptor buf-2))
-
- ;; buf-1 should have been reverted immediately when the mode
- ;; was enabled.
- (should (equal (auto-revert-test--buffer-string buf-1) "1-a"))
-
- ;; Alter a file.
- (auto-revert-test--write-file "2-a" file-2)
- ;; Allow for some time to handle notification events.
- (auto-revert-test--wait-for-buffer-text buf-2 "2-a" 1)
- (should (equal (auto-revert-test--buffer-string buf-2) "2-a"))
-
- ;; Visit a file, and modify it on disk.
- (setq buf-3 (find-file-noselect file-3))
- (auto-revert-test--instrument-kill-buffer-hook buf-3)
- ;; Newly opened buffers won't be use notification until the
- ;; first poll cycle; wait for it.
- (auto-revert-test--wait-for
- (lambda () (buffer-local-value
- 'auto-revert-notify-watch-descriptor buf-3))
- (auto-revert--timeout))
- (should (buffer-local-value
- 'auto-revert-notify-watch-descriptor buf-3))
- (auto-revert-test--write-file "3-a" file-3)
- (auto-revert-test--wait-for-buffer-text buf-3 "3-a" 1)
- (should (equal (auto-revert-test--buffer-string buf-3) "3-a"))
-
- ;; Delete a visited file, and re-create it with new contents.
- (when auto-revert-debug (message "Hallo0"))
- (delete-file file-1)
- (when auto-revert-debug (message "Hallo1"))
- (should (equal (auto-revert-test--buffer-string buf-1) "1-a"))
- (when auto-revert-debug (message "Hallo2"))
- (auto-revert-test--write-file "1-b" file-1)
- (when auto-revert-debug (message "Hallo3"))
- (auto-revert-test--wait-for-buffer-text
- buf-1 "1-b" (auto-revert--timeout))
- ;; On emba, `buf-1' is a killed buffer.
- (when auto-revert-debug
- (message
- "Hallo4 %s %s %s %s %s %s %s"
- buf-1 (buffer-name buf-1) (buffer-live-p buf-1)
- file-1 (get-file-buffer file-1)
- (buffer-name (get-file-buffer file-1))
- (buffer-live-p (get-file-buffer file-1)))
- (with-current-buffer buf-1
- (message "Hallo5\n%s" (buffer-local-variables))))
- (should (buffer-local-value
- 'auto-revert-notify-watch-descriptor buf-1))
- (when auto-revert-debug (message "Hallo6"))
-
- ;; Write a buffer to a new file, then modify the new file on disk.
- (with-current-buffer buf-2
- (write-file file-2b))
- (should (equal (auto-revert-test--buffer-string buf-2) "2-a"))
- (auto-revert-test--write-file "2-b" file-2b)
- (auto-revert-test--wait-for-buffer-text
- buf-2 "2-b" (auto-revert--timeout))
- (should (buffer-local-value
- 'auto-revert-notify-watch-descriptor buf-2)))
-
- ;; Clean up.
- (unless was-in-global-auto-revert-mode
- (global-auto-revert-mode 0)) ; Turn it off.
- (dolist (buf (list buf-1 buf-2 buf-3))
- (with-current-buffer buf (setq-local kill-buffer-hook nil))
- (ignore-errors (kill-buffer buf)))
- (dolist (file (list file-1 file-2 file-2b file-3))
- (ignore-errors (delete-file file)))))))
+ (ert-with-temp-file file-1
+ (ert-with-temp-file file-2
+ (ert-with-temp-file file-3
+ (let* ((auto-revert-use-notify t)
+ (auto-revert-avoid-polling t)
+ (was-in-global-auto-revert-mode global-auto-revert-mode)
+ (file-2b (concat file-2 "-b"))
+ require-final-newline buf-1 buf-2 buf-3)
+ (unwind-protect
+ (progn
+ (setq buf-1 (find-file-noselect file-1))
+ (auto-revert-test--instrument-kill-buffer-hook buf-1)
+ (setq buf-2 (find-file-noselect file-2))
+ (auto-revert-test--instrument-kill-buffer-hook buf-2)
+ (auto-revert-test--write-file "1-a" file-1)
+ (should (equal (auto-revert-test--buffer-string buf-1) ""))
+
+ (global-auto-revert-mode 1) ; Turn it on.
+
+ (should (buffer-local-value
+ 'auto-revert-notify-watch-descriptor buf-1))
+ (should (buffer-local-value
+ 'auto-revert-notify-watch-descriptor buf-2))
+
+ ;; buf-1 should have been reverted immediately when the mode
+ ;; was enabled.
+ (should (equal (auto-revert-test--buffer-string buf-1) "1-a"))
+
+ ;; Alter a file.
+ (auto-revert-test--write-file "2-a" file-2)
+ ;; Allow for some time to handle notification events.
+ (auto-revert-test--wait-for-buffer-text buf-2 "2-a" 1)
+ (should (equal (auto-revert-test--buffer-string buf-2) "2-a"))
+
+ ;; Visit a file, and modify it on disk.
+ (setq buf-3 (find-file-noselect file-3))
+ (auto-revert-test--instrument-kill-buffer-hook buf-3)
+ ;; Newly opened buffers won't be use notification until the
+ ;; first poll cycle; wait for it.
+ (auto-revert-test--wait-for
+ (lambda () (buffer-local-value
+ 'auto-revert-notify-watch-descriptor buf-3))
+ (auto-revert--timeout))
+ (should (buffer-local-value
+ 'auto-revert-notify-watch-descriptor buf-3))
+ (auto-revert-test--write-file "3-a" file-3)
+ (auto-revert-test--wait-for-buffer-text buf-3 "3-a" 1)
+ (should (equal (auto-revert-test--buffer-string buf-3) "3-a"))
+
+ ;; Delete a visited file, and re-create it with new contents.
+ (delete-file file-1)
+ (should (equal (auto-revert-test--buffer-string buf-1) "1-a"))
+ (auto-revert-test--write-file "1-b" file-1)
+ ;; Since the file is deleted, it needs at least
+ ;; `autorevert-interval' to recognize the new file,
+ ;; while polling. So increase the timeout.
+ (auto-revert-test--wait-for-buffer-text
+ buf-1 "1-b" (* 2 (auto-revert--timeout)))
+ (should (buffer-local-value
+ 'auto-revert-notify-watch-descriptor buf-1))
+
+ ;; Write a buffer to a new file, then modify the new file on disk.
+ (with-current-buffer buf-2
+ (write-file file-2b))
+ (should (equal (auto-revert-test--buffer-string buf-2) "2-a"))
+ (auto-revert-test--write-file "2-b" file-2b)
+ (auto-revert-test--wait-for-buffer-text
+ buf-2 "2-b" (auto-revert--timeout))
+ (should (buffer-local-value
+ 'auto-revert-notify-watch-descriptor buf-2)))
+
+ ;; Clean up.
+ (unless was-in-global-auto-revert-mode
+ (global-auto-revert-mode 0)) ; Turn it off.
+ (dolist (buf (list buf-1 buf-2 buf-3))
+ (with-current-buffer buf (setq-local kill-buffer-hook nil))
+ (ignore-errors (kill-buffer buf)))
+ (ignore-errors (delete-file file-2b)))))))))
(auto-revert--deftest-remote auto-revert-test05-global-notify
"Test `global-auto-revert-mode' without polling for remote buffers.")
@@ -587,31 +540,30 @@ This expects `auto-revert--messages' to be bound by
(skip-unless (or file-notify--library
(file-remote-p temporary-file-directory)))
(with-auto-revert-test
- (let* ((auto-revert-use-notify t)
- (file-1 (make-temp-file "auto-revert-test"))
- (file-2 (concat file-1 "-2"))
- require-final-newline buf)
- (unwind-protect
- (progn
- (setq buf (find-file-noselect file-1))
- (with-current-buffer buf
- (insert "A")
- (save-buffer)
+ (ert-with-temp-file file-1
+ (let* ((auto-revert-use-notify t)
+ (file-2 (concat file-1 "-2"))
+ require-final-newline buf)
+ (unwind-protect
+ (progn
+ (setq buf (find-file-noselect file-1))
+ (with-current-buffer buf
+ (insert "A")
+ (save-buffer)
- (auto-revert-mode 1)
+ (auto-revert-mode 1)
- (insert "B")
- (write-file file-2)
+ (insert "B")
+ (write-file file-2)
- (auto-revert-test--write-file "C" file-2)
- (auto-revert-test--wait-for-buffer-text
- buf "C" (auto-revert--timeout))
- (should (equal (buffer-string) "C"))))
+ (auto-revert-test--write-file "C" file-2)
+ (auto-revert-test--wait-for-buffer-text
+ buf "C" (auto-revert--timeout))
+ (should (equal (buffer-string) "C"))))
- ;; Clean up.
- (ignore-errors (kill-buffer buf))
- (ignore-errors (delete-file file-1))
- (ignore-errors (delete-file file-2))))))
+ ;; Clean up.
+ (ignore-errors (kill-buffer buf))
+ (ignore-errors (delete-file file-2)))))))
(auto-revert--deftest-remote auto-revert-test06-write-file
"Test `write-file' in `auto-revert-mode' for remote buffers.")
@@ -620,82 +572,81 @@ This expects `auto-revert--messages' to be bound by
(ert-deftest auto-revert-test07-auto-revert-several-buffers ()
"Check autorevert for several buffers visiting the same file."
;; (with-auto-revert-test
- (let ((auto-revert-use-notify t)
- (tmpfile (make-temp-file "auto-revert-test"))
- (times '(120 60 30 15))
- (num-buffers 10)
- require-final-newline buffers)
-
- (unwind-protect
- ;; Check indirect buffers.
- (ert-with-message-capture auto-revert--messages
- (auto-revert-tests--write-file "any text" tmpfile (pop times))
- (push (find-file-noselect tmpfile) buffers)
- (with-current-buffer (car buffers)
- (should (string-equal (buffer-string) "any text"))
- ;; `buffer-stale--default-function' checks for
- ;; `verify-visited-file-modtime'. We must ensure that
- ;; it returns nil.
- (auto-revert-mode 1)
- (should auto-revert-mode))
-
- (dotimes (i num-buffers)
- (push (make-indirect-buffer
- (car buffers)
- (format "%s-%d" (buffer-file-name (car buffers)) i)
- 'clone)
- buffers))
- (setq buffers (nreverse buffers))
- (dolist (buf buffers)
- (with-current-buffer buf
- (should (string-equal (buffer-string) "any text"))
- (should auto-revert-mode)))
-
- (auto-revert-tests--write-file "another text" tmpfile (pop times))
- ;; Check, that the buffer has been reverted.
- (auto-revert--wait-for-revert (car buffers))
- (dolist (buf buffers)
- (with-current-buffer buf
- (should (string-equal (buffer-string) "another text")))))
-
- ;; Exit.
- (ignore-errors
- (dolist (buf buffers)
- (with-current-buffer buf (set-buffer-modified-p nil))
- (kill-buffer buf)))
- (setq buffers nil)
- (ignore-errors (delete-file tmpfile)))
-
- ;; Check direct buffers.
- (unwind-protect
- (ert-with-message-capture auto-revert--messages
- (auto-revert-tests--write-file "any text" tmpfile (pop times))
-
- (dotimes (i num-buffers)
- (push (generate-new-buffer
- (format "%s-%d" (file-name-nondirectory tmpfile) i))
- buffers))
- (setq buffers (nreverse buffers))
- (dolist (buf buffers)
- (with-current-buffer buf
- (insert-file-contents tmpfile 'visit)
- (should (string-equal (buffer-string) "any text"))
- (auto-revert-mode 1)
- (should auto-revert-mode)))
-
- (auto-revert-tests--write-file "another text" tmpfile (pop times))
- ;; Check, that the buffers have been reverted.
- (dolist (buf buffers)
- (auto-revert--wait-for-revert buf)
- (with-current-buffer buf
- (should (string-equal (buffer-string) "another text")))))
-
- ;; Exit.
- (ignore-errors
- (dolist (buf buffers)
- (with-current-buffer buf (set-buffer-modified-p nil))
- (kill-buffer buf)))
- (ignore-errors (delete-file tmpfile)))));)
+ (ert-with-temp-file tmpfile
+ (let ((auto-revert-use-notify t)
+ (times '(120 60 30 15))
+ (num-buffers 10)
+ require-final-newline buffers)
+
+ (unwind-protect
+ ;; Check indirect buffers.
+ (ert-with-message-capture auto-revert--messages
+ (auto-revert-tests--write-file "any text" tmpfile (pop times))
+ (push (find-file-noselect tmpfile) buffers)
+ (with-current-buffer (car buffers)
+ (should (string-equal (buffer-string) "any text"))
+ ;; `buffer-stale--default-function' checks for
+ ;; `verify-visited-file-modtime'. We must ensure that
+ ;; it returns nil.
+ (auto-revert-mode 1)
+ (should auto-revert-mode))
+
+ (dotimes (i num-buffers)
+ (push (make-indirect-buffer
+ (car buffers)
+ (format "%s-%d" (buffer-file-name (car buffers)) i)
+ 'clone)
+ buffers))
+ (setq buffers (nreverse buffers))
+ (dolist (buf buffers)
+ (with-current-buffer buf
+ (should (string-equal (buffer-string) "any text"))
+ (should auto-revert-mode)))
+
+ (auto-revert-tests--write-file "another text" tmpfile (pop times))
+ ;; Check, that the buffer has been reverted.
+ (auto-revert--wait-for-revert (car buffers))
+ (dolist (buf buffers)
+ (with-current-buffer buf
+ (should (string-equal (buffer-string) "another text")))))
+
+ ;; Exit.
+ (ignore-errors
+ (dolist (buf buffers)
+ (with-current-buffer buf (set-buffer-modified-p nil))
+ (kill-buffer buf)))
+ (setq buffers nil)
+ (ignore-errors (delete-file tmpfile)))
+
+ ;; Check direct buffers.
+ (unwind-protect
+ (ert-with-message-capture auto-revert--messages
+ (auto-revert-tests--write-file "any text" tmpfile (pop times))
+
+ (dotimes (i num-buffers)
+ (push (generate-new-buffer
+ (format "%s-%d" (file-name-nondirectory tmpfile) i))
+ buffers))
+ (setq buffers (nreverse buffers))
+ (dolist (buf buffers)
+ (with-current-buffer buf
+ (insert-file-contents tmpfile 'visit)
+ (should (string-equal (buffer-string) "any text"))
+ (auto-revert-mode 1)
+ (should auto-revert-mode)))
+
+ (auto-revert-tests--write-file "another text" tmpfile (pop times))
+ ;; Check, that the buffers have been reverted.
+ (dolist (buf buffers)
+ (auto-revert--wait-for-revert buf)
+ (with-current-buffer buf
+ (should (string-equal (buffer-string) "another text")))))
+
+ ;; Exit.
+ (ignore-errors
+ (dolist (buf buffers)
+ (with-current-buffer buf (set-buffer-modified-p nil))
+ (kill-buffer buf)))))));)
(auto-revert--deftest-remote auto-revert-test07-auto-revert-several-buffers
"Check autorevert for several buffers visiting the same remote file.")
diff --git a/test/lisp/bookmark-tests.el b/test/lisp/bookmark-tests.el
index 0dd8ba4492f..3bea08bc37a 100644
--- a/test/lisp/bookmark-tests.el
+++ b/test/lisp/bookmark-tests.el
@@ -197,6 +197,9 @@ the lexically-bound variable `buffer'."
(bookmark-maybe-historicize-string "foo")
(should (equal (car bookmark-history) "foo"))))
+(defun bookmark-remove-last-modified (bmk)
+ (assoc-delete-all 'last-modified bmk))
+
(ert-deftest bookmark-tests-make-record ()
(with-bookmark-test-file
(let* ((record `("example.txt" (filename . ,bookmark-tests-example-file)
@@ -206,9 +209,11 @@ the lexically-bound variable `buffer'."
(defaults "example.txt"))))
(with-current-buffer buffer
(goto-char 3)
- (should (equal (bookmark-make-record) record))
+ (should (equal (bookmark-remove-last-modified (bookmark-make-record))
+ record))
;; calling twice gives same record
- (should (equal (bookmark-make-record) record))))))
+ (should (equal (bookmark-remove-last-modified (bookmark-make-record))
+ record))))))
(ert-deftest bookmark-tests-make-record-list ()
(with-bookmark-test-file-list
@@ -219,9 +224,11 @@ the lexically-bound variable `buffer'."
(defaults "example.txt"))))
(with-current-buffer buffer
(goto-char 3)
- (should (equal (bookmark-make-record) record))
+ (should (equal (bookmark-remove-last-modified (bookmark-make-record))
+ record))
;; calling twice gives same record
- (should (equal (bookmark-make-record) record))))))
+ (should (equal (bookmark-remove-last-modified (bookmark-make-record))
+ record))))))
(ert-deftest bookmark-tests-make-record-function ()
(with-bookmark-test
@@ -255,15 +262,18 @@ the lexically-bound variable `buffer'."
;; Set first bookmark
(goto-char (point-min))
(bookmark-set "foo")
- (should (equal bookmark-alist (list bmk1)))
+ (should (equal (mapcar #'bookmark-remove-last-modified bookmark-alist)
+ (list bmk1)))
;; Replace that bookmark
(goto-char (point-max))
(bookmark-set "foo")
- (should (equal bookmark-alist (list bmk2)))
+ (should (equal (mapcar #'bookmark-remove-last-modified bookmark-alist)
+ (list bmk2)))
;; Push another bookmark with the same name
(goto-char (point-min))
(bookmark-set "foo" t) ; NO-OVERWRITE is t
- (should (equal bookmark-alist (list bmk1 bmk2)))
+ (should (equal (mapcar #'bookmark-remove-last-modified bookmark-alist)
+ (list bmk1 bmk2)))
;; 2. bookmark-set-no-overwrite
;; Don't overwrite
@@ -271,11 +281,13 @@ the lexically-bound variable `buffer'."
;; Set new bookmark
(setq bookmark-alist nil)
(bookmark-set-no-overwrite "foo")
- (should (equal bookmark-alist (list bmk1)))
+ (should (equal (mapcar #'bookmark-remove-last-modified bookmark-alist)
+ (list bmk1)))
;; Push another bookmark with the same name
(goto-char (point-max))
(bookmark-set-no-overwrite "foo" t) ; PUSH-BOOKMARK is t
- (should (equal bookmark-alist (list bmk2 bmk1)))
+ (should (equal (mapcar #'bookmark-remove-last-modified bookmark-alist)
+ (list bmk2 bmk1)))
;; 3. bookmark-set-internal
(should-error (bookmark-set-internal "foo" "bar" t))))))
@@ -289,7 +301,7 @@ the lexically-bound variable `buffer'."
(bookmark-set "foo")
(should (equal major-mode 'bookmark-edit-annotation-mode))
;; Should return to the original buffer
- (bookmark-send-edited-annotation)
+ (bookmark-edit-annotation-confirm)
(should (equal (current-buffer) buffer))))))
(ert-deftest bookmark-tests-kill-line ()
@@ -322,7 +334,7 @@ the lexically-bound variable `buffer'."
(with-bookmark-test
(bookmark-edit-annotation "name")
(insert "new text")
- (bookmark-send-edited-annotation)
+ (bookmark-edit-annotation-confirm)
(should (equal (bookmark-get-annotation "name") "new text"))))
(ert-deftest bookmark-tests-jump ()
@@ -371,16 +383,14 @@ Same as `with-bookmark-test' but also sets a temporary
`bookmark-default-file', evaluates BODY, and then runs the test
that saves and then loads the bookmark file."
`(with-bookmark-test
- (let ((file (make-temp-file "bookmark-tests-")))
- (unwind-protect
- (let ((bookmark-default-file file)
- (old-alist bookmark-alist))
- ,@body
- (bookmark-save nil file t)
- (setq bookmark-alist nil)
- (bookmark-load file nil t)
- (should (equal bookmark-alist old-alist)))
- (delete-file file)))))
+ (ert-with-temp-file file
+ (let ((bookmark-default-file file)
+ (old-alist bookmark-alist))
+ ,@body
+ (bookmark-save nil file t)
+ (setq bookmark-alist nil)
+ (bookmark-load file nil t)
+ (should (equal bookmark-alist old-alist))))))
(defvar bookmark-tests-non-ascii-data
(concat "Здра́вствуйте!" "中文,普通话,汉语" "åäöøñ"
@@ -461,7 +471,7 @@ testing `bookmark-bmenu-list'."
(with-bookmark-bmenu-test
(bookmark-bmenu-edit-annotation)
(insert "foo")
- (bookmark-send-edited-annotation)
+ (bookmark-edit-annotation-confirm)
(should (equal (bookmark-get-annotation "name") "foo"))))
(ert-deftest bookmark-test-bmenu-send-edited-annotation/restore-focus ()
@@ -469,7 +479,7 @@ testing `bookmark-bmenu-list'."
(with-bookmark-bmenu-test
(bookmark-bmenu-edit-annotation)
(insert "foo")
- (bookmark-send-edited-annotation)
+ (bookmark-edit-annotation-confirm)
(should (equal (buffer-name (current-buffer)) bookmark-bmenu-buffer))
(beginning-of-line)
(forward-char 4)
diff --git a/test/lisp/buff-menu-tests.el b/test/lisp/buff-menu-tests.el
index 9957b36b1e4..8e7981e6999 100644
--- a/test/lisp/buff-menu-tests.el
+++ b/test/lisp/buff-menu-tests.el
@@ -24,19 +24,20 @@
;;; Code:
(require 'ert)
+(eval-when-compile (require 'ert-x))
(ert-deftest buff-menu-24962 ()
"Test for https://debbugs.gnu.org/24962 ."
- (let* ((file (make-temp-file "foo"))
- (buf (find-file file)))
- (unwind-protect
- (progn
- (rename-buffer " foo")
- (list-buffers)
- (with-current-buffer "*Buffer List*"
- (should (string= " foo" (buffer-name (Buffer-menu-buffer))))))
- (and (buffer-live-p buf) (kill-buffer buf))
- (and (file-exists-p file) (delete-file file)))))
+ (ert-with-temp-file file
+ :suffix "foo"
+ (let ((buf (find-file file)))
+ (unwind-protect
+ (progn
+ (rename-buffer " foo")
+ (list-buffers)
+ (with-current-buffer "*Buffer List*"
+ (should (string= " foo" (buffer-name (Buffer-menu-buffer))))))
+ (and (buffer-live-p buf) (kill-buffer buf))))))
(provide 'buff-menu-tests)
diff --git a/test/lisp/button-tests.el b/test/lisp/button-tests.el
index 870ec29b70c..99d1ee3de46 100644
--- a/test/lisp/button-tests.el
+++ b/test/lisp/button-tests.el
@@ -21,11 +21,9 @@
(require 'ert)
-(defvar button-tests--map
- (let ((map (make-sparse-keymap)))
- (define-key map "x" #'ignore)
- map)
- "Keymap for testing command substitution.")
+(defvar-keymap button-tests--map
+ :doc "Keymap for testing command substitution."
+ "x" #'ignore)
(ert-deftest button-at ()
"Test `button-at' behavior."
diff --git a/test/lisp/calc/calc-tests.el b/test/lisp/calc/calc-tests.el
index abedbb9712a..64e59f5b9b4 100644
--- a/test/lisp/calc/calc-tests.el
+++ b/test/lisp/calc/calc-tests.el
@@ -38,7 +38,7 @@
;; be used to compare such calc expressions.
(defun calc-tests-equal (a b)
"Like `equal' but allow for different representations of numbers.
-For example: (calc-tests-equal 10 '(float 1 1)) => t.
+For example: (calc-tests-equal 10 \\='(float 1 1)) => t.
A and B should be calc expressions."
(cond ((math-numberp a)
(and (math-numberp b)
@@ -810,6 +810,12 @@ An existing calc stack is reused, otherwise a new one is created."
(should (equal (calcFunc-test6 3) (* (* 3 2) (- 3 1))))
(should (equal (calcFunc-test7 3) (* 3 2))))
+(ert-deftest calc-nth-root ()
+ ;; bug#51209
+ (let* ((calc-display-working-message nil)
+ (x (calc-tests--calc-to-number (math-pow 8 '(frac 1 6)))))
+ (should (< (abs (- x (sqrt 2.0))) 1.0e-10))))
+
(provide 'calc-tests)
;;; calc-tests.el ends here
diff --git a/test/lisp/calendar/icalendar-tests.el b/test/lisp/calendar/icalendar-tests.el
index fa741b087b8..ac7a84aa571 100644
--- a/test/lisp/calendar/icalendar-tests.el
+++ b/test/lisp/calendar/icalendar-tests.el
@@ -698,17 +698,18 @@ and ISO style input data must use english month names."
"Actually perform export test.
Argument INPUT input diary string.
Argument EXPECTED-OUTPUT expected iCalendar result string."
- (let ((temp-file (make-temp-file "icalendar-tests-ics")))
+ (ert-with-temp-file temp-file
+ :suffix "icalendar-tests-ics"
(unwind-protect
- (progn
- (with-temp-buffer
- (insert input)
- (icalendar-export-region (point-min) (point-max) temp-file))
- (save-excursion
- (find-file temp-file)
- (goto-char (point-min))
- (cond (expected-output
- (should (re-search-forward "^\\s-*BEGIN:VCALENDAR
+ (progn
+ (with-temp-buffer
+ (insert input)
+ (icalendar-export-region (point-min) (point-max) temp-file))
+ (save-excursion
+ (find-file temp-file)
+ (goto-char (point-min))
+ (cond (expected-output
+ (should (re-search-forward "^\\s-*BEGIN:VCALENDAR
PRODID:-//Emacs//NONSGML icalendar.el//EN
VERSION:2.0
BEGIN:VEVENT
@@ -717,23 +718,22 @@ UID:emacs[0-9]+
END:VEVENT
END:VCALENDAR
\\s-*$"
- nil t))
- (should (string-match
- (concat "^\\s-*"
- (regexp-quote (buffer-substring-no-properties
- (match-beginning 1) (match-end 1)))
- "\\s-*$")
- expected-output)))
- (t
- (should (re-search-forward "^\\s-*BEGIN:VCALENDAR
+ nil t))
+ (should (string-match
+ (concat "^\\s-*"
+ (regexp-quote (buffer-substring-no-properties
+ (match-beginning 1) (match-end 1)))
+ "\\s-*$")
+ expected-output)))
+ (t
+ (should (re-search-forward "^\\s-*BEGIN:VCALENDAR
PRODID:-//Emacs//NONSGML icalendar.el//EN
VERSION:2.0
END:VCALENDAR
\\s-*$"
- nil t))))))
+ nil t))))))
;; cleanup!!
- (kill-buffer (find-buffer-visiting temp-file))
- (delete-file temp-file))))
+ (kill-buffer (find-buffer-visiting temp-file)))))
(ert-deftest icalendar-export-ordinary-no-time ()
"Perform export test."
@@ -1031,7 +1031,8 @@ During import test the timezone is set to Central European Time."
(defun icalendar-tests--do-test-import (expected-output)
"Actually perform import test.
Argument EXPECTED-OUTPUT file containing expected diary string."
- (let ((temp-file (make-temp-file "icalendar-test-diary")))
+ (ert-with-temp-file temp-file
+ :suffix "icalendar-test-diary"
;; Test the Catch-the-mysterious-coding-header logic below.
;; Ruby-mode adds an after-save-hook which inserts the header!
;; (save-excursion
@@ -1061,8 +1062,7 @@ Argument EXPECTED-OUTPUT file containing expected diary string."
(let ((result (buffer-substring-no-properties (point-min) (point-max))))
(should (string= expected-output result)))
- (kill-buffer (find-buffer-visiting temp-file))
- (delete-file temp-file))))
+ (kill-buffer (find-buffer-visiting temp-file)))))
(ert-deftest icalendar-import-non-recurring ()
"Perform standard import tests."
@@ -1240,35 +1240,33 @@ Argument INPUT icalendar event string."
(defun icalendar-tests--do-test-cycle ()
"Actually perform import/export cycle test."
- (let ((temp-diary (make-temp-file "icalendar-test-diary"))
- (temp-ics (make-temp-file "icalendar-test-ics"))
- (org-input (buffer-substring-no-properties (point-min) (point-max))))
-
- (unwind-protect
- (progn
- ;; step 1: import
- (icalendar-import-buffer temp-diary t t)
-
- ;; step 2: export what was just imported
- (save-excursion
- (find-file temp-diary)
- (icalendar-export-region (point-min) (point-max) temp-ics))
-
- ;; compare the output of step 2 with the input of step 1
- (save-excursion
- (find-file temp-ics)
- (goto-char (point-min))
- ;;(when (re-search-forward "\nUID:.*\n" nil t)
- ;;(replace-match "\n"))
- (let ((cycled (buffer-substring-no-properties (point-min) (point-max))))
- (should (string= org-input cycled)))))
- ;; clean up
- (kill-buffer (find-buffer-visiting temp-diary))
- (with-current-buffer (find-buffer-visiting temp-ics)
- (set-buffer-modified-p nil)
- (kill-buffer (current-buffer)))
- (delete-file temp-diary)
- (delete-file temp-ics))))
+ (ert-with-temp-file temp-diary
+ (ert-with-temp-file temp-ics
+ (let ((org-input (buffer-substring-no-properties (point-min) (point-max))))
+
+ (unwind-protect
+ (progn
+ ;; step 1: import
+ (icalendar-import-buffer temp-diary t t)
+
+ ;; step 2: export what was just imported
+ (save-excursion
+ (find-file temp-diary)
+ (icalendar-export-region (point-min) (point-max) temp-ics))
+
+ ;; compare the output of step 2 with the input of step 1
+ (save-excursion
+ (find-file temp-ics)
+ (goto-char (point-min))
+ ;;(when (re-search-forward "\nUID:.*\n" nil t)
+ ;;(replace-match "\n"))
+ (let ((cycled (buffer-substring-no-properties (point-min) (point-max))))
+ (should (string= org-input cycled)))))
+ ;; clean up
+ (kill-buffer (find-buffer-visiting temp-diary))
+ (with-current-buffer (find-buffer-visiting temp-ics)
+ (set-buffer-modified-p nil)
+ (kill-buffer (current-buffer))))))))
(ert-deftest icalendar-cycle ()
"Perform cycling tests.
@@ -1635,28 +1633,30 @@ SUMMARY:NNN Wwwwwwww Wwwww - Aaaaaa Pppppppp rrrrrr ddd oo Nnnnnnnn 30
(let ((time (icalendar--decode-isodatetime string day zone)))
(format-time-string "%FT%T%z" (encode-time time) 0)))
-(defun icalendar-tests--decode-isodatetime (_ical-string)
+(ert-deftest icalendar-tests--decode-isodatetime ()
"Test `icalendar--decode-isodatetime'."
- (should (equal (icalendar-test--format "20040917T050910-0200")
- "2004-09-17T03:09:10+0000"))
- (should (equal (icalendar-test--format "20040917T050910")
+ (should (equal (icalendar-test--format "20040917T050910-02:00")
"2004-09-17T03:09:10+0000"))
+ (let ((orig (icalendar-test--format "20040917T050910")))
+ (unwind-protect
+ (let ((zone "XXX-02"))
+ (should (equal (icalendar-test--format "20040917T050910" nil zone)
+ "2004-09-17T03:09:10+0000"))
+ (should (equal (icalendar-test--format "20040917T0509" nil zone)
+ "2004-09-17T03:09:00+0000"))
+ (should (equal (icalendar-test--format "20040917" nil zone)
+ "2004-09-16T22:00:00+0000"))
+ (should (equal (icalendar-test--format "20040917T050910" 1 zone)
+ "2004-09-18T03:09:10+0000"))
+ (should (equal (icalendar-test--format "20040917T050910" 30 zone)
+ "2004-10-17T03:09:10+0000")))
+ (should (equal orig (icalendar-test--format "20040917T050910")))))
(should (equal (icalendar-test--format "20040917T050910Z")
"2004-09-17T05:09:10+0000"))
- (should (equal (icalendar-test--format "20040917T0509")
- "2004-09-17T03:09:00+0000"))
- (should (equal (icalendar-test--format "20040917")
- "2004-09-16T22:00:00+0000"))
- (should (equal (icalendar-test--format "20040917T050910" 1)
- "2004-09-18T03:09:10+0000"))
- (should (equal (icalendar-test--format "20040917T050910" 30)
- "2004-10-17T03:09:10+0000"))
- (should (equal (icalendar-test--format "20040917T050910" -1)
- "2004-09-16T03:09:10+0000"))
-
+ (should (equal (icalendar-test--format "20040917T050910" -1 0)
+ "2004-09-16T05:09:10+0000"))
(should (equal (icalendar-test--format "20040917T050910" nil -3600)
"2004-09-17T06:09:10+0000")))
-
(provide 'icalendar-tests)
;;; icalendar-tests.el ends here
diff --git a/test/lisp/calendar/iso8601-tests.el b/test/lisp/calendar/iso8601-tests.el
index 6c9e85ec920..f64c498c027 100644
--- a/test/lisp/calendar/iso8601-tests.el
+++ b/test/lisp/calendar/iso8601-tests.el
@@ -82,9 +82,9 @@
(should (equal (iso8601-parse "2008-03-02T13:47:30Z")
'(30 47 13 2 3 2008 nil nil 0)))
(should (equal (iso8601-parse "2008-03-02T13:47:30+01:00")
- '(30 47 13 2 3 2008 nil nil 3600)))
+ '(30 47 13 2 3 2008 nil -1 3600)))
(should (equal (iso8601-parse "2008-03-02T13:47:30-01")
- '(30 47 13 2 3 2008 nil nil -3600))))
+ '(30 47 13 2 3 2008 nil -1 -3600))))
(ert-deftest test-iso8601-duration ()
(should (equal (iso8601-parse-duration "P3Y6M4DT12H30M5S")
@@ -221,24 +221,24 @@
(ert-deftest standard-test-time-of-day-zone ()
(should (equal (iso8601-parse-time "152746+0100")
- '(46 27 15 nil nil nil nil nil 3600)))
+ '(46 27 15 nil nil nil nil -1 3600)))
(should (equal (iso8601-parse-time "15:27:46+0100")
- '(46 27 15 nil nil nil nil nil 3600)))
+ '(46 27 15 nil nil nil nil -1 3600)))
(should (equal (iso8601-parse-time "152746+01")
- '(46 27 15 nil nil nil nil nil 3600)))
+ '(46 27 15 nil nil nil nil -1 3600)))
(should (equal (iso8601-parse-time "15:27:46+01")
- '(46 27 15 nil nil nil nil nil 3600)))
+ '(46 27 15 nil nil nil nil -1 3600)))
(should (equal (iso8601-parse-time "152746-0500")
- '(46 27 15 nil nil nil nil nil -18000)))
+ '(46 27 15 nil nil nil nil -1 -18000)))
(should (equal (iso8601-parse-time "15:27:46-0500")
- '(46 27 15 nil nil nil nil nil -18000)))
+ '(46 27 15 nil nil nil nil -1 -18000)))
(should (equal (iso8601-parse-time "152746-05")
- '(46 27 15 nil nil nil nil nil -18000)))
+ '(46 27 15 nil nil nil nil -1 -18000)))
(should (equal (iso8601-parse-time "15:27:46-05")
- '(46 27 15 nil nil nil nil nil -18000))))
+ '(46 27 15 nil nil nil nil -1 -18000))))
(defun test-iso8601-format-time-string-zone-round-trip (offset-minutes z-format)
diff --git a/test/lisp/calendar/time-date-tests.el b/test/lisp/calendar/time-date-tests.el
index 19088e8a368..fd4d5ac8a1b 100644
--- a/test/lisp/calendar/time-date-tests.el
+++ b/test/lisp/calendar/time-date-tests.el
@@ -41,6 +41,13 @@
(encode-time-value 1 2 3 4 3))
'(1 2 3 4))))
+(ert-deftest test-date-to-time ()
+ (should (equal (format-time-string "%F %T" (date-to-time "2021-12-04"))
+ "2021-12-04 00:00:00")))
+
+(ert-deftest test-days-between ()
+ (should (equal (days-between "2021-10-22" "2020-09-29") 388)))
+
(ert-deftest test-leap-year ()
(should-not (date-leap-year-p 1999))
(should-not (date-leap-year-p 1900))
@@ -48,13 +55,13 @@
(should (date-leap-year-p 2004)))
(ert-deftest test-days-to-time ()
- (should (equal (days-to-time 0) '(0 0)))
- (should (equal (days-to-time 1) '(1 20864)))
- (should (equal (days-to-time 999) '(1317 2688)))
- (should (equal (days-to-time 0.0) '(0 0 0 0)))
- (should (equal (days-to-time 0.5) '(0 43200 0 0)))
- (should (equal (days-to-time 1.0) '(1 20864 0 0)))
- (should (equal (days-to-time 999.0) '(1317 2688 0 0))))
+ (should (time-equal-p (days-to-time 0) '(0 0)))
+ (should (time-equal-p (days-to-time 1) '(1 20864)))
+ (should (time-equal-p (days-to-time 999) '(1317 2688)))
+ (should (time-equal-p (days-to-time 0.0) '(0 0 0 0)))
+ (should (time-equal-p (days-to-time 0.5) '(0 43200 0 0)))
+ (should (time-equal-p (days-to-time 1.0) '(1 20864 0 0)))
+ (should (time-equal-p (days-to-time 999.0) '(1317 2688 0 0))))
(ert-deftest test-seconds-to-string ()
(should (equal (seconds-to-string 0) "0s"))
@@ -81,14 +88,19 @@
(ert-deftest test-format-seconds ()
(should (equal (format-seconds "%y %d %h %m %s %%" 0) "0 0 0 0 0 %"))
(should (equal (format-seconds "%y %d %h %m %s %%" 9999999) "0 115 17 46 39 %"))
- (should (equal (format-seconds "%y %d %h %m %z %s %%" 1) " 1 %"))
+ (should (equal (format-seconds "%y %d %h %m %z %s %%" 1) "1 %"))
(should (equal (format-seconds "%mm %ss" 66) "1m 6s"))
(should (equal (format-seconds "%mm %5ss" 66) "1m 6s"))
(should (equal (format-seconds "%mm %.5ss" 66.4) "1m 00006s"))
(should (equal (format-seconds "%mm %,1ss" 66.4) "1m 6.4s"))
(should (equal (format-seconds "%mm %5,1ss" 66.4) "1m 6.4s"))
- (should (equal (format-seconds "%mm %.5,1ss" 66.4) "1m 006.4s")))
+ (should (equal (format-seconds "%mm %.5,1ss" 66.4) "1m 006.4s"))
+
+ (should (equal (format-seconds "%hh %z%x%mm %ss" (* 60 2)) "2m"))
+ (should (equal (format-seconds "%hh %z%mm %ss" (* 60 2)) "2m 0s"))
+ (should (equal (format-seconds "%hh %x%mm %ss" (* 60 2)) "0h 2m"))
+ (should (equal (format-seconds "%hh %x%mm %ss" 0) "0h 0m 0s")))
(ert-deftest test-ordinal ()
(should (equal (date-ordinal-to-time 2008 271)
@@ -163,7 +175,8 @@
(ert-deftest test-time-since ()
(should (time-equal-p 0 (time-since nil)))
- (should (= (cadr (time-since (time-subtract (current-time) 1))) 1)))
+ (should (time-equal-p 1 (time-convert (time-since (time-subtract nil 1))
+ 'integer))))
(ert-deftest test-time-decoded-period ()
(should (equal (decoded-time-period '(nil nil 1 nil nil nil nil nil nil))
diff --git a/test/lisp/calendar/todo-mode-tests.el b/test/lisp/calendar/todo-mode-tests.el
index 8172a39865f..0102b62c10f 100644
--- a/test/lisp/calendar/todo-mode-tests.el
+++ b/test/lisp/calendar/todo-mode-tests.el
@@ -37,25 +37,24 @@
(defmacro with-todo-test (&rest body)
"Set up an isolated `todo-mode' test environment."
(declare (debug (body)))
- `(let* ((todo-test-home (make-temp-file "todo-test-home-" t))
- ;; Since we change HOME, clear this to avoid a conflict
- ;; e.g. if Emacs runs within the user's home directory.
- (abbreviated-home-dir nil)
- (process-environment (cons (format "HOME=%s" todo-test-home)
- process-environment))
- (todo-directory (ert-resource-directory))
- (todo-default-todo-file (todo-short-file-name
- (car (funcall todo-files-function)))))
- (unwind-protect
- (progn ,@body)
- ;; Restore pre-test-run state of test files.
- (dolist (f (directory-files todo-directory))
- (let ((buf (get-file-buffer f)))
- (when buf
- (with-current-buffer buf
- (restore-buffer-modified-p nil)
- (kill-buffer)))))
- (delete-directory todo-test-home t))))
+ `(ert-with-temp-directory todo-test-home
+ (let* (;; Since we change HOME, clear this to avoid a conflict
+ ;; e.g. if Emacs runs within the user's home directory.
+ (abbreviated-home-dir nil)
+ (process-environment (cons (format "HOME=%s" todo-test-home)
+ process-environment))
+ (todo-directory (ert-resource-directory))
+ (todo-default-todo-file (todo-short-file-name
+ (car (funcall todo-files-function)))))
+ (unwind-protect
+ (progn ,@body)
+ ;; Restore pre-test-run state of test files.
+ (dolist (f (directory-files todo-directory))
+ (let ((buf (get-file-buffer f)))
+ (when buf
+ (with-current-buffer buf
+ (restore-buffer-modified-p nil)
+ (kill-buffer)))))))))
(defun todo-test--show (num &optional archive)
"Display category NUM of test todo file.
diff --git a/test/lisp/cedet/cedet-files-tests.el b/test/lisp/cedet/cedet-files-tests.el
index d264410e3cb..daaf3edfc4e 100644
--- a/test/lisp/cedet/cedet-files-tests.el
+++ b/test/lisp/cedet/cedet-files-tests.el
@@ -29,20 +29,17 @@
(require 'cedet-files)
(defvar cedet-files-utest-list
- '(
- ( "/home/me/src/myproj/src/foo.c" . "!home!me!src!myproj!src!foo.c" )
- ( "c:/work/myproj/foo.el" . "!drive_c!work!myproj!foo.el" )
- ( "//windows/proj/foo.java" . "!!windows!proj!foo.java" )
- ( "/home/me/proj!bang/foo.c" . "!home!me!proj!!bang!foo.c" )
- )
- "List of different file names to test.
-Each entry is a cons cell of ( FNAME . CONVERTED )
+ '(("/home/me/src/myproj/src/foo.c" . "!home!me!src!myproj!src!foo.c")
+ ("c:/work/myproj/foo.el" . "!drive_c!work!myproj!foo.el")
+ ("//windows/proj/foo.java" . "!!windows!proj!foo.java")
+ ("/home/me/proj!bang/foo.c" . "!home!me!proj!!bang!foo.c"))
+ "List of file names to test.
+Each entry is a cons cell of (FNAME . CONVERTED)
where FNAME is some file name, and CONVERTED is what it should be
converted into.")
(ert-deftest cedet-files-utest ()
- "Test out some file name conversions."
- (interactive)
+ "Test some file name conversions."
(dolist (FT cedet-files-utest-list)
(let ((dir->file (cedet-directory-name-to-file-name (car FT) t))
(file->dir (cedet-file-name-to-directory-name (cdr FT) t)))
diff --git a/test/lisp/cedet/semantic-utest-ia-resources/teststruct.cpp b/test/lisp/cedet/semantic-utest-ia-resources/teststruct.cpp
index e7d85101a1a..f5b6d641842 100644
--- a/test/lisp/cedet/semantic-utest-ia-resources/teststruct.cpp
+++ b/test/lisp/cedet/semantic-utest-ia-resources/teststruct.cpp
@@ -20,7 +20,7 @@
// along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
-// Note: initially provided by by Alex Ott.
+// Note: initially provided by Alex Ott.
template <typename DerivedT>
struct grammar {
diff --git a/test/lisp/cedet/semantic/bovine/gcc-tests.el b/test/lisp/cedet/semantic/bovine/gcc-tests.el
index 2e61f91e58c..041773a0c80 100644
--- a/test/lisp/cedet/semantic/bovine/gcc-tests.el
+++ b/test/lisp/cedet/semantic/bovine/gcc-tests.el
@@ -26,6 +26,7 @@
;;; Code:
(require 'ert)
+(require 'ert-x)
(require 'semantic/bovine/gcc)
;;; From bovine-gcc:
@@ -122,14 +123,9 @@ gcc version 2.95.2 19991024 (release)"
(ert-deftest semantic-gcc-test-output-parser-this-machine ()
"Test the output parser against the machine currently running Emacs."
- (skip-unless (executable-find "gcc"))
+ (skip-unless (and (executable-find "gcc")
+ (not (ert-gcc-is-clang-p))))
(let ((semantic-gcc-test-strings (list (semantic-gcc-query "gcc" "-v"))))
- ;; Some macOS machines run llvm when you type gcc. (!)
- ;; We can't even check if it's a symlink; it's a binary placed in
- ;; "/usr/bin/gcc". So check the output and just skip this test if
- ;; it looks like that's the case.
- (unless (string-match "Apple \\(LLVM\\|clang\\)\\|Xcode\\.app"
- (car semantic-gcc-test-strings))
- (semantic-gcc-test-output-parser))))
+ (semantic-gcc-test-output-parser)))
;;; gcc-tests.el ends here
diff --git a/test/lisp/cedet/srecode-utest-template.el b/test/lisp/cedet/srecode-utest-template.el
index 1eb91e6053b..87c28c6af12 100644
--- a/test/lisp/cedet/srecode-utest-template.el
+++ b/test/lisp/cedet/srecode-utest-template.el
@@ -33,7 +33,7 @@
;;; MAP DUMP TESTING
(defun srecode-utest-map-reset ()
"Reset, then dump the map of SRecoder templates.
-Probably should be called 'describe-srecode-maps'."
+Probably should be called `describe-srecode-maps'."
(interactive)
(message "SRecode Template Path: %S" srecode-map-load-path)
;; Interactive call allows us to dump.
diff --git a/test/lisp/cedet/srecode/document-tests.el b/test/lisp/cedet/srecode/document-tests.el
index 71c4cd7410b..5341bb09366 100644
--- a/test/lisp/cedet/srecode/document-tests.el
+++ b/test/lisp/cedet/srecode/document-tests.el
@@ -35,8 +35,6 @@
"Test old comment extraction.
Dump out the extracted dictionary."
:tags '(:unstable)
- (interactive)
-
(srecode-load-tables-for-mode major-mode)
(srecode-load-tables-for-mode major-mode 'document)
diff --git a/test/lisp/cedet/srecode/fields-tests.el b/test/lisp/cedet/srecode/fields-tests.el
index 5e41010f3cd..292ac4e3b5e 100644
--- a/test/lisp/cedet/srecode/fields-tests.el
+++ b/test/lisp/cedet/srecode/fields-tests.el
@@ -57,8 +57,7 @@ It is filled with some text."
(end-of-line)
(forward-word -1)
- (setq f (srecode-field "Test"
- :name "TEST"
+ (setq f (srecode-field :name "TEST"
:start 6
:end 8))
@@ -99,19 +98,17 @@ It is filled with some text."
(reg nil)
(fields
(list
- (srecode-field "Test1" :name "TEST-1" :start 5 :end 10)
- (srecode-field "Test2" :name "TEST-2" :start 15 :end 20)
- (srecode-field "Test3" :name "TEST-3" :start 25 :end 30)
+ (srecode-field :name "TEST-1" :start 5 :end 10)
+ (srecode-field :name "TEST-2" :start 15 :end 20)
+ (srecode-field :name "TEST-3" :start 25 :end 30)
- (srecode-field "Test4" :name "TEST-4" :start 35 :end 35))
- ))
+ (srecode-field :name "TEST-4" :start 35 :end 35))))
(when (not (= (length srecode-field-archive) 4))
(error "Region Test: Found %d fields. Expected 4"
(length srecode-field-archive)))
- (setq reg (srecode-template-inserted-region "REG"
- :start 4
+ (setq reg (srecode-template-inserted-region :start 4
:end 40))
(srecode-overlaid-activate reg)
@@ -183,10 +180,10 @@ It is filled with some text."
;; Test variable linkage.
(let* ((srecode-field-archive nil)
- (f1 (srecode-field "Test1" :name "TEST" :start 6 :end 8))
- (f2 (srecode-field "Test2" :name "TEST" :start 28 :end 30))
- (f3 (srecode-field "Test3" :name "NOTTEST" :start 35 :end 40))
- (reg (srecode-template-inserted-region "REG" :start 4 :end 40)))
+ (f1 (srecode-field :name "TEST" :start 6 :end 8))
+ (f2 (srecode-field :name "TEST" :start 28 :end 30))
+ (f3 (srecode-field :name "NOTTEST" :start 35 :end 40))
+ (reg (srecode-template-inserted-region :start 4 :end 40)))
(srecode-overlaid-activate reg)
(when (not (string= (srecode-overlaid-text f1)
diff --git a/test/lisp/color-tests.el b/test/lisp/color-tests.el
index 49b632c8410..e4e1eda26d3 100644
--- a/test/lisp/color-tests.el
+++ b/test/lisp/color-tests.el
@@ -220,32 +220,32 @@
(ert-deftest color-tests-lighten-hsl ()
(should (equal (color-lighten-hsl 360 0.5 0.5 0) '(360 0.5 0.5)))
- (should (equal (color-lighten-hsl 360 0.5 0.5 -10) '(360 0.5 0.4)))
+ (should (equal (color-lighten-hsl 360 0.5 0.5 -10) '(360 0.5 0.45)))
(should (equal (color-lighten-hsl 360 0.5 0.5 -500) '(360 0.5 0.0)))
(should
(color-tests--approx-equal
- (color-lighten-hsl 120 0.5 0.8 5) '(120 0.5 0.85)))
+ (color-lighten-hsl 120 0.5 0.8 5) '(120 0.5 0.84)))
(should
(equal (color-lighten-hsl 120 0.5 0.8 500) '(120 0.5 1.0))))
(ert-deftest color-tests-lighten-name ()
- (should (equal (color-lighten-name "black" 100) "#ffffffffffff"))
+ (should (equal (color-lighten-name "black" 100) "#000000000000"))
(should (equal (color-lighten-name "white" 100) "#ffffffffffff"))
(should (equal (color-lighten-name "red" 0) "#ffff00000000"))
- (should (equal (color-lighten-name "red" 10) "#ffff33323332")))
+ (should (equal (color-lighten-name "red" 10) "#ffff19991999")))
(ert-deftest color-tests-darken-hsl ()
(should (equal (color-darken-hsl 360 0.5 0.5 0) '(360 0.5 0.5)))
- (should (equal (color-darken-hsl 360 0.5 0.5 -10) '(360 0.5 0.6)))
+ (should (equal (color-darken-hsl 360 0.5 0.5 -10) '(360 0.5 0.55)))
(should (equal (color-darken-hsl 360 0.5 0.5 -500) '(360 0.5 1.0)))
- (should (equal (color-darken-hsl 120 0.5 0.8 5) '(120 0.5 0.75)))
+ (should (equal (color-darken-hsl 120 0.5 0.8 5) '(120 0.5 0.76)))
(should (equal (color-darken-hsl 120 0.5 0.8 500) '(120 0.5 0.0))))
(ert-deftest color-tests-darken-name ()
(should (equal (color-darken-name "black" 100) "#000000000000"))
(should (equal (color-darken-name "white" 100) "#000000000000"))
(should (equal (color-darken-name "red" 0) "#ffff00000000"))
- (should (equal (color-darken-name "red" 10) "#cccc00000000")))
+ (should (equal (color-darken-name "red" 10) "#e66500000000")))
(provide 'color-tests)
;;; color-tests.el ends here
diff --git a/test/lisp/comint-tests.el b/test/lisp/comint-tests.el
index b284aa871ef..2885aaa9146 100644
--- a/test/lisp/comint-tests.el
+++ b/test/lisp/comint-tests.el
@@ -43,6 +43,7 @@
"PIN for user:" ; Bug#35523
"Password (again):"
"Enter password:"
+ "(user@host) Password: " ; openssh-8.6p1
"Current password:" ; "passwd" (to change password) in Debian.
"Enter encryption key: " ; ccrypt
"Enter decryption key: " ; ccrypt
diff --git a/test/lisp/cus-edit-tests.el b/test/lisp/cus-edit-tests.el
index 01a1407dcaa..0ef5168109b 100644
--- a/test/lisp/cus-edit-tests.el
+++ b/test/lisp/cus-edit-tests.el
@@ -76,5 +76,14 @@
(customize-saved)
(should (search-forward cus-edit-tests--obsolete-option-tag nil t)))))
+(defcustom cus-edit-test-foo1 0
+ ""
+ :type 'number)
+
+(ert-deftest test-setopt ()
+ (should (= (setopt cus-edit-test-foo1 1) 1))
+ (should (= cus-edit-test-foo1 1))
+ (should-error (setopt cus-edit-test-foo1 :foo)))
+
(provide 'cus-edit-tests)
;;; cus-edit-tests.el ends here
diff --git a/test/lisp/custom-tests.el b/test/lisp/custom-tests.el
index 2a0b0fc012c..d1effaa72a8 100644
--- a/test/lisp/custom-tests.el
+++ b/test/lisp/custom-tests.el
@@ -24,21 +24,11 @@
(require 'wid-edit)
(require 'cus-edit)
-
-(defmacro custom-tests--with-temp-dir (&rest body)
- "Eval BODY with `temporary-file-directory' bound to a fresh directory.
-Ensure the directory is recursively deleted after the fact."
- (declare (debug t) (indent 0))
- (let ((dir (make-symbol "dir")))
- `(let ((,dir (file-name-as-directory (make-temp-file "custom-tests-" t))))
- (unwind-protect
- (let ((temporary-file-directory ,dir))
- ,@body)
- (delete-directory ,dir t)))))
+(require 'bytecomp)
(ert-deftest custom-theme--load-path ()
"Test `custom-theme--load-path' behavior."
- (custom-tests--with-temp-dir
+ (ert-with-temp-directory temporary-file-directory
;; Path is empty.
(let ((custom-theme-load-path ()))
(should (null (custom-theme--load-path))))
@@ -50,28 +40,28 @@ Ensure the directory is recursively deleted after the fact."
(should (null (custom-theme--load-path))))
;; Path comprises existing file.
- (let* ((file (make-temp-file "file"))
- (custom-theme-load-path (list file)))
- (should (file-exists-p file))
- (should (not (file-directory-p file)))
- (should (null (custom-theme--load-path))))
+ (ert-with-temp-file file
+ (let* ((custom-theme-load-path (list file)))
+ (should (file-exists-p file))
+ (should (not (file-directory-p file)))
+ (should (null (custom-theme--load-path)))))
;; Path comprises existing directory.
- (let* ((dir (make-temp-file "dir" t))
- (custom-theme-load-path (list dir)))
- (should (file-directory-p dir))
- (should (equal (custom-theme--load-path) custom-theme-load-path)))
+ (ert-with-temp-directory dir
+ (let* ((custom-theme-load-path (list dir)))
+ (should (file-directory-p dir))
+ (should (equal (custom-theme--load-path) custom-theme-load-path))))
;; Expand `custom-theme-directory' path element.
(let ((custom-theme-load-path '(custom-theme-directory)))
(let ((custom-theme-directory (make-temp-name temporary-file-directory)))
(should (not (file-exists-p custom-theme-directory)))
(should (null (custom-theme--load-path))))
- (let ((custom-theme-directory (make-temp-file "file")))
+ (ert-with-temp-file custom-theme-directory
(should (file-exists-p custom-theme-directory))
(should (not (file-directory-p custom-theme-directory)))
(should (null (custom-theme--load-path))))
- (let ((custom-theme-directory (make-temp-file "dir" t)))
+ (ert-with-temp-directory custom-theme-directory
(should (file-directory-p custom-theme-directory))
(should (equal (custom-theme--load-path)
(list custom-theme-directory)))))
@@ -97,7 +87,7 @@ Ensure the directory is recursively deleted after the fact."
(ert-deftest custom-tests-require-theme ()
"Test `require-theme'."
(require 'warnings)
- (custom-tests--with-temp-dir
+ (ert-with-temp-directory temporary-file-directory
(let* ((default-directory temporary-file-directory)
(custom-theme-load-path (list default-directory))
(load-path ()))
diff --git a/test/lisp/desktop-tests.el b/test/lisp/desktop-tests.el
new file mode 100644
index 00000000000..d52fe39ed96
--- /dev/null
+++ b/test/lisp/desktop-tests.el
@@ -0,0 +1,50 @@
+;;; desktop-tests.el --- Tests for desktop.el -*- lexical-binding: t -*-
+
+;; Copyright (C) 2020 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'ert)
+(require 'desktop)
+
+(ert-deftest desktop-tests--emacs-pid-running-p ()
+ (should (desktop--emacs-pid-running-p (emacs-pid)))
+ (should-not (desktop--emacs-pid-running-p 1)))
+
+(ert-deftest desktop-tests--load-locked-desktop-p ()
+ (let ((desktop-load-locked-desktop t))
+ (should (desktop--load-locked-desktop-p (emacs-pid)))))
+
+(ert-deftest desktop-tests--load-locked-desktop-p-nil ()
+ (let ((desktop-load-locked-desktop nil))
+ (should-not (desktop--load-locked-desktop-p (emacs-pid)))))
+
+(ert-deftest desktop-tests--load-locked-desktop-p-ask ()
+ (let ((desktop-load-locked-desktop 'ask))
+ (cl-letf (((symbol-function 'y-or-n-p) (lambda (&rest _) t)))
+ (should (desktop--load-locked-desktop-p (emacs-pid))))
+ (cl-letf (((symbol-function 'y-or-n-p) (lambda (&rest _) nil)))
+ (should-not (desktop--load-locked-desktop-p (emacs-pid))))))
+
+(ert-deftest desktop-tests--load-locked-desktop-p-check ()
+ (let ((desktop-load-locked-desktop 'check-pid))
+ (desktop--load-locked-desktop-p (emacs-pid))))
+
+(provide 'desktop-tests)
diff --git a/test/lisp/dired-aux-tests.el b/test/lisp/dired-aux-tests.el
index 3ffcd529cae..694deaae4c2 100644
--- a/test/lisp/dired-aux-tests.el
+++ b/test/lisp/dired-aux-tests.el
@@ -19,26 +19,25 @@
;;; Code:
(require 'ert)
+(require 'ert-x)
(require 'dired-aux)
(eval-when-compile (require 'cl-lib))
(ert-deftest dired-test-bug27496 ()
"Test for https://debbugs.gnu.org/27496 ."
(skip-unless (executable-find shell-file-name))
- (let* ((foo (make-temp-file "foo"))
- (files (list foo)))
- (unwind-protect
- (cl-letf (((symbol-function 'read-char-from-minibuffer) 'error))
- (dired temporary-file-directory)
- (dired-goto-file foo)
- ;; `dired-do-shell-command' returns nil on success.
- (should-error (dired-do-shell-command "ls ? ./?" nil files))
- (should-error (dired-do-shell-command "ls ./? ?" nil files))
- (should-not (dired-do-shell-command "ls ? ?" nil files))
- (should-error (dired-do-shell-command "ls * ./*" nil files))
- (should-not (dired-do-shell-command "ls * *" nil files))
- (should-not (dired-do-shell-command "ls ? ./`?`" nil files)))
- (delete-file foo))))
+ (ert-with-temp-file foo
+ (let* ((files (list foo)))
+ (cl-letf (((symbol-function 'read-char-from-minibuffer) 'error))
+ (dired temporary-file-directory)
+ (dired-goto-file foo)
+ ;; `dired-do-shell-command' returns nil on success.
+ (should-error (dired-do-shell-command "ls ? ./?" nil files))
+ (should-error (dired-do-shell-command "ls ./? ?" nil files))
+ (should-not (dired-do-shell-command "ls ? ?" nil files))
+ (should-error (dired-do-shell-command "ls * ./*" nil files))
+ (should-not (dired-do-shell-command "ls * *" nil files))
+ (should-not (dired-do-shell-command "ls ? ./`?`" nil files))))))
;; Auxiliary macro for `dired-test-bug28834': it binds
;; `dired-create-destination-dirs' to CREATE-DIRS and execute BODY.
@@ -47,28 +46,25 @@
(defmacro with-dired-bug28834-test (create-dirs yes-or-no &rest body)
(declare (debug (form symbolp body)))
(let ((foo (make-symbol "foo")))
- `(let* ((,foo (make-temp-file "foo" 'dir))
- (dired-create-destination-dirs ,create-dirs))
- (setq from (make-temp-file "from"))
- (setq to-cp
- (expand-file-name
- "foo-cp" (file-name-as-directory (expand-file-name "bar" ,foo))))
- (setq to-mv
- (expand-file-name
- "foo-mv" (file-name-as-directory (expand-file-name "qux" ,foo))))
- (unwind-protect
- (if ,yes-or-no
- (cl-letf (((symbol-function 'yes-or-no-p)
- (lambda (_prompt) (eq ,yes-or-no 'yes))))
- ,@body)
- ,@body)
- ;; clean up
- (delete-directory ,foo 'recursive)
- (delete-file from)))))
+ `(ert-with-temp-directory ,foo
+ (ert-with-temp-file from
+ (let* ((dired-create-destination-dirs ,create-dirs))
+ (setq to-cp
+ (expand-file-name
+ "foo-cp" (file-name-as-directory (expand-file-name "bar" ,foo))))
+ (setq to-mv
+ (expand-file-name
+ "foo-mv" (file-name-as-directory (expand-file-name "qux" ,foo))))
+ (unwind-protect
+ (if ,yes-or-no
+ (cl-letf (((symbol-function 'yes-or-no-p)
+ (lambda (_prompt) (eq ,yes-or-no 'yes))))
+ ,@body)
+ ,@body)))))))
(ert-deftest dired-test-bug28834 ()
"test for https://debbugs.gnu.org/28834 ."
- (let (from to-cp to-mv)
+ (let (to-cp to-mv)
;; `dired-create-destination-dirs' set to 'always.
(with-dired-bug28834-test
'always nil
diff --git a/test/lisp/dired-resources/insert-directory/test_dir/bar b/test/lisp/dired-resources/insert-directory/test_dir/bar
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/test/lisp/dired-resources/insert-directory/test_dir/bar
diff --git a/test/lisp/dired-resources/insert-directory/test_dir/foo b/test/lisp/dired-resources/insert-directory/test_dir/foo
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/test/lisp/dired-resources/insert-directory/test_dir/foo
diff --git a/test/lisp/dired-resources/insert-directory/test_dir_other/bar b/test/lisp/dired-resources/insert-directory/test_dir_other/bar
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/test/lisp/dired-resources/insert-directory/test_dir_other/bar
diff --git a/test/lisp/dired-resources/insert-directory/test_dir_other/foo b/test/lisp/dired-resources/insert-directory/test_dir_other/foo
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/test/lisp/dired-resources/insert-directory/test_dir_other/foo
diff --git a/test/lisp/dired-tests.el b/test/lisp/dired-tests.el
index 62aa5af573d..0e893259077 100644
--- a/test/lisp/dired-tests.el
+++ b/test/lisp/dired-tests.el
@@ -19,6 +19,7 @@
;;; Code:
(require 'ert)
+(require 'ert-x)
(require 'dired)
(ert-deftest dired-autoload ()
@@ -141,116 +142,113 @@
(ert-deftest dired-test-bug27243-01 ()
"Test for https://debbugs.gnu.org/cgi/bugreport.cgi?bug=27243#5 ."
- (let* ((test-dir (file-name-as-directory (make-temp-file "test-dir-" t)))
- (save-pos (lambda ()
- (with-current-buffer (car (dired-buffers-for-dir test-dir))
- (dired-save-positions))))
- (dired-auto-revert-buffer t) buffers)
- ;; On MS-Windows, get rid of 8+3 short names in test-dir, if the
- ;; corresponding long file names exist, otherwise such names trip
- ;; dired-buffers-for-dir.
- (if (eq system-type 'windows-nt)
- (setq test-dir (file-truename test-dir)))
- (should-not (dired-buffers-for-dir test-dir))
- (with-current-buffer (find-file-noselect test-dir)
- (make-directory "test-subdir"))
- (message "Saved pos: %S" (funcall save-pos))
- ;; Point must be at end-of-buffer.
- (with-current-buffer (car (dired-buffers-for-dir test-dir))
- (should (eobp)))
- (push (dired test-dir) buffers)
- (message "Saved pos: %S" (funcall save-pos))
- ;; Previous dired call shouldn't create a new buffer: must visit the one
- ;; created by `find-file-noselect' above.
- (should (eq 1 (length (dired-buffers-for-dir test-dir))))
- (unwind-protect
- (let ((buf (current-buffer))
- (pt1 (point))
- (test-file (concat (file-name-as-directory "test-subdir")
- "test-file")))
- (message "Saved pos: %S" (funcall save-pos))
- (write-region "Test" nil test-file nil 'silent nil 'excl)
- (message "Saved pos: %S" (funcall save-pos))
- ;; Sanity check: point should now be on the subdirectory.
- (should (equal (dired-file-name-at-point)
- (concat test-dir (file-name-as-directory "test-subdir"))))
- (message "Saved pos: %S" (funcall save-pos))
- (push (dired-find-file) buffers)
- (let ((pt2 (point))) ; Point is on test-file.
- (pop-to-buffer-same-window buf)
- ;; Sanity check: point should now be back on the subdirectory.
- (should (eq (point) pt1))
+ (ert-with-temp-directory test-dir
+ (let* ((save-pos (lambda ()
+ (with-current-buffer (car (dired-buffers-for-dir test-dir))
+ (dired-save-positions))))
+ (dired-auto-revert-buffer t) buffers)
+ ;; On MS-Windows, get rid of 8+3 short names in test-dir, if the
+ ;; corresponding long file names exist, otherwise such names trip
+ ;; dired-buffers-for-dir.
+ (if (eq system-type 'windows-nt)
+ (setq test-dir (file-truename test-dir)))
+ (should-not (dired-buffers-for-dir test-dir))
+ (with-current-buffer (find-file-noselect test-dir)
+ (make-directory "test-subdir"))
+ (message "Saved pos: %S" (funcall save-pos))
+ ;; Point must be at end-of-buffer.
+ (with-current-buffer (car (dired-buffers-for-dir test-dir))
+ (should (eobp)))
+ (push (dired test-dir) buffers)
+ (message "Saved pos: %S" (funcall save-pos))
+ ;; Previous dired call shouldn't create a new buffer: must visit the one
+ ;; created by `find-file-noselect' above.
+ (should (eq 1 (length (dired-buffers-for-dir test-dir))))
+ (unwind-protect
+ (let ((buf (current-buffer))
+ (pt1 (point))
+ (test-file (concat (file-name-as-directory "test-subdir")
+ "test-file")))
+ (message "Saved pos: %S" (funcall save-pos))
+ (write-region "Test" nil test-file nil 'silent nil 'excl)
+ (message "Saved pos: %S" (funcall save-pos))
+ ;; Sanity check: point should now be on the subdirectory.
+ (should (equal (dired-file-name-at-point)
+ (concat test-dir (file-name-as-directory "test-subdir"))))
+ (message "Saved pos: %S" (funcall save-pos))
(push (dired-find-file) buffers)
- (should (eq (point) pt2))))
- (dolist (buf buffers)
- (when (buffer-live-p buf) (kill-buffer buf)))
- (delete-directory test-dir t))))
+ (let ((pt2 (point))) ; Point is on test-file.
+ (pop-to-buffer-same-window buf)
+ ;; Sanity check: point should now be back on the subdirectory.
+ (should (eq (point) pt1))
+ (push (dired-find-file) buffers)
+ (should (eq (point) pt2))))
+ (dolist (buf buffers)
+ (when (buffer-live-p buf) (kill-buffer buf)))))))
(ert-deftest dired-test-bug27243-02 ()
"Test for https://debbugs.gnu.org/cgi/bugreport.cgi?bug=27243#28 ."
- (let ((test-dir (make-temp-file "test-dir-" t))
- (dired-auto-revert-buffer t) buffers)
- ;; On MS-Windows, get rid of 8+3 short names in test-dir, if the
- ;; corresponding long file names exist, otherwise such names trip
- ;; string comparisons below.
- (if (eq system-type 'windows-nt)
- (setq test-dir (file-truename test-dir)))
- (with-current-buffer (find-file-noselect test-dir)
- (make-directory "test-subdir"))
- (push (dired test-dir) buffers)
- (unwind-protect
- (let ((buf (current-buffer))
- (pt1 (point))
- (test-file (concat (file-name-as-directory "test-subdir")
- "test-file")))
- (write-region "Test" nil test-file nil 'silent nil 'excl)
- ;; Sanity check: point should now be on the subdirectory.
- (should (equal (dired-file-name-at-point)
- (concat (file-name-as-directory test-dir)
- (file-name-as-directory "test-subdir"))))
- (push (dired-find-file) buffers)
- ;; Point is on test-file.
- (switch-to-buffer buf)
- ;; Sanity check: point should now be back on the subdirectory.
- (should (eq (point) pt1))
- (push (dired test-dir) buffers)
- (should (eq (point) pt1)))
- (dolist (buf buffers)
- (when (buffer-live-p buf) (kill-buffer buf)))
- (delete-directory test-dir t))))
+ (ert-with-temp-directory test-dir
+ (let ((dired-auto-revert-buffer t) buffers)
+ ;; On MS-Windows, get rid of 8+3 short names in test-dir, if the
+ ;; corresponding long file names exist, otherwise such names trip
+ ;; string comparisons below.
+ (if (eq system-type 'windows-nt)
+ (setq test-dir (file-truename test-dir)))
+ (with-current-buffer (find-file-noselect test-dir)
+ (make-directory "test-subdir"))
+ (push (dired test-dir) buffers)
+ (unwind-protect
+ (let ((buf (current-buffer))
+ (pt1 (point))
+ (test-file (concat (file-name-as-directory "test-subdir")
+ "test-file")))
+ (write-region "Test" nil test-file nil 'silent nil 'excl)
+ ;; Sanity check: point should now be on the subdirectory.
+ (should (equal (dired-file-name-at-point)
+ (concat (file-name-as-directory test-dir)
+ (file-name-as-directory "test-subdir"))))
+ (push (dired-find-file) buffers)
+ ;; Point is on test-file.
+ (switch-to-buffer buf)
+ ;; Sanity check: point should now be back on the subdirectory.
+ (should (eq (point) pt1))
+ (push (dired test-dir) buffers)
+ (should (eq (point) pt1)))
+ (dolist (buf buffers)
+ (when (buffer-live-p buf) (kill-buffer buf)))))))
(ert-deftest dired-test-bug27243-03 ()
"Test for https://debbugs.gnu.org/cgi/bugreport.cgi?bug=27243#61 ."
- (let ((test-dir (make-temp-file "test-dir-" t))
- (dired-auto-revert-buffer t)
- allbufs)
- (unwind-protect
- (progn
- (with-current-buffer (find-file-noselect test-dir)
- (push (current-buffer) allbufs)
- (make-directory "test-subdir1")
- (make-directory "test-subdir2")
- (let ((test-file1 "test-file1")
- (test-file2 "test-file2"))
- (with-current-buffer (find-file-noselect "test-subdir1")
- (push (current-buffer) allbufs)
- (write-region "Test1" nil test-file1 nil 'silent nil 'excl))
- (with-current-buffer (find-file-noselect "test-subdir2")
- (push (current-buffer) allbufs)
- (write-region "Test2" nil test-file2 nil 'silent nil 'excl))))
- ;; Call find-file with a wild card and test point in each file.
- (let ((buffers (find-file (concat (file-name-as-directory test-dir)
- "*")
- t)))
- (dolist (buf buffers)
- (let ((pt (with-current-buffer buf (point))))
- (switch-to-buffer (find-file-noselect test-dir))
- (find-file (buffer-name buf))
- (should (equal (point) pt))))
- (append buffers allbufs)))
- (dolist (buf allbufs)
- (when (buffer-live-p buf) (kill-buffer buf)))
- (delete-directory test-dir t))))
+ (ert-with-temp-directory test-dir
+ (let ((dired-auto-revert-buffer t)
+ allbufs)
+ (unwind-protect
+ (progn
+ (with-current-buffer (find-file-noselect test-dir)
+ (push (current-buffer) allbufs)
+ (make-directory "test-subdir1")
+ (make-directory "test-subdir2")
+ (let ((test-file1 "test-file1")
+ (test-file2 "test-file2"))
+ (with-current-buffer (find-file-noselect "test-subdir1")
+ (push (current-buffer) allbufs)
+ (write-region "Test1" nil test-file1 nil 'silent nil 'excl))
+ (with-current-buffer (find-file-noselect "test-subdir2")
+ (push (current-buffer) allbufs)
+ (write-region "Test2" nil test-file2 nil 'silent nil 'excl))))
+ ;; Call find-file with a wild card and test point in each file.
+ (let ((buffers (find-file (concat (file-name-as-directory test-dir)
+ "*")
+ t)))
+ (dolist (buf buffers)
+ (let ((pt (with-current-buffer buf (point))))
+ (switch-to-buffer (find-file-noselect test-dir))
+ (find-file (buffer-name buf))
+ (should (equal (point) pt))))
+ (append buffers allbufs)))
+ (dolist (buf allbufs)
+ (when (buffer-live-p buf) (kill-buffer buf)))))))
(ert-deftest dired-test-bug7131 ()
"Test for https://debbugs.gnu.org/7131 ."
@@ -274,22 +272,21 @@
;; ls-lisp-tests.el and em-ls-tests.el.
(skip-unless (and (not (featurep 'ls-lisp))
(not (featurep 'eshell))))
- (let* ((dir (make-temp-file "bug27631" 'dir))
- (dir1 (expand-file-name "dir1" dir))
- (dir2 (expand-file-name "dir2" dir))
- (default-directory dir)
- buf)
- (unwind-protect
- (progn
- (make-directory dir1)
- (make-directory dir2)
- (with-temp-file (expand-file-name "a.txt" dir1))
- (with-temp-file (expand-file-name "b.txt" dir2))
- (setq buf (dired (expand-file-name "dir*/*.txt" dir)))
- (dired-toggle-marks)
- (should (cdr (dired-get-marked-files))))
- (delete-directory dir 'recursive)
- (when (buffer-live-p buf) (kill-buffer buf)))))
+ (ert-with-temp-directory dir
+ (let* ((dir1 (expand-file-name "dir1" dir))
+ (dir2 (expand-file-name "dir2" dir))
+ (default-directory dir)
+ buf)
+ (unwind-protect
+ (progn
+ (make-directory dir1)
+ (make-directory dir2)
+ (with-temp-file (expand-file-name "a.txt" dir1))
+ (with-temp-file (expand-file-name "b.txt" dir2))
+ (setq buf (dired (expand-file-name "dir*/*.txt" dir)))
+ (dired-toggle-marks)
+ (should (cdr (dired-get-marked-files))))
+ (when (buffer-live-p buf) (kill-buffer buf))))))
(ert-deftest dired-test-bug27899 ()
"Test for https://debbugs.gnu.org/27899 ."
@@ -310,72 +307,69 @@
(ert-deftest dired-test-bug27968 ()
"Test for https://debbugs.gnu.org/27968 ."
- (let* ((top-dir (make-temp-file "top-dir" t))
- (subdir (expand-file-name "subdir" top-dir))
- (header-len-fn (lambda ()
- (save-excursion
- (goto-char 1)
- (forward-line 1)
- (- (point-at-eol) (point)))))
- orig-len len diff pos line-nb)
- (make-directory subdir 'parents)
- (unwind-protect
- (with-current-buffer (dired-noselect subdir)
- (setq orig-len (funcall header-len-fn)
- pos (point)
- line-nb (line-number-at-pos))
- ;; Bug arises when the header line changes its length; this may
- ;; happen if the used space has changed: for instance, with the
- ;; creation of additional files.
- (make-directory "subdir" t)
- (dired-revert)
- ;; Change the header line.
- (save-excursion
- (goto-char 1)
- (forward-line 1)
- (let ((inhibit-read-only t)
- (new-header " test-bug27968"))
- (delete-region (point) (point-at-eol))
- (when (= orig-len (length new-header))
- ;; Wow lucky guy! I must buy lottery today.
- (setq new-header (concat new-header " :-)")))
- (insert new-header)))
- (setq len (funcall header-len-fn)
- diff (- len orig-len))
- (should-not (zerop diff)) ; Header length has changed.
- ;; If diff > 0, then the point moves back.
- ;; If diff < 0, then the point moves forward.
- ;; If diff = 0, then the point doesn't move.
- ;; Sometimes this point movement causes
- ;; line-nb != (line-number-at-pos pos), so that we get
- ;; an unexpected file at point if we store buffer points.
- ;; Note that the line number before/after revert
- ;; doesn't change.
- (should (= line-nb
- (line-number-at-pos)
- (line-number-at-pos (+ pos diff))))
- ;; After revert, the point must be in 'subdir' line.
- (should (equal "subdir" (dired-get-filename 'local t))))
- (delete-directory top-dir t))))
+ (ert-with-temp-directory top-dir
+ (let* ((subdir (expand-file-name "subdir" top-dir))
+ (header-len-fn (lambda ()
+ (save-excursion
+ (goto-char 1)
+ (forward-line 1)
+ (- (point-at-eol) (point)))))
+ orig-len len diff pos line-nb)
+ (make-directory subdir 'parents)
+ (with-current-buffer (dired-noselect subdir)
+ (setq orig-len (funcall header-len-fn)
+ pos (point)
+ line-nb (line-number-at-pos))
+ ;; Bug arises when the header line changes its length; this may
+ ;; happen if the used space has changed: for instance, with the
+ ;; creation of additional files.
+ (make-directory "subdir" t)
+ (dired-revert)
+ ;; Change the header line.
+ (save-excursion
+ (goto-char 1)
+ (forward-line 1)
+ (let ((inhibit-read-only t)
+ (new-header " test-bug27968"))
+ (delete-region (point) (point-at-eol))
+ (when (= orig-len (length new-header))
+ ;; Wow lucky guy! I must buy lottery today.
+ (setq new-header (concat new-header " :-)")))
+ (insert new-header)))
+ (setq len (funcall header-len-fn)
+ diff (- len orig-len))
+ (should-not (zerop diff)) ; Header length has changed.
+ ;; If diff > 0, then the point moves back.
+ ;; If diff < 0, then the point moves forward.
+ ;; If diff = 0, then the point doesn't move.
+ ;; Sometimes this point movement causes
+ ;; line-nb != (line-number-at-pos pos), so that we get
+ ;; an unexpected file at point if we store buffer points.
+ ;; Note that the line number before/after revert
+ ;; doesn't change.
+ (should (= line-nb
+ (line-number-at-pos)
+ (line-number-at-pos (+ pos diff))))
+ ;; After revert, the point must be in 'subdir' line.
+ (should (equal "subdir" (dired-get-filename 'local t)))))))
(defmacro dired-test-with-temp-dirs (just-empty-dirs &rest body)
"Helper macro for Bug#27940 test."
(declare (indent 1) (debug body))
(let ((dir (make-symbol "dir")))
- `(let* ((,dir (make-temp-file "bug27940" t))
- (dired-deletion-confirmer (lambda (_) "yes")) ; Suppress prompts.
- (inhibit-message t)
- (default-directory ,dir))
- (dotimes (i 5) (make-directory (format "empty-dir-%d" i)))
- (unless ,just-empty-dirs
- (dotimes (i 5) (make-directory (format "non-empty-%d/foo" i) 'parents)))
- (make-directory "zeta-empty-dir")
- (unwind-protect
- (progn
- ,@body)
- (delete-directory ,dir t)
- (kill-buffer (current-buffer))))))
+ `(ert-with-temp-directory ,dir
+ (let* ((dired-deletion-confirmer (lambda (_) "yes")) ; Suppress prompts.
+ (inhibit-message t)
+ (default-directory ,dir))
+ (dotimes (i 5) (make-directory (format "empty-dir-%d" i)))
+ (unless ,just-empty-dirs
+ (dotimes (i 5) (make-directory (format "non-empty-%d/foo" i) 'parents)))
+ (make-directory "zeta-empty-dir")
+ (unwind-protect
+ (progn
+ ,@body)
+ (kill-buffer (current-buffer)))))))
(ert-deftest dired-test-bug27940 ()
"Test for https://debbugs.gnu.org/27940 ."
@@ -517,5 +511,92 @@
(when (file-directory-p testdir)
(delete-directory testdir t)))))
+;; `dired-insert-directory' output tests.
+(let* ((data-dir "insert-directory")
+ (test-dir (file-name-as-directory
+ (ert-resource-file
+ (concat data-dir "/test_dir"))))
+ (test-dir-other (file-name-as-directory
+ (ert-resource-file
+ (concat data-dir "/test_dir_other"))))
+ (test-files `(,test-dir "foo" "bar")) ;expected files to be found
+ ;; Free space test data for `insert-directory'.
+ ;; Meaning: (path free-space-bytes-to-stub expected-free-space-string)
+ (free-data `((,test-dir 10 "available 10 B")
+ (,test-dir-other 100 "available 100 B")
+ (:default 999 "available 999 B"))))
+
+ (defun files-tests--look-up-free-data (path)
+ "Look up free space test data, with a default for unspecified paths."
+ (let ((path (file-name-as-directory path)))
+ (cdr (or (assoc path free-data)
+ (assoc :default free-data)))))
+
+ (defun files-tests--make-file-system-info-stub (&optional static-path)
+ "Return a stub for `file-system-info' using dynamic or static test data.
+If that data should be static, pass STATIC-PATH to choose which
+path's data to use."
+ (lambda (path)
+ (let* ((path (cond (static-path)
+ ;; file-system-info knows how to handle ".", so we
+ ;; do the same thing
+ ((equal "." path) default-directory)
+ (path)))
+ (return-size
+ ;; It is always defined but this silences the byte-compiler:
+ (when (fboundp 'files-tests--look-up-free-data)
+ (car (files-tests--look-up-free-data path)))))
+ (list return-size return-size return-size))))
+
+ (defun files-tests--insert-directory-output (dir &optional _verbose)
+ "Run `insert-directory' and return its output."
+ (with-current-buffer-window "files-tests--insert-directory" nil nil
+ (let ((dired-free-space 'separate))
+ (dired-insert-directory dir "-l" nil nil t))
+ (buffer-substring-no-properties (point-min) (point-max))))
+
+ (ert-deftest files-tests-insert-directory-shows-files ()
+ "Verify `insert-directory' reports the files in the directory."
+ ;; It is always defined but this silences the byte-compiler:
+ (when (fboundp 'files-tests--insert-directory-output)
+ (let* ((test-dir (car test-files))
+ (files (cdr test-files))
+ (output (files-tests--insert-directory-output test-dir)))
+ (dolist (file files)
+ (should (string-match-p file output))))))
+
+ (defun files-tests--insert-directory-shows-given-free (dir &optional
+ info-func)
+ "Run `insert-directory' and verify it reports the correct available space.
+Stub `file-system-info' to ensure the available space is consistent,
+either with the given stub function or a default one using test data."
+ ;; It is always defined but this silences the byte-compiler:
+ (when (and (fboundp 'files-tests--make-file-system-info-stub)
+ (fboundp 'files-tests--look-up-free-data)
+ (fboundp 'files-tests--insert-directory-output))
+ (cl-letf (((symbol-function 'file-system-info)
+ (or info-func
+ (files-tests--make-file-system-info-stub))))
+ (should (string-match-p (cadr
+ (files-tests--look-up-free-data dir))
+ (files-tests--insert-directory-output dir t))))))
+
+ (ert-deftest files-tests-insert-directory-shows-free ()
+ "Test that verbose `insert-directory' shows the correct available space."
+ ;; It is always defined but this silences the byte-compiler:
+ (when (and (fboundp 'files-tests--insert-directory-shows-given-free)
+ (fboundp 'files-tests--make-file-system-info-stub))
+ (files-tests--insert-directory-shows-given-free
+ test-dir
+ (files-tests--make-file-system-info-stub test-dir))))
+
+ (ert-deftest files-tests-bug-50630 ()
+ "Verify verbose `insert-directory' shows free space of the target directory.
+The current directory at call time should not affect the result (Bug#50630)."
+ ;; It is always defined but this silences the byte-compiler:
+ (when (fboundp 'files-tests--insert-directory-shows-given-free)
+ (let ((default-directory test-dir-other))
+ (files-tests--insert-directory-shows-given-free test-dir)))))
+
(provide 'dired-tests)
;;; dired-tests.el ends here
diff --git a/test/lisp/dired-x-tests.el b/test/lisp/dired-x-tests.el
index e6228f065d0..cec266b0ef9 100644
--- a/test/lisp/dired-x-tests.el
+++ b/test/lisp/dired-x-tests.el
@@ -19,6 +19,7 @@
;;; Code:
(require 'ert)
+(require 'ert-x)
(require 'dired-x)
@@ -31,23 +32,20 @@
(append (copy-sequence dirs)
(delete "c" (copy-sequence files)))
#'string<))
- (dir (make-temp-file "Bug25942" 'dir))
(extension "c"))
- (unwind-protect
- (progn
- (dolist (d dirs)
- (make-directory (expand-file-name d dir)))
- (dolist (f files)
- (write-region nil nil (expand-file-name f dir)))
- (dired dir)
- (dired-mark-extension extension)
- (should (equal '("bar.c" "foo.c")
- (sort (dired-get-marked-files 'local) #'string<)))
- (dired-unmark-all-marks)
- (dired-mark-suffix extension)
- (should (equal all-but-c
- (sort (dired-get-marked-files 'local) #'string<))))
- (delete-directory dir 'recursive))))
+ (ert-with-temp-directory dir
+ (dolist (d dirs)
+ (make-directory (expand-file-name d dir)))
+ (dolist (f files)
+ (write-region nil nil (expand-file-name f dir)))
+ (dired dir)
+ (dired-mark-extension extension)
+ (should (equal '("bar.c" "foo.c")
+ (sort (dired-get-marked-files 'local) #'string<)))
+ (dired-unmark-all-marks)
+ (dired-mark-suffix extension)
+ (should (equal all-but-c
+ (sort (dired-get-marked-files 'local) #'string<))))))
(ert-deftest dired-guess-default ()
(let ((dired-guess-shell-alist-user nil)
@@ -62,5 +60,15 @@
(should (equal (dired-guess-default '("/tmp/foo.png" "/tmp/foo.txt"))
nil))))
+(ert-deftest dired-x--string-to-number ()
+ (should (= (dired-x--string-to-number "2.4K") 2457.6))
+ (should (= (dired-x--string-to-number "2400") 2400))
+ (should (= (dired-x--string-to-number "123.4M") 129394278.4))
+ (should (= (dired-x--string-to-number "123.40000M") 129394278.4))
+ (should (= (dired-x--string-to-number "4.134") 4134))
+ (should (= (dired-x--string-to-number "4,134") 4134))
+ (should (= (dired-x--string-to-number "4 134") 4134))
+ (should (= (dired-x--string-to-number "41,52,134") 4152134)))
+
(provide 'dired-x-tests)
;;; dired-x-tests.el ends here
diff --git a/test/lisp/dnd-tests.el b/test/lisp/dnd-tests.el
new file mode 100644
index 00000000000..88f6e694577
--- /dev/null
+++ b/test/lisp/dnd-tests.el
@@ -0,0 +1,441 @@
+;;; dnd-tests.el --- Tests for window system independent DND support -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Tests for stuff in dnd.el that doesn't require a window system.
+
+;; The drag API tests only check the behavior of the simplified drag
+;; APIs in dnd.el. Actual drags are not performed during the
+;; automated testing process (make check), but some of the tests can
+;; also be run under X.
+
+;;; Code:
+
+(require 'dnd)
+(require 'cl-lib)
+(require 'tramp)
+(require 'select)
+(require 'ert-x)
+
+(defvar dnd-tests-selection-table nil
+ "Alist of selection names to their values.")
+
+(defvar x-treat-local-requests-remotely)
+(defvar x-dnd-preserve-selection-data)
+
+;; Define some replacements for functions used by the drag-and-drop
+;; code on X when running under something else.
+(unless (eq window-system 'x)
+ ;; Substitute for x-begin-drag, which isn't present on all systems.
+ (defalias 'x-begin-drag
+ (lambda (_targets &optional action frame &rest _)
+ ;; Verify that frame is either nil or a valid frame.
+ (when (and frame (not (frame-live-p frame)))
+ (signal 'wrong-type-argument frame))
+ ;; Verify that the action is valid and pretend the drag succeeded
+ ;; (by returning the action).
+ (cl-ecase action
+ ('XdndActionCopy action)
+ ('XdndActionMove action)
+ ('XdndActionLink action)
+ ;; These two are not technically valid, but x-begin-drag accepts
+ ;; them anyway.
+ ('XdndActionPrivate action)
+ ('XdndActionAsk 'XdndActionPrivate))))
+
+ ;; This doesn't work during tests.
+ (defalias 'gui-set-selection
+ (lambda (type data)
+ (or (gui--valid-simple-selection-p data)
+ (and (vectorp data)
+ (let ((valid t))
+ (dotimes (i (length data))
+ (or (gui--valid-simple-selection-p (aref data i))
+ (setq valid nil)))
+ valid))
+ (signal 'error (list "invalid selection" data)))
+ (setf (alist-get type dnd-tests-selection-table) data))))
+
+(declare-function x-get-selection-internal "xselect.c")
+
+(defun dnd-tests-verify-selection-data (type)
+ "Return the data of the drag-and-drop selection converted to TYPE."
+ (if (eq window-system 'x)
+ (let ((x-treat-local-requests-remotely t))
+ (x-get-selection-internal 'XdndSelection type))
+ (let* ((basic-value (cdr (assq 'XdndSelection
+ dnd-tests-selection-table)))
+ (local-value (if (stringp basic-value)
+ (or (get-text-property 0 type basic-value)
+ basic-value)
+ basic-value))
+ (converter-list (cdr (assq type selection-converter-alist)))
+ (converter (if (consp converter-list)
+ (cdr converter-list)
+ converter-list)))
+ (if (and local-value converter)
+ (funcall converter 'XdndSelection type local-value)
+ (error "No selection converter or local value: %s" type)))))
+
+(defun dnd-tests-remote-accessible-p ()
+ "Return if a test involving remote files can proceed."
+ (ignore-errors
+ (and
+ (file-remote-p ert-remote-temporary-file-directory)
+ (file-directory-p ert-remote-temporary-file-directory)
+ (file-writable-p ert-remote-temporary-file-directory))))
+
+(defun dnd-tests-make-temp-name ()
+ "Return a temporary remote file name for test.
+The temporary file is not created."
+ (expand-file-name (make-temp-name "dnd-test-remote")
+ ert-remote-temporary-file-directory))
+
+(defun dnd-tests-parse-tt-netfile (netfile)
+ "Parse NETFILE and return its components.
+NETFILE should be a canonicalized ToolTalk file name.
+Return a list of its hostname, real path, and local path."
+ (save-match-data
+ (when (string-match (concat "HOST=0-\\([[:digit:]]+\\),RPATH=\\([[:digit:]]+\\)-"
+ "\\([[:digit:]]+\\),LPATH=\\([[:digit:]]+\\)-"
+ "\\([[:digit:]]+\\)\\(:\\)")
+ netfile)
+ (let ((beg (match-end 6)))
+ (list (substring netfile beg
+ (+ beg 1
+ (string-to-number (match-string 1 netfile))))
+ (substring netfile
+ (+ beg
+ (string-to-number (match-string 2 netfile)))
+ (+ beg 1
+ (string-to-number (match-string 3 netfile))))
+ (substring netfile
+ (+ beg
+ (string-to-number (match-string 4 netfile)))
+ (+ beg 1
+ (string-to-number (match-string 5 netfile)))))))))
+
+(defun dnd-tests-extract-selection-data (selection expect-cons)
+ "Return the selection data in SELECTION.
+SELECTION can either be the value of `gui-get-selection', or the
+return value of a selection converter.
+
+If EXPECT-CONS, then expect SELECTION to be a cons (when not
+running under X).
+
+This function only tries to handle strings."
+ (when (and expect-cons (not (eq window-system 'x)))
+ (should (and (consp selection)
+ (stringp (cdr selection)))))
+ (if (stringp selection)
+ selection
+ (cdr selection)))
+
+(ert-deftest dnd-tests-begin-text-drag ()
+ ;; When running this test under X, please make sure to drop onto a
+ ;; program with reasonably correct behavior, such as dtpad, gedit,
+ ;; or Mozilla.
+ ;; ASCII Latin-1 UTF-8
+ (let ((test-text "hello, everyone! sæl öllsömul! всем привет")
+ (x-dnd-preserve-selection-data t))
+ ;; Verify that dragging works.
+ (should (eq (dnd-begin-text-drag test-text) 'copy))
+ (should (eq (dnd-begin-text-drag test-text nil 'move) 'move))
+ ;; Verify that the important data types are converted correctly.
+ (let ((string-data (dnd-tests-verify-selection-data 'STRING)))
+ ;; Check that the Latin-1 target is converted correctly.
+ (should (equal (dnd-tests-extract-selection-data string-data t)
+ (encode-coding-string test-text
+ 'iso-8859-1))))
+ ;; And that UTF8_STRING and the Xdnd UTF8 string are as well.
+ (let* ((string-data (dnd-tests-verify-selection-data
+ 'UTF8_STRING))
+ (string-data-1 (dnd-tests-verify-selection-data
+ 'text/plain\;charset=utf-8))
+ (extracted-1 (dnd-tests-extract-selection-data string-data-1 t))
+ (extracted (dnd-tests-extract-selection-data string-data t)))
+ (should (and (stringp extracted) (stringp extracted-1)))
+ (should (equal extracted extracted)))
+ ;; Now check text/plain.
+ (let ((string-data (dnd-tests-verify-selection-data
+ 'text/plain)))
+ (should (equal (dnd-tests-extract-selection-data string-data t)
+ (encode-coding-string test-text 'ascii))))))
+
+(ert-deftest dnd-tests-begin-file-drag ()
+ ;; These tests also involve handling remote file names.
+ (skip-unless (and (dnd-tests-remote-accessible-p)
+ ;; TODO: make these tests work under X.
+ (not (eq window-system 'x))))
+ (let ((normal-temp-file (expand-file-name (make-temp-name "dnd-test")
+ temporary-file-directory))
+ (normal-multibyte-file (expand-file-name
+ (make-temp-name "тест-на-перетаскивание")
+ temporary-file-directory))
+ (remote-temp-file (dnd-tests-make-temp-name))
+ (x-dnd-preserve-selection-data t))
+ ;; Touch those files if they don't exist.
+ (unless (file-exists-p normal-temp-file)
+ (write-region "" 0 normal-temp-file))
+ (unless (file-exists-p normal-multibyte-file)
+ (write-region "" 0 normal-multibyte-file))
+ (unless (file-exists-p remote-temp-file)
+ (write-region "" 0 remote-temp-file))
+ (unwind-protect
+ (progn
+ ;; Now test dragging a normal file.
+ (should (eq (dnd-begin-file-drag normal-temp-file) 'copy))
+ ;; Test that the selection data is correct.
+ (let ((uri-list-data (cdr (dnd-tests-verify-selection-data 'text/uri-list)))
+ (username-data (dnd-tests-verify-selection-data 'text/x-xdnd-username))
+ (file-name-data (cdr (dnd-tests-verify-selection-data 'FILE_NAME)))
+ (host-name-data (cdr (dnd-tests-verify-selection-data 'HOST_NAME)))
+ (netfile-data (cdr (dnd-tests-verify-selection-data '_DT_NETFILE))))
+ ;; Check if the URI list is formatted correctly.
+ (let* ((split-uri-list (split-string uri-list-data "[\0\r\n]" t))
+ (decoded (dnd-get-local-file-name (car split-uri-list))))
+ (should (equal decoded normal-temp-file)))
+ ;; Test that the username reported is correct.
+ (should (equal username-data (user-real-login-name)))
+ ;; Test that the file name data is correct.
+ (let* ((split-file-names (split-string file-name-data "\0"))
+ (file-name (car split-file-names)))
+ ;; Make sure there are no extra leading or trailing NULL bytes.
+ (should (and split-file-names (null (cdr split-file-names))))
+ ;; Make sure the file name is encoded correctly;
+ (should-not (multibyte-string-p file-name))
+ ;; Make sure decoding the file name results in the
+ ;; originals.
+ (should (equal (decode-coding-string file-name
+ (or file-name-coding-system
+ default-file-name-coding-system))
+ normal-temp-file))
+ ;; Also make sure the hostname is correct.
+ (should (equal host-name-data (system-name))))
+ ;; Check that the netfile hostname, rpath and lpath are correct.
+ (let ((parsed (dnd-tests-parse-tt-netfile netfile-data))
+ (filename (encode-coding-string normal-temp-file
+ (or file-name-coding-system
+ default-file-name-coding-system))))
+ (should (equal (nth 0 parsed) (system-name)))
+ (should (equal (nth 1 parsed) filename))
+ (should (equal (nth 2 parsed) filename))))
+ ;; And the remote file.
+ (should (eq (dnd-begin-file-drag remote-temp-file) 'copy))
+ ;; Test that the remote file was added to the list of files
+ ;; to remove later.
+ (should dnd-last-dragged-remote-file)
+ ;; Make sure the appropriate hook is added so the remote
+ ;; files are removed when Emacs exits.
+ (should (memq #'dnd-remove-last-dragged-remote-file
+ kill-emacs-hook))
+ ;; Test that the remote file was removed.
+ (should (progn
+ (dnd-begin-file-drag normal-temp-file)
+ (not dnd-last-dragged-remote-file)))
+ ;; Make sure the remote file removal hook was deleted.
+ (should-not (memq #'dnd-remove-last-dragged-remote-file
+ kill-emacs-hook))
+ ;; Test that links to remote files can't be created.
+ (should-error (dnd-begin-file-drag remote-temp-file nil 'link))
+ ;; Test dragging a file with a multibyte filename.
+ (should (eq (dnd-begin-file-drag normal-multibyte-file) 'copy))
+ ;; Test that the ToolTalk filename is encodes and decodes correctly.
+ (let* ((netfile-data (cdr (dnd-tests-verify-selection-data '_DT_NETFILE)))
+ (parsed (dnd-tests-parse-tt-netfile netfile-data))
+ (filename (encode-coding-string normal-multibyte-file
+ (or file-name-coding-system
+ default-file-name-coding-system))))
+ (should (equal (nth 0 parsed) (system-name)))
+ (should (equal (nth 1 parsed) filename))
+ (should (equal (nth 2 parsed) filename))))
+ (delete-file normal-temp-file)
+ (delete-file normal-multibyte-file)
+ (delete-file remote-temp-file))))
+
+(ert-deftest dnd-tests-begin-drag-files ()
+ (skip-unless (and (dnd-tests-remote-accessible-p)
+ ;; TODO: make these tests work under X.
+ (not (eq window-system 'x))))
+ (let ((normal-temp-file (expand-file-name (make-temp-name "dnd-test")
+ temporary-file-directory))
+ (normal-temp-file-1 (expand-file-name (make-temp-name "dnd-test")
+ temporary-file-directory))
+ (remote-temp-file (dnd-tests-make-temp-name))
+ (nonexistent-local-file
+ (expand-file-name (make-temp-name "dnd-test")
+ temporary-file-directory))
+ (nonexistent-remote-file (dnd-tests-make-temp-name))
+ (nonexistent-remote-file-1 (dnd-tests-make-temp-name))
+ (x-dnd-preserve-selection-data t))
+ ;; Touch those files if they don't exist.
+ (unless (file-exists-p normal-temp-file)
+ (write-region "" 0 normal-temp-file))
+ (unless (file-exists-p normal-temp-file-1)
+ (write-region "" 0 normal-temp-file))
+ (unless (file-exists-p remote-temp-file)
+ (write-region "" 0 remote-temp-file))
+ (ignore-errors
+ (delete-file nonexistent-local-file)
+ (delete-file nonexistent-remote-file)
+ (delete-file nonexistent-remote-file-1))
+ (unwind-protect
+ (progn
+ ;; Now test dragging a normal file and a remote file.
+ (should (eq (dnd-begin-drag-files (list normal-temp-file
+ remote-temp-file))
+ 'copy))
+ ;; Test that the remote file produced was added to the list
+ ;; of files to remove upon the next call.
+ (should dnd-last-dragged-remote-file)
+ ;; Make sure the appropriate hook is added so the remote
+ ;; files are removed when Emacs exits.
+ (should (memq #'dnd-remove-last-dragged-remote-file
+ kill-emacs-hook))
+ ;; Two local files at the same time.
+ (should (eq (dnd-begin-drag-files (list normal-temp-file
+ normal-temp-file-1))
+ 'copy))
+ ;; Test that the remote files were removed.
+ (should-not dnd-last-dragged-remote-file)
+ ;; And so was the hook.
+ (should-not (memq #'dnd-remove-last-dragged-remote-file
+ kill-emacs-hook))
+ ;; Test the selection data is correct.
+ (let ((uri-list-data (cdr (dnd-tests-verify-selection-data 'text/uri-list)))
+ (username-data (dnd-tests-verify-selection-data 'text/x-xdnd-username))
+ (file-name-data (cdr (dnd-tests-verify-selection-data 'FILE_NAME)))
+ (host-name-data (cdr (dnd-tests-verify-selection-data 'HOST_NAME))))
+ ;; Check if the URI list is formatted correctly.
+ (let* ((split-uri-list (split-string uri-list-data "[\0\r\n]" t))
+ (decoded (mapcar #'dnd-get-local-file-name split-uri-list)))
+ (should (equal (car decoded) normal-temp-file))
+ (should (equal (cadr decoded) normal-temp-file-1)))
+ ;; Test that the username reported is correct.
+ (should (equal username-data (user-real-login-name)))
+ ;; Test that the file name data is correct.
+ (let ((split-file-names (split-string file-name-data "\0")))
+ ;; Make sure there are no extra leading or trailing NULL bytes.
+ (should (equal (length split-file-names) 2))
+ ;; Make sure all file names are encoded correctly;
+ (dolist (name split-file-names)
+ (should-not (multibyte-string-p name)))
+ ;; Make sure decoding the file names result in the
+ ;; originals.
+ (should (equal (decode-coding-string (car split-file-names)
+ (or file-name-coding-system
+ default-file-name-coding-system))
+ normal-temp-file))
+ (should (equal (decode-coding-string (cadr split-file-names)
+ (or file-name-coding-system
+ default-file-name-coding-system))
+ normal-temp-file-1))
+ ;; Also make sure the hostname is correct.
+ (should (equal host-name-data (system-name)))))
+ ;; Multiple local files with some remote files that will
+ ;; fail, and some that won't.
+ (should (and (eq (dnd-begin-drag-files (list normal-temp-file
+ remote-temp-file
+ remote-temp-file
+ nonexistent-remote-file
+ normal-temp-file-1
+ nonexistent-remote-file-1))
+ 'copy)
+ ;; Make sure exactly two valid remote files
+ ;; were downloaded.
+ (eq (length dnd-last-dragged-remote-file) 2)))
+ ;; Make sure the appropriate hook is added so the remote
+ ;; files are removed when Emacs exits.
+ (should (memq #'dnd-remove-last-dragged-remote-file
+ kill-emacs-hook))
+ ;; Make sure links can't be created to remote files.
+ (should-error (dnd-begin-drag-files (list normal-temp-file
+ remote-temp-file
+ normal-temp-file-1)
+ nil 'link))
+ ;; And that they can to normal files.
+ (should (eq (dnd-begin-drag-files (list normal-temp-file
+ normal-temp-file-1)
+ nil 'link)
+ 'link))
+ ;; Make sure the remote file removal hook was deleted.
+ (should-not (memq #'dnd-remove-last-dragged-remote-file
+ kill-emacs-hook))
+ ;; Make sure you can't drag an empty list of files.
+ (should-error (dnd-begin-drag-files nil))
+ ;; And when all remote files are inaccessible.
+ (should-error (dnd-begin-drag-files (list nonexistent-remote-file
+ nonexistent-remote-file-1))))
+ (delete-file normal-temp-file)
+ (delete-file normal-temp-file-1)
+ (delete-file remote-temp-file))))
+
+(ert-deftest dnd-tests-get-local-file-uri ()
+ (should (equal (dnd-get-local-file-uri "file://localhost/path/to/foo")
+ "file:///path/to/foo"))
+ (should (equal (dnd-get-local-file-uri
+ (format "file://%s/path/to/" (system-name)))
+ "file:///path/to/"))
+ (should-not (dnd-get-local-file-uri "file://some-remote-host/path/to/foo"))
+ (should-not (dnd-get-local-file-uri "file:///path/to/foo")))
+
+(ert-deftest dnd-tests-open-remote-url ()
+ ;; Expensive test to make sure opening an FTP URL during
+ ;; drag-and-drop works.
+ :tags '(:expensive-test)
+ ;; Don't run if there is no ftp client.
+ (skip-unless (executable-find "ftp"))
+ ;; Don't run this test if the FTP server isn't reachable.
+ (skip-unless (and (fboundp 'network-lookup-address-info)
+ (network-lookup-address-info "ftp.gnu.org")))
+ ;; Make sure bug#56078 doesn't happen again.
+ (let ((url "ftp://anonymous@ftp.gnu.org/")
+ ;; This prints a bunch of annoying spaces to stdout.
+ (inhibit-message t))
+ (should (prog1 t (dnd-open-remote-url url 'private)))))
+
+(ert-deftest dnd-tests-direct-save ()
+ ;; This test just verifies that a direct save works; the window
+ ;; system specific test is in x-dnd-tests.el. When running this
+ ;; interactively, keep in mind that there are only two file managers
+ ;; which are known to implement XDS correctly: System G (see
+ ;; http://nps-systemg.sourceforge.net), and Emacs itself. GTK file
+ ;; managers such as Nautilus will not work, since they prefer the
+ ;; `text/uri-list' selection target to `XdndDirectSave0', contrary
+ ;; to the XDS specification.
+ (let ((window-system window-system)
+ (normal-temp-file (expand-file-name (make-temp-name "dnd-test")
+ temporary-file-directory)))
+ (unwind-protect
+ (progn
+ (unless (file-exists-p normal-temp-file)
+ (write-region "" 0 normal-temp-file))
+ (unless (eq window-system 'x)
+ ;; Use a window system that isn't X, since we only want to test
+ ;; the fallback code when run non-interactively.
+ (setq window-system 'haiku))
+ (should (eq (dnd-direct-save normal-temp-file
+ (make-temp-name "target-file-name"))
+ 'copy)))
+ (ignore-errors
+ (delete-file normal-temp-file)))))
+
+(provide 'dnd-tests)
+;;; dnd-tests.el ends here
diff --git a/test/lisp/edmacro-tests.el b/test/lisp/edmacro-tests.el
new file mode 100644
index 00000000000..e386342f6ee
--- /dev/null
+++ b/test/lisp/edmacro-tests.el
@@ -0,0 +1,48 @@
+;;; edmacro-tests.el --- Tests for edmacro.el -*- lexical-binding:t -*-
+
+;; Copyright (C) 2021-2022 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'ert)
+(require 'edmacro)
+
+(ert-deftest edmacro-test-edmacro-parse-keys ()
+ (should (equal (edmacro-parse-keys "") []))
+ (should (equal (edmacro-parse-keys "x") [?x]))
+ (should (equal (edmacro-parse-keys "C-a") [?\C-a]))
+
+ ;; comments
+ (should (equal (edmacro-parse-keys ";; foobar") []))
+ (should (equal (edmacro-parse-keys ";;;") []))
+ (should (equal (edmacro-parse-keys "; ; ;") [?\; ?\; ?\;]))
+ (should (equal (edmacro-parse-keys "REM foobar") []))
+ (should (equal (edmacro-parse-keys "x ;; foobar") [?x]))
+ (should (equal (edmacro-parse-keys "x REM foobar") [?x]))
+ (should (equal (edmacro-parse-keys "<<goto-line>>")
+ [?\M-x ?g ?o ?t ?o ?- ?l ?i ?n ?e ?\r]))
+
+ ;; repetitions
+ (should (equal (edmacro-parse-keys "3*x") [?x ?x ?x]))
+ (should (equal (edmacro-parse-keys "3*C-m") [?\C-m ?\C-m ?\C-m]))
+ (should (equal (edmacro-parse-keys "10*foo")
+ (apply #'vconcat (make-list 10 [?f ?o ?o])))))
+
+;;; edmacro-tests.el ends here
diff --git a/test/lisp/electric-tests.el b/test/lisp/electric-tests.el
index 1263767476e..5d7e905cfa3 100644
--- a/test/lisp/electric-tests.el
+++ b/test/lisp/electric-tests.el
@@ -79,7 +79,7 @@
(should (equal (point)
expected-point))))
-(eval-when-compile
+(eval-and-compile
(defun electric-pair-define-test-form (name fixture
char
pos
@@ -97,8 +97,8 @@
(with-temp-buffer
(cl-progv
;; FIXME: avoid `eval'
- (mapcar #'car (eval bindings))
- (mapcar #'cdr (eval bindings))
+ (mapcar #'car (eval bindings t))
+ (mapcar #'cdr (eval bindings t))
(dlet ((python-indent-guess-indent-offset-verbose nil))
(funcall mode)
(insert fixture)
@@ -176,7 +176,7 @@ The buffer's contents should %s:
expected-string
expected-point
bindings
- (modes '(quote (ruby-mode js-mode python-mode)))
+ (modes '(quote (ruby-mode js-mode python-mode c-mode)))
(test-in-comments t)
(test-in-strings t)
(test-in-code t)
@@ -187,7 +187,7 @@ The buffer's contents should %s:
(fixture-fn '#'electric-pair-mode))
`(progn
,@(cl-loop
- for mode in (eval modes) ;FIXME: avoid `eval'
+ for mode in (eval modes t) ;FIXME: avoid `eval'
append
(cl-loop
for (prefix suffix extra-desc) in
@@ -428,7 +428,9 @@ baz\"\""
:bindings '((electric-pair-skip-whitespace . chomp))
:test-in-strings nil
:test-in-code nil
- :test-in-comments t)
+ :test-in-comments t
+ :fixture-fn (lambda () (when (eq major-mode 'c-mode)
+ (c-toggle-comment-style -1))))
(define-electric-pair-test whitespace-skipping-for-quotes-not-outside
" \" \"" "\"-----" :expected-string "\"\" \" \""
@@ -548,16 +550,6 @@ baz\"\""
(electric-indent-mode 1)
(electric-layout-mode 1)))
-(define-electric-pair-test js-mode-braces-with-layout-and-indent
- "" "{" :expected-string "{\n \n}" :expected-point 7
- :modes '(js-mode)
- :test-in-comments nil
- :test-in-strings nil
- :fixture-fn (lambda ()
- (electric-pair-mode 1)
- (electric-indent-mode 1)
- (electric-layout-mode 1)))
-
;;; Backspacing
;;; TODO: better tests
diff --git a/test/lisp/elide-head-tests.el b/test/lisp/elide-head-tests.el
index 7c820db9758..6f351170f1d 100644
--- a/test/lisp/elide-head-tests.el
+++ b/test/lisp/elide-head-tests.el
@@ -28,35 +28,200 @@
(require 'elide-head)
(require 'ert)
+(require 'ert-x)
-(ert-deftest elide-head-tests-elide-head ()
+(ert-deftest elide-head-tests-elide-head-mode ()
(let ((elide-head-headers-to-hide '(("START" . "END"))))
(with-temp-buffer
(insert "foo\nSTART\nHIDDEN\nEND\nbar")
- (elide-head)
+ (elide-head-mode 1)
(let ((o (car (overlays-at 14))))
(should (= (overlay-start o) 10))
(should (= (overlay-end o) 21))
(should (overlay-get o 'invisible))
(should (overlay-get o 'evaporate))))))
-(ert-deftest elide-head-tests-elide-head-with-prefix-arg ()
+(ert-deftest elide-head-tests-elide-head-mode/enable-disable ()
(let ((elide-head-headers-to-hide '(("START" . "END"))))
(with-temp-buffer
(insert "foo\nSTART\nHIDDEN\nEND\nbar")
- (elide-head)
+ (elide-head-mode 1)
(should (overlays-at 14))
- (elide-head t)
+ (elide-head-mode -1)
(should-not (overlays-at 14)))))
-(ert-deftest elide-head-tests-show ()
- (let ((elide-head-headers-to-hide '(("START" . "END"))))
- (with-temp-buffer
- (insert "foo\nSTART\nHIDDEN\nEND\nbar")
- (elide-head)
- (should (overlays-at 14))
- (elide-head-show)
- (should-not (overlays-at 14)))))
+(ert-deftest elide-head-tests-elide-head-mode/normal-mode ()
+ (ert-with-temp-file fil
+ (with-temp-file fil
+ (insert "foo\nSTART\nHIDDEN\nEND\nbar"))
+ (let ((elide-head-headers-to-hide '(("START" . "END")))
+ (buf (find-file-noselect fil)))
+ (save-excursion
+ (unwind-protect
+ (progn
+ (set-buffer buf)
+ (elide-head-mode 1)
+ (should (= 1 (length (overlays-in (point-min) (point-max)))))
+ (normal-mode)
+ (should (= 0 (length (overlays-in (point-min) (point-max))))))
+ (when buf (kill-buffer buf)))))))
+
+(ert-deftest elide-head-tests-elide-head-mode/revert-buffer ()
+ (ert-with-temp-file fil
+ (with-temp-file fil
+ (insert "foo\nSTART\nHIDDEN\nEND\nbar"))
+ (let ((elide-head-headers-to-hide '(("START" . "END")))
+ (buf (find-file-noselect fil)))
+ (save-excursion
+ (unwind-protect
+ (progn
+ (set-buffer buf)
+ (elide-head-mode 1)
+ (should (= 1 (length (overlays-in (point-min) (point-max)))))
+ (revert-buffer nil t)
+ (elide-head-mode 1)
+ (should (= 1 (length (overlays-in (point-min) (point-max))))))
+ (when buf (kill-buffer buf)))))))
+
+
+(defmacro elide-head--add-test (name text search-str)
+ `(ert-deftest ,(intern (format "elide-head--test-headers-to-hide/%s" name)) ()
+ (with-temp-buffer
+ (insert ,text)
+ (elide-head-mode 1)
+ (goto-char (point-min))
+ (re-search-forward ,search-str)
+ (let ((o (car (overlays-at (match-beginning 0)))))
+ (should (overlayp o))
+ (should (overlay-get o 'invisible))
+ (should (overlay-get o 'evaporate))))))
+
+
+;;; GPLv3
+
+;; from Emacs
+(elide-head--add-test gpl3-1 "\
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+" "GNU Emacs is distributed in the hope that")
+
+;; from libtorrent
+(elide-head--add-test gpl3-2 "\
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+" "This library is distributed in the hope that")
+
+;; from notmuch
+(elide-head--add-test gpl3-3 "\
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
+" "This program is distributed in the hope that")
+
+;; from fribok
+(elide-head--add-test gpl3-4 "\
+/***************************************************************************
+ * Copyright (C) 2007, 2009 by J. Random Hacker <jrh@example.org> *
+ * *
+ * This program is free software: you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation, either version 3 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program. If not, see <http://www.gnu.org/licenses/> *.
+ * *
+ ***************************************************************************/
+" "This program is distributed in the hope that")
+
+
+;;; GPLv2
+
+;; from jackmeter
+(elide-head--add-test gpl2-1 "\
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+" "This program is distributed in the hope that")
+
+
+;;; Obsolete
+
+(with-suppressed-warnings ((obsolete elide-head)
+ (obsolete elide-head-show))
+ (ert-deftest elide-head-tests-elide-head ()
+ (let ((elide-head-headers-to-hide '(("START" . "END"))))
+ (with-temp-buffer
+ (insert "foo\nSTART\nHIDDEN\nEND\nbar")
+ (elide-head)
+ (let ((o (car (overlays-at 14))))
+ (should (= (overlay-start o) 10))
+ (should (= (overlay-end o) 21))
+ (should (overlay-get o 'invisible))
+ (should (overlay-get o 'evaporate))))))
+
+ (ert-deftest elide-head-tests-elide-head-with-prefix-arg ()
+ (let ((elide-head-headers-to-hide '(("START" . "END"))))
+ (with-temp-buffer
+ (insert "foo\nSTART\nHIDDEN\nEND\nbar")
+ (elide-head)
+ (should (overlays-at 14))
+ (elide-head t)
+ (should-not (overlays-at 14)))))
+
+ (ert-deftest elide-head-tests-show ()
+ (let ((elide-head-headers-to-hide '(("START" . "END"))))
+ (with-temp-buffer
+ (insert "foo\nSTART\nHIDDEN\nEND\nbar")
+ (elide-head)
+ (should (overlays-at 14))
+ (elide-head-show)
+ (should-not (overlays-at 14))))))
(provide 'elide-head-tests)
;;; elide-head-tests.el ends here
diff --git a/test/lisp/emacs-lisp/backtrace-tests.el b/test/lisp/emacs-lisp/backtrace-tests.el
index 6f099fff173..b08695a22bb 100644
--- a/test/lisp/emacs-lisp/backtrace-tests.el
+++ b/test/lisp/emacs-lisp/backtrace-tests.el
@@ -49,7 +49,7 @@
(setq backtrace-frames (seq-subseq backtrace-frames 0 (1+ this-index))))
(backtrace-print))))
- (eval backtrace-tests--uncompiled-functions))
+ (eval backtrace-tests--uncompiled-functions t))
(defun backtrace-tests--backtrace-lines ()
(if debugger-stack-frame-as-list
diff --git a/test/lisp/emacs-lisp/bindat-tests.el b/test/lisp/emacs-lisp/bindat-tests.el
index 7722cf6c020..0c03c51e2ef 100644
--- a/test/lisp/emacs-lisp/bindat-tests.el
+++ b/test/lisp/emacs-lisp/bindat-tests.el
@@ -36,7 +36,7 @@
(bindat-type
(type u8)
(opcode u8)
- (length uintr 16) ;; little endian order
+ (length uint 16 'le) ;; little endian order
(id strz 8)
(data vec length)
(_ align 4)))
@@ -128,18 +128,17 @@
(r (zerop (% kind 2))))
(dotimes (_ 100)
(let* ((n (random (ash 1 bitlen)))
- (i (- n (ash 1 (1- bitlen)))))
+ (i (- n (ash 1 (1- bitlen))))
+ (stype (bindat-type sint bitlen r))
+ (utype (bindat-type if r (uintr bitlen) (uint bitlen))))
(should (equal (bindat-unpack
- (bindat-type sint bitlen r)
- (bindat-pack (bindat-type sint bitlen r) i))
+ stype
+ (bindat-pack stype i))
i))
(when (>= i 0)
- (should (equal (bindat-pack
- (bindat-type if r (uintr bitlen) (uint bitlen)) i)
- (bindat-pack (bindat-type sint bitlen r) i)))
- (should (equal (bindat-unpack
- (bindat-type if r (uintr bitlen) (uint bitlen))
- (bindat-pack (bindat-type sint bitlen r) i))
+ (should (equal (bindat-pack utype i)
+ (bindat-pack stype i)))
+ (should (equal (bindat-unpack utype (bindat-pack stype i))
i))))))))
(defconst bindat-test--LEB128
@@ -162,4 +161,125 @@
(bindat-pack bindat-test--LEB128 n))
n)))))))
+(ert-deftest bindat-test--str-strz-prealloc ()
+ (dolist (tc `(((,(bindat-type str 1) "") . "xx")
+ ((,(bindat-type str 2) "") . "xx")
+ ((,(bindat-type str 2) "a") . "ax")
+ ((,(bindat-type str 2) "ab") . "ab")
+ ((,(bindat-type str 2) "abc") . "ab")
+ ((((x str 1)) ((x . ""))) . "xx")
+ ((((x str 2)) ((x . ""))) . "xx")
+ ((((x str 2)) ((x . "a"))) . "ax")
+ ((((x str 2)) ((x . "ab"))) . "ab")
+ ((((x str 2)) ((x . "abc"))) . "ab")
+ ((,(bindat-type strz 1) "") . "\0x")
+ ((,(bindat-type strz 2) "") . "\0x")
+ ((,(bindat-type strz 2) "a") . "a\0")
+ ((,(bindat-type strz 2) "ab") . "ab")
+ ((,(bindat-type strz 2) "abc") . "ab")
+ ((((x strz 1)) ((x . ""))) . "\0x")
+ ((((x strz 2)) ((x . ""))) . "\0x")
+ ((((x strz 2)) ((x . "a"))) . "a\0")
+ ((((x strz 2)) ((x . "ab"))) . "ab")
+ ((((x strz 2)) ((x . "abc"))) . "ab")
+ ((,(bindat-type strz) "") . "\0x")
+ ((,(bindat-type strz) "a") . "a\0")))
+ (let ((prealloc (make-string 2 ?x)))
+ (apply #'bindat-pack (append (car tc) (list prealloc)))
+ (should (equal prealloc (cdr tc))))))
+
+(ert-deftest bindat-test--str-strz-multibyte ()
+ (dolist (spec (list (bindat-type str 2)
+ (bindat-type strz 2)
+ (bindat-type strz)))
+ (should (equal (bindat-pack spec (string-to-multibyte "x")) "x\0"))
+ (should (equal (bindat-pack spec (string-to-multibyte "\xff")) "\xff\0"))
+ (should-error (bindat-pack spec "💩"))
+ (should-error (bindat-pack spec "\N{U+ff}")))
+ (dolist (spec (list '((x str 2)) '((x strz 2))))
+ (should (equal (bindat-pack spec `((x . ,(string-to-multibyte "x"))))
+ "x\0"))
+ (should (equal (bindat-pack spec `((x . ,(string-to-multibyte "\xff"))))
+ "\xff\0"))
+ (should-error (bindat-pack spec '((x . "💩"))))
+ (should-error (bindat-pack spec '((x . "\N{U+ff}"))))))
+
+(let ((spec (bindat-type strz 2)))
+ (ert-deftest bindat-test--strz-fixedlen-len ()
+ (should (equal (bindat-length spec "") 2))
+ (should (equal (bindat-length spec "a") 2)))
+
+ (ert-deftest bindat-test--strz-fixedlen-len-overflow ()
+ (should (equal (bindat-length spec "ab") 2))
+ (should (equal (bindat-length spec "abc") 2)))
+
+ (ert-deftest bindat-test--strz-fixedlen-pack ()
+ (should (equal (bindat-pack spec "") "\0\0"))
+ (should (equal (bindat-pack spec "a") "a\0")))
+
+ (ert-deftest bindat-test--strz-fixedlen-pack-overflow ()
+ ;; This is not the only valid semantic, but it's the one we've
+ ;; offered historically.
+ (should (equal (bindat-pack spec "ab") "ab"))
+ (should (equal (bindat-pack spec "abc") "ab")))
+
+ (ert-deftest bindat-test--strz-fixedlen-unpack ()
+ (should (equal (bindat-unpack spec "\0\0") ""))
+ (should (equal (bindat-unpack spec "\0X") ""))
+ (should (equal (bindat-unpack spec "a\0") "a"))
+ ;; Same comment as for b-t-s-f-pack-overflow.
+ (should (equal (bindat-unpack spec "ab") "ab"))
+ ;; Missing null terminator.
+ (should-error (bindat-unpack spec ""))
+ (should-error (bindat-unpack spec "a"))))
+
+(let ((spec (bindat-type strz)))
+ (ert-deftest bindat-test--strz-varlen-len ()
+ (should (equal (bindat-length spec "") 1))
+ (should (equal (bindat-length spec "abc") 4)))
+
+ (ert-deftest bindat-test--strz-varlen-pack ()
+ (should (equal (bindat-pack spec "") "\0"))
+ (should (equal (bindat-pack spec "abc") "abc\0"))
+ ;; Null bytes in the input string break unpacking.
+ (should-error (bindat-pack spec "\0"))
+ (should-error (bindat-pack spec "\0x"))
+ (should-error (bindat-pack spec "x\0"))
+ (should-error (bindat-pack spec "x\0y")))
+
+ (ert-deftest bindat-test--strz-varlen-unpack ()
+ (should (equal (bindat-unpack spec "\0") ""))
+ (should (equal (bindat-unpack spec "abc\0") "abc"))
+ ;; Missing null terminator.
+ (should-error (bindat-unpack spec ""))
+ (should-error (bindat-unpack spec "a"))))
+
+(let ((spec '((x strz 2))))
+ (ert-deftest bindat-test--strz-legacy-fixedlen-len ()
+ (should (equal (bindat-length spec '((x . ""))) 2))
+ (should (equal (bindat-length spec '((x . "a"))) 2)))
+
+ (ert-deftest bindat-test--strz-legacy-fixedlen-len-overflow ()
+ (should (equal (bindat-length spec '((x . "ab"))) 2))
+ (should (equal (bindat-length spec '((x . "abc"))) 2)))
+
+ (ert-deftest bindat-test--strz-legacy-fixedlen-pack ()
+ (should (equal (bindat-pack spec '((x . ""))) "\0\0"))
+ (should (equal (bindat-pack spec '((x . "a"))) "a\0")))
+
+ (ert-deftest bindat-test--strz-legacy-fixedlen-pack-overflow ()
+ ;; Same comment as for b-t-s-f-pack-overflow.
+ (should (equal (bindat-pack spec '((x . "ab"))) "ab"))
+ (should (equal (bindat-pack spec '((x . "abc"))) "ab")))
+
+ (ert-deftest bindat-test--strz-legacy-fixedlen-unpack ()
+ (should (equal (bindat-unpack spec "\0\0") '((x . ""))))
+ (should (equal (bindat-unpack spec "\0X") '((x . ""))))
+ (should (equal (bindat-unpack spec "a\0") '((x . "a"))))
+ ;; Same comment as for b-t-s-f-pack-overflow.
+ (should (equal (bindat-unpack spec "ab") '((x . "ab"))))
+ ;; Missing null terminator.
+ (should-error (bindat-unpack spec ""))
+ (should-error (bindat-unpack spec "a"))))
+
;;; bindat-tests.el ends here
diff --git a/test/lisp/emacs-lisp/bytecomp-resources/fun-attr-warn.el b/test/lisp/emacs-lisp/bytecomp-resources/fun-attr-warn.el
new file mode 100644
index 00000000000..be907b32f47
--- /dev/null
+++ b/test/lisp/emacs-lisp/bytecomp-resources/fun-attr-warn.el
@@ -0,0 +1,266 @@
+;;; -*- lexical-binding: t -*-
+
+;; Correct
+
+(defun faw-str-decl-code (x)
+ "something"
+ (declare (pure t))
+ (print x))
+
+(defun faw-doc-decl-code (x)
+ (:documentation "something")
+ (declare (pure t))
+ (print x))
+
+(defun faw-str-int-code (x)
+ "something"
+ (interactive "P")
+ (print x))
+
+(defun faw-doc-int-code (x)
+ (:documentation "something")
+ (interactive "P")
+ (print x))
+
+(defun faw-decl-int-code (x)
+ (declare (pure t))
+ (interactive "P")
+ (print x))
+
+(defun faw-str-decl-int-code (x)
+ "something"
+ (declare (pure t))
+ (interactive "P")
+ (print x))
+
+(defun faw-doc-decl-int-code (x)
+ (:documentation "something")
+ (declare (pure t))
+ (interactive "P")
+ (print x))
+
+
+;; Correct (last string is return value)
+
+(defun faw-str ()
+ "something")
+
+(defun faw-decl-str ()
+ (declare (pure t))
+ "something")
+
+(defun faw-decl-int-str ()
+ (declare (pure t))
+ (interactive)
+ "something")
+
+(defun faw-str-str ()
+ "something"
+ "something else")
+
+(defun faw-doc-str ()
+ (:documentation "something")
+ "something else")
+
+
+;; Incorrect (bad order)
+
+(defun faw-int-decl-code (x)
+ (interactive "P")
+ (declare (pure t))
+ (print x))
+
+(defun faw-int-str-code (x)
+ (interactive "P")
+ "something"
+ (print x))
+
+(defun faw-int-doc-code (x)
+ (interactive "P")
+ (:documentation "something")
+ (print x))
+
+(defun faw-decl-str-code (x)
+ (declare (pure t))
+ "something"
+ (print x))
+
+(defun faw-decl-doc-code (x)
+ (declare (pure t))
+ (:documentation "something")
+ (print x))
+
+(defun faw-str-int-decl-code (x)
+ "something"
+ (interactive "P")
+ (declare (pure t))
+ (print x))
+
+(defun faw-doc-int-decl-code (x)
+ (:documentation "something")
+ (interactive "P")
+ (declare (pure t))
+ (print x))
+
+(defun faw-int-str-decl-code (x)
+ (interactive "P")
+ "something"
+ (declare (pure t))
+ (print x))
+
+(defun faw-int-doc-decl-code (x)
+ (interactive "P")
+ (:documentation "something")
+ (declare (pure t))
+ (print x))
+
+(defun faw-int-decl-str-code (x)
+ (interactive "P")
+ (declare (pure t))
+ "something"
+ (print x))
+
+(defun faw-int-decl-doc-code (x)
+ (interactive "P")
+ (declare (pure t))
+ (:documentation "something")
+ (print x))
+
+(defun faw-decl-int-str-code (x)
+ (declare (pure t))
+ (interactive "P")
+ "something"
+ (print x))
+
+(defun faw-decl-int-doc-code (x)
+ (declare (pure t))
+ (interactive "P")
+ (:documentation "something")
+ (print x))
+
+(defun faw-decl-str-int-code (x)
+ (declare (pure t))
+ "something"
+ (interactive "P")
+ (print x))
+
+(defun faw-decl-doc-int-code (x)
+ (declare (pure t))
+ (:documentation "something")
+ (interactive "P")
+ (print x))
+
+
+;; Incorrect (duplication)
+
+(defun faw-str-str-decl-int-code (x)
+ "something"
+ "something else"
+ (declare (pure t))
+ (interactive "P")
+ (print x))
+
+(defun faw-str-doc-decl-int-code (x)
+ "something"
+ (:documentation "something else")
+ (declare (pure t))
+ (interactive "P")
+ (print x))
+
+(defun faw-doc-str-decl-int-code (x)
+ (:documentation "something")
+ "something else"
+ (declare (pure t))
+ (interactive "P")
+ (print x))
+
+(defun faw-doc-doc-decl-int-code (x)
+ (:documentation "something")
+ (:documentation "something else")
+ (declare (pure t))
+ (interactive "P")
+ (print x))
+
+(defun faw-str-decl-str-int-code (x)
+ "something"
+ (declare (pure t))
+ "something else"
+ (interactive "P")
+ (print x))
+
+(defun faw-doc-decl-str-int-code (x)
+ (:documentation "something")
+ (declare (pure t))
+ "something else"
+ (interactive "P")
+ (print x))
+
+(defun faw-str-decl-doc-int-code (x)
+ "something"
+ (declare (pure t))
+ (:documentation "something else")
+ (interactive "P")
+ (print x))
+
+(defun faw-doc-decl-doc-int-code (x)
+ (:documentation "something")
+ (declare (pure t))
+ (:documentation "something else")
+ (interactive "P")
+ (print x))
+
+(defun faw-str-decl-decl-int-code (x)
+ "something"
+ (declare (pure t))
+ (declare (indent 1))
+ (interactive "P")
+ (print x))
+
+(defun faw-doc-decl-decl-int-code (x)
+ (:documentation "something")
+ (declare (pure t))
+ (declare (indent 1))
+ (interactive "P")
+ (print x))
+
+(defun faw-str-decl-int-decl-code (x)
+ "something"
+ (declare (pure t))
+ (interactive "P")
+ (declare (indent 1))
+ (print x))
+
+(defun faw-doc-decl-int-decl-code (x)
+ (:documentation "something")
+ (declare (pure t))
+ (interactive "P")
+ (declare (indent 1))
+ (print x))
+
+(defun faw-str-decl-int-int-code (x)
+ "something"
+ (declare (pure t))
+ (interactive "P")
+ (interactive "p")
+ (print x))
+
+(defun faw-doc-decl-int-int-code (x)
+ (:documentation "something")
+ (declare (pure t))
+ (interactive "P")
+ (interactive "p")
+ (print x))
+
+(defun faw-str-int-decl-int-code (x)
+ "something"
+ (interactive "P")
+ (declare (pure t))
+ (interactive "p")
+ (print x))
+
+(defun faw-doc-int-decl-int-code (x)
+ (:documentation "something")
+ (interactive "P")
+ (declare (pure t))
+ (interactive "p")
+ (print x))
diff --git a/test/lisp/emacs-lisp/bytecomp-resources/no-byte-compile.el b/test/lisp/emacs-lisp/bytecomp-resources/no-byte-compile.el
new file mode 100644
index 00000000000..00ad1947507
--- /dev/null
+++ b/test/lisp/emacs-lisp/bytecomp-resources/no-byte-compile.el
@@ -0,0 +1 @@
+;; -*- no-byte-compile: t; -*-
diff --git a/test/lisp/emacs-lisp/bytecomp-resources/warn-variable-setq-nonvariable.el b/test/lisp/emacs-lisp/bytecomp-resources/warn-variable-setq-nonvariable.el
new file mode 100644
index 00000000000..5a56913cd9b
--- /dev/null
+++ b/test/lisp/emacs-lisp/bytecomp-resources/warn-variable-setq-nonvariable.el
@@ -0,0 +1,3 @@
+;;; -*- lexical-binding: t -*-
+(defun foo ()
+ (setq (a) nil))
diff --git a/test/lisp/emacs-lisp/bytecomp-resources/warn-variable-setq-odd.el b/test/lisp/emacs-lisp/bytecomp-resources/warn-variable-setq-odd.el
new file mode 100644
index 00000000000..9ce80de08cd
--- /dev/null
+++ b/test/lisp/emacs-lisp/bytecomp-resources/warn-variable-setq-odd.el
@@ -0,0 +1,3 @@
+;;; -*- lexical-binding: t -*-
+(defun foo (a b)
+ (setq a 1 b))
diff --git a/test/lisp/emacs-lisp/bytecomp-resources/warn-wide-docstring-ignore-substitutions.el b/test/lisp/emacs-lisp/bytecomp-resources/warn-wide-docstring-ignore-substitutions.el
new file mode 100644
index 00000000000..37cfe463bfe
--- /dev/null
+++ b/test/lisp/emacs-lisp/bytecomp-resources/warn-wide-docstring-ignore-substitutions.el
@@ -0,0 +1,17 @@
+;;; -*- lexical-binding: t -*-
+(defalias 'foo #'ignore
+ "None of this should be considered too wide.
+
+; this should be treated as 60 characters - no warning
+\\[quit-window]\\[quit-window]\\[quit-window]\\[quit-window]\\[quit-window]\\[quit-window]\\[quit-window]\\[quit-window]\\[quit-window]\\[quit-window]\\[quit-window]\\[quit-window]\\[quit-window]\\[quit-window]\\[quit-window]\\[quit-window]\\[quit-window]\\[quit-window]
+
+; 64 * 'x' does not warn
+\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'\\`x'
+
+; keymaps are just ignored
+\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>\\<foo-bar-map>
+
+\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}\\{foo-bar-map}
+
+bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar
+")
diff --git a/test/lisp/emacs-lisp/bytecomp-tests.el b/test/lisp/emacs-lisp/bytecomp-tests.el
index a97473e7de4..a246c25e24f 100644
--- a/test/lisp/emacs-lisp/bytecomp-tests.el
+++ b/test/lisp/emacs-lisp/bytecomp-tests.el
@@ -640,6 +640,58 @@ inner loops respectively."
(f (list (lambda (x) (setq a x)))))
(funcall (car f) 3)
(list a b))
+
+ (cond)
+ (mapcar (lambda (x) (cond ((= x 0)))) '(0 1))
+
+ ;; These expressions give different results in lexbind and dynbind modes,
+ ;; but in each the compiler and interpreter should agree!
+ ;; (They look much the same but come in pairs exercising both the
+ ;; `let' and `let*' paths.)
+ (let ((f (lambda (x)
+ (lambda ()
+ (let ((g (lambda () x)))
+ (let ((x 'a))
+ (list x (funcall g))))))))
+ (funcall (funcall f 'b)))
+ (let ((f (lambda (x)
+ (lambda ()
+ (let ((g (lambda () x)))
+ (let* ((x 'a))
+ (list x (funcall g))))))))
+ (funcall (funcall f 'b)))
+ (let ((f (lambda (x)
+ (lambda ()
+ (let ((g (lambda () x)))
+ (setq x (list x x))
+ (let ((x 'a))
+ (list x (funcall g))))))))
+ (funcall (funcall f 'b)))
+ (let ((f (lambda (x)
+ (lambda ()
+ (let ((g (lambda () x)))
+ (setq x (list x x))
+ (let* ((x 'a))
+ (list x (funcall g))))))))
+ (funcall (funcall f 'b)))
+ (let ((f (lambda (x)
+ (let ((g (lambda () x))
+ (h (lambda () (setq x (list x x)))))
+ (let ((x 'a))
+ (list x (funcall g) (funcall h)))))))
+ (funcall (funcall f 'b)))
+ (let ((f (lambda (x)
+ (let ((g (lambda () x))
+ (h (lambda () (setq x (list x x)))))
+ (let* ((x 'a))
+ (list x (funcall g) (funcall h)))))))
+ (funcall (funcall f 'b)))
+
+ ;; Test constant-propagation of access to captured variables.
+ (let* ((x 2)
+ (f (lambda ()
+ (let ((y x)) (list y 3 y)))))
+ (funcall f))
)
"List of expressions for cross-testing interpreted and compiled code.")
@@ -690,24 +742,20 @@ byte-compiled. Run with dynamic binding."
(defun test-byte-comp-compile-and-load (compile &rest forms)
(declare (indent 1))
- (let ((elfile nil)
- (elcfile nil))
- (unwind-protect
- (progn
- (setf elfile (make-temp-file "test-bytecomp" nil ".el"))
- (when compile
- (setf elcfile (make-temp-file "test-bytecomp" nil ".elc")))
- (with-temp-buffer
- (dolist (form forms)
- (print form (current-buffer)))
- (write-region (point-min) (point-max) elfile nil 'silent))
- (if compile
- (let ((byte-compile-dest-file-function
- (lambda (e) elcfile)))
- (byte-compile-file elfile)))
- (load elfile nil 'nomessage))
- (when elfile (delete-file elfile))
- (when elcfile (delete-file elcfile)))))
+ (ert-with-temp-file elfile
+ :suffix ".el"
+ (ert-with-temp-file elcfile
+ :suffix ".elc"
+ (with-temp-buffer
+ (insert ";;; -*- lexical-binding: t -*-\n")
+ (dolist (form forms)
+ (print form (current-buffer)))
+ (write-region (point-min) (point-max) elfile nil 'silent))
+ (if compile
+ (let ((byte-compile-dest-file-function
+ (lambda (e) elcfile)))
+ (byte-compile-file elfile)))
+ (load elfile nil 'nomessage))))
(ert-deftest test-byte-comp-macro-expansion ()
(test-byte-comp-compile-and-load t
@@ -810,8 +858,7 @@ byte-compiled. Run with dynamic binding."
(byte-compile-file ,(ert-resource-file file))
(ert-info ((buffer-string) :prefix "buffer: ")
(,(if reverse 'should-not 'should)
- (re-search-forward ,(string-replace " " "[ \n]+" re-warning)
- nil t))))))
+ (re-search-forward ,re-warning nil t))))))
(bytecomp--define-warning-file-test "error-lexical-var-with-add-hook.el"
"add-hook.*lexical var")
@@ -904,11 +951,17 @@ byte-compiled. Run with dynamic binding."
"let-bind nonvariable")
(bytecomp--define-warning-file-test "warn-variable-set-constant.el"
- "variable reference to constant")
+ "attempt to set constant")
(bytecomp--define-warning-file-test "warn-variable-set-nonvariable.el"
"variable reference to nonvariable")
+(bytecomp--define-warning-file-test "warn-variable-setq-nonvariable.el"
+ "attempt to set non-variable")
+
+(bytecomp--define-warning-file-test "warn-variable-setq-odd.el"
+ "odd number of arguments")
+
(bytecomp--define-warning-file-test
"warn-wide-docstring-autoload.el"
"autoload .foox. docstring wider than .* characters")
@@ -939,7 +992,7 @@ byte-compiled. Run with dynamic binding."
(bytecomp--define-warning-file-test
"warn-wide-docstring-defun.el"
- "wider than .* characters")
+ "Warning: docstring wider than .* characters")
(bytecomp--define-warning-file-test
"warn-wide-docstring-defvar.el"
@@ -958,6 +1011,10 @@ byte-compiled. Run with dynamic binding."
"defvar .foo-bar. docstring wider than .* characters" 'reverse)
(bytecomp--define-warning-file-test
+ "warn-wide-docstring-ignore-substitutions.el"
+ "defvar .foo-bar. docstring wider than .* characters" 'reverse)
+
+(bytecomp--define-warning-file-test
"warn-wide-docstring-ignore.el"
"defvar .foo-bar. docstring wider than .* characters" 'reverse)
@@ -1013,10 +1070,9 @@ byte-compiled. Run with dynamic binding."
(defmacro bytecomp-tests--with-temp-file (file-name-var &rest body)
(declare (indent 1))
(cl-check-type file-name-var symbol)
- `(let ((,file-name-var (make-temp-file "emacs")))
+ `(ert-with-temp-file ,file-name-var
(unwind-protect
(progn ,@body)
- (delete-file ,file-name-var)
(let ((elc (concat ,file-name-var ".elc")))
(if (file-exists-p elc) (delete-file elc))))))
@@ -1178,12 +1234,19 @@ literals (Bug#20852)."
'((lexical prefixless))
"global/dynamic var .prefixless. lacks")
- (test-suppression
- '(defun foo()
- (let ((nil t))
- (message-mail)))
- '((constants nil))
- "Warning: attempt to let-bind constant .nil.")
+ ;; FIXME: These messages cannot be suppressed reliably right now,
+ ;; but attempting mutate `nil' or `5' is a rather daft thing to do
+ ;; in the first place. Preventing mutation of constants such as
+ ;; `most-positive-fixnum' makes more sense but the compiler doesn't
+ ;; warn about that at all right now (it's caught at runtime, and we
+ ;; allow writing the same value).
+ ;;
+ ;; (test-suppression
+ ;; '(defun foo()
+ ;; (let ((nil t))
+ ;; (message-mail)))
+ ;; '((constants nil))
+ ;; "Warning: attempt to let-bind constant .nil.")
(test-suppression
'(progn
@@ -1202,7 +1265,7 @@ literals (Bug#20852)."
(defun zot ()
(wrong-params 1 2 3)))
'((callargs wrong-params))
- "Warning: wrong-params called with")
+ "Warning: .wrong-params. called with")
(test-byte-comp-compile-and-load nil
(defvar obsolete-variable nil)
@@ -1243,25 +1306,25 @@ literals (Bug#20852)."
(ert-deftest bytecomp-tests--not-writable-directory ()
"Test that byte compilation works if the output directory isn't
writable (Bug#44631)."
- (let ((directory (make-temp-file "bytecomp-tests-" :directory)))
- (unwind-protect
- (let* ((input-file (expand-file-name "test.el" directory))
- (output-file (expand-file-name "test.elc" directory))
- (byte-compile-dest-file-function
- (lambda (_) output-file))
- (byte-compile-error-on-warn t))
- (write-region "" nil input-file nil nil nil 'excl)
- (write-region "" nil output-file nil nil nil 'excl)
- (set-file-modes input-file #o400)
- (set-file-modes output-file #o200)
- (set-file-modes directory #o500)
- (should (byte-compile-file input-file))
- (should (file-regular-p output-file))
- (should (cl-plusp (file-attribute-size
- (file-attributes output-file)))))
- (with-demoted-errors "Error cleaning up directory: %s"
- (set-file-modes directory #o700)
- (delete-directory directory :recursive)))))
+ (ert-with-temp-directory directory
+ (let* ((input-file (expand-file-name "test.el" directory))
+ (output-file (expand-file-name "test.elc" directory))
+ (byte-compile-dest-file-function
+ (lambda (_) output-file))
+ (byte-compile-error-on-warn t))
+ (unwind-protect
+ (progn
+ (write-region "" nil input-file nil nil nil 'excl)
+ (write-region "" nil output-file nil nil nil 'excl)
+ (set-file-modes input-file #o400)
+ (set-file-modes output-file #o200)
+ (set-file-modes directory #o500)
+ (should (byte-compile-file input-file))
+ (should (file-regular-p output-file))
+ (should (cl-plusp (file-attribute-size
+ (file-attributes output-file)))))
+ ;; Allow the directory to be deleted.
+ (set-file-modes directory #o777)))))
(ert-deftest bytecomp-tests--dest-mountpoint ()
"Test that byte compilation works if the destination file is a
@@ -1273,56 +1336,53 @@ mountpoint (Bug#44631)."
(skip-unless (not (file-remote-p bwrap)))
(skip-unless (file-executable-p emacs))
(skip-unless (not (file-remote-p emacs)))
- (let ((directory (make-temp-file "bytecomp-tests-" :directory)))
- (unwind-protect
- (let* ((input-file (expand-file-name "test.el" directory))
- (output-file (expand-file-name "test.elc" directory))
- (unquoted-file (file-name-unquote output-file))
- (byte-compile-dest-file-function
- (lambda (_) output-file))
- (byte-compile-error-on-warn t))
- (should-not (file-remote-p input-file))
- (should-not (file-remote-p output-file))
- (write-region "" nil input-file nil nil nil 'excl)
- (write-region "" nil output-file nil nil nil 'excl)
- (set-file-modes input-file #o400)
- (set-file-modes output-file #o200)
- (set-file-modes directory #o500)
- (with-temp-buffer
- (let ((status (call-process
- bwrap nil t nil
- "--ro-bind" "/" "/"
- "--bind" unquoted-file unquoted-file
- emacs "--quick" "--batch" "--load=bytecomp"
- (format "--eval=%S"
- `(setq byte-compile-dest-file-function
- (lambda (_) ,output-file)
- byte-compile-error-on-warn t))
- "--funcall=batch-byte-compile" input-file)))
- (unless (eql status 0)
- (ert-fail `((status . ,status)
- (output . ,(buffer-string)))))))
- (should (file-regular-p output-file))
- (should (cl-plusp (file-attribute-size
- (file-attributes output-file)))))
- (with-demoted-errors "Error cleaning up directory: %s"
- (set-file-modes directory #o700)
- (delete-directory directory :recursive))))))
+ (ert-with-temp-directory directory
+ (let* ((input-file (expand-file-name "test.el" directory))
+ (output-file (expand-file-name "test.elc" directory))
+ (unquoted-file (file-name-unquote output-file))
+ (byte-compile-dest-file-function
+ (lambda (_) output-file))
+ (byte-compile-error-on-warn t))
+ (should-not (file-remote-p input-file))
+ (should-not (file-remote-p output-file))
+ (write-region "" nil input-file nil nil nil 'excl)
+ (write-region "" nil output-file nil nil nil 'excl)
+ (unwind-protect
+ (progn
+ (set-file-modes input-file #o400)
+ (set-file-modes output-file #o200)
+ (set-file-modes directory #o500)
+ (with-temp-buffer
+ (let ((status (call-process
+ bwrap nil t nil
+ "--ro-bind" "/" "/"
+ "--bind" unquoted-file unquoted-file
+ emacs "--quick" "--batch" "--load=bytecomp"
+ (format "--eval=%S"
+ `(setq byte-compile-dest-file-function
+ (lambda (_) ,output-file)
+ byte-compile-error-on-warn t))
+ "--funcall=batch-byte-compile" input-file)))
+ (unless (eql status 0)
+ (ert-fail `((status . ,status)
+ (output . ,(buffer-string)))))))
+ (should (file-regular-p output-file))
+ (should (cl-plusp (file-attribute-size
+ (file-attributes output-file)))))
+ ;; Allow the directory to be deleted.
+ (set-file-modes directory #o777))))))
(ert-deftest bytecomp-tests--target-file-no-directory ()
"Check that Bug#45287 is fixed."
- (let ((directory (make-temp-file "bytecomp-tests-" :directory)))
- (unwind-protect
- (let* ((default-directory directory)
- (byte-compile-dest-file-function (lambda (_) "test.elc"))
- (byte-compile-error-on-warn t))
- (write-region "" nil "test.el" nil nil nil 'excl)
- (should (byte-compile-file "test.el"))
- (should (file-regular-p "test.elc"))
- (should (cl-plusp (file-attribute-size
- (file-attributes "test.elc")))))
- (with-demoted-errors "Error cleaning up directory: %s"
- (delete-directory directory :recursive)))))
+ (ert-with-temp-directory directory
+ (let* ((default-directory directory)
+ (byte-compile-dest-file-function (lambda (_) "test.elc"))
+ (byte-compile-error-on-warn t))
+ (write-region "" nil "test.el" nil nil nil 'excl)
+ (should (byte-compile-file "test.el"))
+ (should (file-regular-p "test.elc"))
+ (should (cl-plusp (file-attribute-size
+ (file-attributes "test.elc")))))))
(defun bytecomp-tests--get-vars ()
(list (ignore-errors (symbol-value 'bytecomp-tests--var1))
@@ -1492,6 +1552,103 @@ EXPECTED-POINT BINDINGS (MODES \\='\\='(ruby-mode js-mode python-mode)) \
(TEST-IN-COMMENTS t) (TEST-IN-STRINGS t) (TEST-IN-CODE t) \
(FIXTURE-FN \\='#\\='electric-pair-mode))" fill-column)))
+(defun test-bytecomp-defgroup-choice ()
+ (should-not (byte-compile--suspicious-defcustom-choice 'integer))
+ (should-not (byte-compile--suspicious-defcustom-choice
+ '(choice (const :tag "foo" bar))))
+ (should (byte-compile--suspicious-defcustom-choice
+ '(choice (const :tag "foo" 'bar)))))
+
+(ert-deftest bytecomp-function-attributes ()
+ ;; Check that `byte-compile' keeps the declarations, interactive spec and
+ ;; doc string of the function (bug#55830).
+ (let ((fname 'bytecomp-test-fun))
+ (fset fname nil)
+ (put fname 'pure nil)
+ (put fname 'lisp-indent-function nil)
+ (eval `(defun ,fname (x)
+ "tata"
+ (declare (pure t) (indent 1))
+ (interactive "P")
+ (list 'toto x))
+ t)
+ (let ((bc (byte-compile fname)))
+ (should (byte-code-function-p bc))
+ (should (equal (funcall bc 'titi) '(toto titi)))
+ (should (equal (aref bc 5) "P"))
+ (should (equal (get fname 'pure) t))
+ (should (equal (get fname 'lisp-indent-function) 1))
+ (should (equal (aref bc 4) "tata\n\n(fn X)")))))
+
+(ert-deftest bytecomp-fun-attr-warn ()
+ ;; Check that warnings are emitted when doc strings, `declare' and
+ ;; `interactive' forms don't come in the proper order, or more than once.
+ (let* ((filename "fun-attr-warn.el")
+ (el (ert-resource-file filename))
+ (elc (concat el "c"))
+ (text-quoting-style 'grave))
+ (with-current-buffer (get-buffer-create "*Compile-Log*")
+ (let ((inhibit-read-only t))
+ (erase-buffer))
+ (byte-compile-file el)
+ (let ((expected
+ '("70:4: Warning: `declare' after `interactive'"
+ "74:4: Warning: Doc string after `interactive'"
+ "79:4: Warning: Doc string after `interactive'"
+ "84:4: Warning: Doc string after `declare'"
+ "89:4: Warning: Doc string after `declare'"
+ "96:4: Warning: `declare' after `interactive'"
+ "102:4: Warning: `declare' after `interactive'"
+ "108:4: Warning: `declare' after `interactive'"
+ "106:4: Warning: Doc string after `interactive'"
+ "114:4: Warning: `declare' after `interactive'"
+ "112:4: Warning: Doc string after `interactive'"
+ "118:4: Warning: Doc string after `interactive'"
+ "119:4: Warning: `declare' after `interactive'"
+ "124:4: Warning: Doc string after `interactive'"
+ "125:4: Warning: `declare' after `interactive'"
+ "130:4: Warning: Doc string after `declare'"
+ "136:4: Warning: Doc string after `declare'"
+ "142:4: Warning: Doc string after `declare'"
+ "148:4: Warning: Doc string after `declare'"
+ "159:4: Warning: More than one doc string"
+ "165:4: Warning: More than one doc string"
+ "171:4: Warning: More than one doc string"
+ "178:4: Warning: More than one doc string"
+ "186:4: Warning: More than one doc string"
+ "192:4: Warning: More than one doc string"
+ "200:4: Warning: More than one doc string"
+ "206:4: Warning: More than one doc string"
+ "215:4: Warning: More than one `declare' form"
+ "222:4: Warning: More than one `declare' form"
+ "230:4: Warning: More than one `declare' form"
+ "237:4: Warning: More than one `declare' form"
+ "244:4: Warning: More than one `interactive' form"
+ "251:4: Warning: More than one `interactive' form"
+ "258:4: Warning: More than one `interactive' form"
+ "257:4: Warning: `declare' after `interactive'"
+ "265:4: Warning: More than one `interactive' form"
+ "264:4: Warning: `declare' after `interactive'")))
+ (goto-char (point-min))
+ (let ((actual nil))
+ (while (re-search-forward
+ (rx bol (* (not ":")) ":"
+ (group (+ digit) ":" (+ digit) ": Warning: "
+ (or "More than one " (+ nonl) " form"
+ (: (+ nonl) " after " (+ nonl))))
+ eol)
+ nil t)
+ (push (match-string 1) actual))
+ (setq actual (nreverse actual))
+ (should (equal actual expected)))))))
+
+(ert-deftest byte-compile-file/no-byte-compile ()
+ (let* ((src-file (ert-resource-file "no-byte-compile.el"))
+ (dest-file (make-temp-file "bytecomp-tests-" nil ".elc"))
+ (byte-compile-dest-file-function (lambda (_) dest-file)))
+ (should (eq (byte-compile-file src-file) 'no-byte-compile))
+ (should-not (file-exists-p dest-file))))
+
;; Local Variables:
;; no-byte-compile: t
diff --git a/test/lisp/emacs-lisp/cconv-tests.el b/test/lisp/emacs-lisp/cconv-tests.el
index edb746cdecf..9904c6a969c 100644
--- a/test/lisp/emacs-lisp/cconv-tests.el
+++ b/test/lisp/emacs-lisp/cconv-tests.el
@@ -23,6 +23,8 @@
(require 'ert)
(require 'cl-lib)
+(require 'generator)
+(require 'bytecomp)
(ert-deftest cconv-tests-lambda-:documentation ()
"Docstring for lambda can be specified with :documentation."
@@ -83,9 +85,6 @@
(iter-yield 'cl-iter-defun-result))
(ert-deftest cconv-tests-cl-iter-defun-:documentation ()
"Docstring for cl-iter-defun can be specified with :documentation."
- ;; FIXME: See Bug#28557.
- :tags '(:unstable)
- :expected-result :failed
(should (string= (documentation 'cconv-tests-cl-iter-defun)
"cl-iter-defun documentation"))
(should (eq (iter-next (cconv-tests-cl-iter-defun))
@@ -96,17 +95,12 @@
(iter-yield 'iter-defun-result))
(ert-deftest cconv-tests-iter-defun-:documentation ()
"Docstring for iter-defun can be specified with :documentation."
- ;; FIXME: See Bug#28557.
- :tags '(:unstable)
- :expected-result :failed
(should (string= (documentation 'cconv-tests-iter-defun)
"iter-defun documentation"))
(should (eq (iter-next (cconv-tests-iter-defun)) 'iter-defun-result)))
(ert-deftest cconv-tests-iter-lambda-:documentation ()
"Docstring for iter-lambda can be specified with :documentation."
- ;; FIXME: See Bug#28557.
- :expected-result :failed
(let ((iter-fun
(iter-lambda ()
(:documentation (concat "iter-lambda" " documentation"))
@@ -116,13 +110,11 @@
(ert-deftest cconv-tests-cl-function-:documentation ()
"Docstring for cl-function can be specified with :documentation."
- ;; FIXME: See Bug#28557.
- :expected-result :failed
(let ((fun (cl-function (lambda (&key arg)
(:documentation (concat "cl-function"
" documentation"))
(list arg 'cl-function-result)))))
- (should (string= (documentation fun) "cl-function documentation"))
+ (should (string-match "\\`cl-function documentation$" (documentation fun)))
(should (equal (funcall fun :arg t) '(t cl-function-result)))))
(ert-deftest cconv-tests-function-:documentation ()
@@ -142,8 +134,6 @@
(+ 1 n))
(ert-deftest cconv-tests-cl-defgeneric-:documentation ()
"Docstring for cl-defgeneric can be specified with :documentation."
- ;; FIXME: See Bug#28557.
- :expected-result :failed
(let ((descr (describe-function 'cconv-tests-cl-defgeneric)))
(set-text-properties 0 (length descr) nil descr)
(should (string-match-p "cl-defgeneric documentation" descr))
@@ -205,5 +195,157 @@
nil 99)
42)))
+(defun cconv-tests--intern-all (x)
+ "Intern all symbols in X."
+ (cond ((symbolp x) (intern (symbol-name x)))
+ ((consp x) (cons (cconv-tests--intern-all (car x))
+ (cconv-tests--intern-all (cdr x))))
+ ;; Assume we don't need to deal with vectors etc.
+ (t x)))
+
+(ert-deftest cconv-closure-convert-remap-var ()
+ ;; Verify that we correctly remap shadowed lambda-lifted variables.
+
+ ;; We intern all symbols for ease of comparison; this works because
+ ;; the `cconv-closure-convert' result should contain no pair of
+ ;; distinct symbols having the same name.
+
+ ;; Sanity check: captured variable, no lambda-lifting or shadowing:
+ (should (equal (cconv-tests--intern-all
+ (cconv-closure-convert
+ '#'(lambda (x)
+ #'(lambda () x))))
+ '#'(lambda (x)
+ (internal-make-closure
+ nil (x) nil
+ (internal-get-closed-var 0)))))
+
+ ;; Basic case:
+ (should (equal (cconv-tests--intern-all
+ (cconv-closure-convert
+ '#'(lambda (x)
+ (let ((f #'(lambda () x)))
+ (let ((x 'b))
+ (list x (funcall f)))))))
+ '#'(lambda (x)
+ (let ((f #'(lambda (x) x)))
+ (let ((x 'b)
+ (closed-x x))
+ (list x (funcall f closed-x)))))))
+ (should (equal (cconv-tests--intern-all
+ (cconv-closure-convert
+ '#'(lambda (x)
+ (let ((f #'(lambda () x)))
+ (let* ((x 'b))
+ (list x (funcall f)))))))
+ '#'(lambda (x)
+ (let ((f #'(lambda (x) x)))
+ (let* ((closed-x x)
+ (x 'b))
+ (list x (funcall f closed-x)))))))
+
+ ;; With the lambda-lifted shadowed variable also being captured:
+ (should (equal
+ (cconv-tests--intern-all
+ (cconv-closure-convert
+ '#'(lambda (x)
+ #'(lambda ()
+ (let ((f #'(lambda () x)))
+ (let ((x 'a))
+ (list x (funcall f))))))))
+ '#'(lambda (x)
+ (internal-make-closure
+ nil (x) nil
+ (let ((f #'(lambda (x) x)))
+ (let ((x 'a)
+ (closed-x (internal-get-closed-var 0)))
+ (list x (funcall f closed-x))))))))
+ (should (equal
+ (cconv-tests--intern-all
+ (cconv-closure-convert
+ '#'(lambda (x)
+ #'(lambda ()
+ (let ((f #'(lambda () x)))
+ (let* ((x 'a))
+ (list x (funcall f))))))))
+ '#'(lambda (x)
+ (internal-make-closure
+ nil (x) nil
+ (let ((f #'(lambda (x) x)))
+ (let* ((closed-x (internal-get-closed-var 0))
+ (x 'a))
+ (list x (funcall f closed-x))))))))
+ ;; With lambda-lifted shadowed variable also being mutably captured:
+ (should (equal
+ (cconv-tests--intern-all
+ (cconv-closure-convert
+ '#'(lambda (x)
+ #'(lambda ()
+ (let ((f #'(lambda () x)))
+ (setq x x)
+ (let ((x 'a))
+ (list x (funcall f))))))))
+ '#'(lambda (x)
+ (let ((x (list x)))
+ (internal-make-closure
+ nil (x) nil
+ (let ((f #'(lambda (x) (car-safe x))))
+ (setcar (internal-get-closed-var 0)
+ (car-safe (internal-get-closed-var 0)))
+ (let ((x 'a)
+ (closed-x (internal-get-closed-var 0)))
+ (list x (funcall f closed-x)))))))))
+ (should (equal
+ (cconv-tests--intern-all
+ (cconv-closure-convert
+ '#'(lambda (x)
+ #'(lambda ()
+ (let ((f #'(lambda () x)))
+ (setq x x)
+ (let* ((x 'a))
+ (list x (funcall f))))))))
+ '#'(lambda (x)
+ (let ((x (list x)))
+ (internal-make-closure
+ nil (x) nil
+ (let ((f #'(lambda (x) (car-safe x))))
+ (setcar (internal-get-closed-var 0)
+ (car-safe (internal-get-closed-var 0)))
+ (let* ((closed-x (internal-get-closed-var 0))
+ (x 'a))
+ (list x (funcall f closed-x)))))))))
+ ;; Lambda-lifted variable that isn't actually captured where it is shadowed:
+ (should (equal
+ (cconv-tests--intern-all
+ (cconv-closure-convert
+ '#'(lambda (x)
+ (let ((g #'(lambda () x))
+ (h #'(lambda () (setq x x))))
+ (let ((x 'b))
+ (list x (funcall g) (funcall h)))))))
+ '#'(lambda (x)
+ (let ((x (list x)))
+ (let ((g #'(lambda (x) (car-safe x)))
+ (h #'(lambda (x) (setcar x (car-safe x)))))
+ (let ((x 'b)
+ (closed-x x))
+ (list x (funcall g closed-x) (funcall h closed-x))))))))
+ (should (equal
+ (cconv-tests--intern-all
+ (cconv-closure-convert
+ '#'(lambda (x)
+ (let ((g #'(lambda () x))
+ (h #'(lambda () (setq x x))))
+ (let* ((x 'b))
+ (list x (funcall g) (funcall h)))))))
+ '#'(lambda (x)
+ (let ((x (list x)))
+ (let ((g #'(lambda (x) (car-safe x)))
+ (h #'(lambda (x) (setcar x (car-safe x)))))
+ (let* ((closed-x x)
+ (x 'b))
+ (list x (funcall g closed-x) (funcall h closed-x))))))))
+ )
+
(provide 'cconv-tests)
;;; cconv-tests.el ends here
diff --git a/test/lisp/emacs-lisp/check-declare-tests.el b/test/lisp/emacs-lisp/check-declare-tests.el
index 42b6a4ccab6..59dfc10163d 100644
--- a/test/lisp/emacs-lisp/check-declare-tests.el
+++ b/test/lisp/emacs-lisp/check-declare-tests.el
@@ -28,6 +28,7 @@
(require 'check-declare)
(require 'ert)
+(require 'ert-x)
(eval-when-compile (require 'subr-x))
(ert-deftest check-declare-tests-locate ()
@@ -36,62 +37,53 @@
(string-prefix-p "ext:" (check-declare-locate "ext:foo" ""))))
(ert-deftest check-declare-tests-scan ()
- (let ((file (make-temp-file "check-declare-tests-")))
- (unwind-protect
- (progn
- (with-temp-file file
- (insert
- (string-join
- '(";; foo comment"
- "(declare-function ring-insert \"ring\" (ring item))"
- "(let ((foo 'code)) foo)")
- "\n")))
- (let ((res (check-declare-scan file)))
- (should (= (length res) 1))
- (pcase-let ((`((,fnfile ,fn ,arglist ,fileonly)) res))
- (should (string-match-p "ring" fnfile))
- (should (equal "ring-insert" fn))
- (should (equal '(ring item) arglist))
- (should-not fileonly))))
- (delete-file file))))
+ (ert-with-temp-file file
+ (with-temp-file file
+ (insert
+ (string-join
+ '(";; foo comment"
+ "(declare-function ring-insert \"ring\" (ring item))"
+ "(let ((foo 'code)) foo)")
+ "\n")))
+ (let ((res (check-declare-scan file)))
+ (should (= (length res) 1))
+ (pcase-let ((`((,fnfile ,fn ,arglist ,fileonly)) res))
+ (should (string-match-p "ring" fnfile))
+ (should (equal "ring-insert" fn))
+ (should (equal '(ring item) arglist))
+ (should-not fileonly)))))
(ert-deftest check-declare-tests-verify ()
- (let ((file (make-temp-file "check-declare-tests-")))
- (unwind-protect
- (progn
- (with-temp-file file
- (insert
- (string-join
- '(";; foo comment"
- "(defun foo-fun ())"
- "(defun ring-insert (ring item)"
- "\"Insert onto ring RING the item ITEM.\""
- "nil)")
- "\n")))
- (should-not
- (check-declare-verify
- file '(("foo.el" "ring-insert" (ring item))))))
- (delete-file file))))
+ (ert-with-temp-file file
+ (with-temp-file file
+ (insert
+ (string-join
+ '(";; foo comment"
+ "(defun foo-fun ())"
+ "(defun ring-insert (ring item)"
+ "\"Insert onto ring RING the item ITEM.\""
+ "nil)")
+ "\n")))
+ (should-not
+ (check-declare-verify
+ file '(("foo.el" "ring-insert" (ring item)))))))
(ert-deftest check-declare-tests-verify-mismatch ()
- (let ((file (make-temp-file "check-declare-tests-")))
- (unwind-protect
- (progn
- (with-temp-file file
- (insert
- (string-join
- '(";; foo comment"
- "(defun foo-fun ())"
- "(defun ring-insert (ring)"
- "\"Insert onto ring RING the item ITEM.\""
- "nil)")
- "\n")))
- (should
- (equal
- (check-declare-verify
- file '(("foo.el" "ring-insert" (ring item))))
- '(("foo.el" "ring-insert" "arglist mismatch")))))
- (delete-file file))))
+ (ert-with-temp-file file
+ (with-temp-file file
+ (insert
+ (string-join
+ '(";; foo comment"
+ "(defun foo-fun ())"
+ "(defun ring-insert (ring)"
+ "\"Insert onto ring RING the item ITEM.\""
+ "nil)")
+ "\n")))
+ (should
+ (equal
+ (check-declare-verify
+ file '(("foo.el" "ring-insert" (ring item))))
+ '(("foo.el" "ring-insert" "arglist mismatch"))))))
(ert-deftest check-declare-tests-sort ()
(should-not (check-declare-sort '()))
diff --git a/test/lisp/emacs-lisp/cl-generic-tests.el b/test/lisp/emacs-lisp/cl-generic-tests.el
index b906e8485cd..56b766769ea 100644
--- a/test/lisp/emacs-lisp/cl-generic-tests.el
+++ b/test/lisp/emacs-lisp/cl-generic-tests.el
@@ -27,7 +27,7 @@
(require 'edebug)
;; Don't indirectly require `cl-lib' at run-time.
-(eval-when-compile (require 'ert))
+(require 'ert)
(declare-function ert--should-signal-hook "ert")
(declare-function ert--signal-should-execution "ert")
(declare-function ert-fail "ert")
@@ -200,9 +200,14 @@
(fmakunbound 'cl--generic-1)
(cl-defgeneric cl--generic-1 (x y))
(cl-defmethod cl--generic-1 ((x t) y)
- (list x y (cl-next-method-p)))
+ (list x y
+ (with-suppressed-warnings ((obsolete cl-next-method-p))
+ (cl-next-method-p))))
(cl-defmethod cl--generic-1 ((_x (eql 4)) _y)
- (cl-list* "quatre" (cl-next-method-p) (cl-call-next-method)))
+ (cl-list* "quatre"
+ (with-suppressed-warnings ((obsolete cl-next-method-p))
+ (cl-next-method-p))
+ (cl-call-next-method)))
(should (equal (cl--generic-1 4 5) '("quatre" t 4 5 nil))))
(ert-deftest cl-generic-test-12-context ()
diff --git a/test/lisp/emacs-lisp/cl-lib-tests.el b/test/lisp/emacs-lisp/cl-lib-tests.el
index 03b5371f1bf..b19494af746 100644
--- a/test/lisp/emacs-lisp/cl-lib-tests.el
+++ b/test/lisp/emacs-lisp/cl-lib-tests.el
@@ -353,13 +353,6 @@
(should (= 5 (cl-fifth '(1 2 3 4 5 6))))
(should-error (cl-fifth "12345") :type 'wrong-type-argument))
-(ert-deftest cl-lib-test-fifth ()
- (should (null (cl-fifth '())))
- (should (null (cl-fifth '(1 2 3 4))))
- (should (= 5 (cl-fifth '(1 2 3 4 5))))
- (should (= 5 (cl-fifth '(1 2 3 4 5 6))))
- (should-error (cl-fifth "12345") :type 'wrong-type-argument))
-
(ert-deftest cl-lib-test-sixth ()
(should (null (cl-sixth '())))
(should (null (cl-sixth '(1 2 3 4 5))))
@@ -558,4 +551,9 @@
(should cl-old-struct-compat-mode)
(cl-old-struct-compat-mode (if saved 1 -1))))
+(ert-deftest cl-constantly ()
+ (should (equal (mapcar (cl-constantly 3) '(a b c d))
+ '(3 3 3 3))))
+
+
;;; cl-lib-tests.el ends here
diff --git a/test/lisp/emacs-lisp/cl-macs-tests.el b/test/lisp/emacs-lisp/cl-macs-tests.el
index 17a84d2067a..19ede627a13 100644
--- a/test/lisp/emacs-lisp/cl-macs-tests.el
+++ b/test/lisp/emacs-lisp/cl-macs-tests.el
@@ -23,6 +23,7 @@
(require 'cl-lib)
(require 'cl-macs)
+(require 'edebug)
(require 'ert)
@@ -529,7 +530,7 @@ collection clause."
(should-error
;; Use `eval' so the error is signaled when running the test rather than
;; when macroexpanding it.
- (eval '(let ((l (list 1))) (cl-symbol-macrolet ((x 1)) (setq (car l) 0)))))
+ (eval '(let ((l (list 1))) (cl-symbol-macrolet ((x 1)) (setq (car l) 0))) t))
;; Make sure `gv-synthetic-place' isn't macro-expanded before `setf' gets to
;; see its `gv-expander'.
(should (equal (let ((l '(0)))
@@ -637,17 +638,26 @@ collection clause."
(/ 1 (logand n 1))
(arith-error (len3 (cdr xs) (1+ n)))
(:success (len3 (cdr xs) (+ n k))))
- n)))
+ n))
+
+ ;; Tail calls in `cond'.
+ (len4 (xs n)
+ (cond (xs (cond (nil 'nevertrue)
+ ((len4 (cdr xs) (1+ n)))))
+ (t n))))
(should (equal (len nil 0) 0))
(should (equal (len2 nil 0) 0))
(should (equal (len3 nil 0) 0))
+ (should (equal (len4 nil 0) 0))
(should (equal (len list-42 0) 42))
(should (equal (len2 list-42 0) 42))
(should (equal (len3 list-42 0) 42))
+ (should (equal (len4 list-42 0) 42))
;; Should not bump into stack depth limits.
(should (equal (len list-42k 0) 42000))
(should (equal (len2 list-42k 0) 42000))
- (should (equal (len3 list-42k 0) 42000))))
+ (should (equal (len3 list-42k 0) 42000))
+ (should (equal (len4 list-42k 0) 42000))))
;; Check that non-recursive functions are handled more efficiently.
(should (pcase (macroexpand '(cl-labels ((f (x) (+ x 1))) (f 5)))
@@ -657,11 +667,64 @@ collection clause."
(should (pcase (macroexpand
'(cl-labels ((len (xs n) (if xs (len (cdr xs) (1+ n)) n)))
#'len))
- (`(function (lambda (,_ ,_) . ,_)) t))))
+ (`(function (lambda (,_ ,_) . ,_)) t)))
+
+ ;; Verify that there is no tail position inside dynamic variable bindings.
+ (defvar dyn-var)
+ (let ((dyn-var 'a))
+ (cl-labels ((f (x) (if x
+ dyn-var
+ (let ((dyn-var 'b))
+ (f dyn-var)))))
+ (should (equal (f nil) 'b))))
+
+ ;; Control: same as above but with lexical binding.
+ (let ((lex-var 'a))
+ (cl-labels ((f (x) (if x
+ lex-var
+ (let ((lex-var 'b))
+ (f lex-var)))))
+ (should (equal (f nil) 'a)))))
(ert-deftest cl-macs--progv ()
- (should (= (cl-progv '(test test) '(1 2) test) 2))
- (should (equal (cl-progv '(test1 test2) '(1 2) (list test1 test2))
+ (defvar cl-macs--test)
+ (defvar cl-macs--test1)
+ (defvar cl-macs--test2)
+ (should (= (cl-progv '(cl-macs--test cl-macs--test) '(1 2) cl-macs--test) 2))
+ (should (equal (cl-progv '(cl-macs--test1 cl-macs--test2) '(1 2)
+ (list cl-macs--test1 cl-macs--test2))
'(1 2))))
+(ert-deftest cl-define-compiler-macro/edebug ()
+ "Check that we can instrument compiler macros."
+ (with-temp-buffer
+ (dolist (form '((defun cl-define-compiler-macro/edebug (a b) nil)
+ (cl-define-compiler-macro
+ cl-define-compiler-macro/edebug
+ (&whole w a b)
+ w)))
+ (print form (current-buffer)))
+ (let ((edebug-all-defs t)
+ (edebug-initial-mode 'Go-nonstop))
+ ;; Just make sure the forms can be instrumented.
+ (eval-buffer))))
+
+(ert-deftest cl-defstruct/edebug ()
+ "Check that we can instrument `cl-defstruct' forms."
+ (with-temp-buffer
+ (dolist (form '((cl-defstruct cl-defstruct/edebug/1)
+ (cl-defstruct (cl-defstruct/edebug/2
+ :noinline))
+ (cl-defstruct (cl-defstruct/edebug/3
+ (:noinline t)))
+ (cl-defstruct (cl-defstruct/edebug/4
+ :named))
+ (cl-defstruct (cl-defstruct/edebug/5
+ (:named t)))))
+ (print form (current-buffer)))
+ (let ((edebug-all-defs t)
+ (edebug-initial-mode 'Go-nonstop))
+ ;; Just make sure the forms can be instrumented.
+ (eval-buffer))))
+
;;; cl-macs-tests.el ends here
diff --git a/test/lisp/emacs-lisp/copyright-tests.el b/test/lisp/emacs-lisp/copyright-tests.el
index abb0913a0d7..b00d697aa64 100644
--- a/test/lisp/emacs-lisp/copyright-tests.el
+++ b/test/lisp/emacs-lisp/copyright-tests.el
@@ -72,5 +72,25 @@
(buffer-string))
"Copyright 2021 FSF\nCopyright 2021, 2022 FSF\n")))
+(defmacro with-copyright-fix-years-test (orig result)
+ `(let ((copyright-year-ranges t))
+ (with-temp-buffer
+ (insert ,orig)
+ (copyright-fix-years)
+ (should (equal (buffer-string) ,result)))))
+
+(defvar copyright-fix-years-tests--data
+ '((";; Copyright (C) 2008, 2010, 2012"
+ . ";; Copyright (C) 2008, 2010, 2012")
+ (";; Copyright (C) 2008, 2009, 2010, 2013, 2014, 2015, 2016, 2018"
+ . ";; Copyright (C) 2008-2010, 2013-2016, 2018")
+ (";; Copyright (C) 2008-2010, 2011, 2015, 2016, 2017"
+ . ";; Copyright (C) 2008-2010, 2011, 2015-2017")))
+
+(ert-deftest text-copyright-fix-years ()
+ "Test basics of \\[copyright-fix-years]."
+ (dolist (test copyright-fix-years-tests--data)
+ (with-copyright-fix-years-test (car test) (cdr test))))
+
(provide 'copyright-tests)
;;; copyright-tests.el ends here
diff --git a/test/lisp/emacs-lisp/derived-tests.el b/test/lisp/emacs-lisp/derived-tests.el
index dba8f904c78..547b16843d4 100644
--- a/test/lisp/emacs-lisp/derived-tests.el
+++ b/test/lisp/emacs-lisp/derived-tests.el
@@ -24,13 +24,13 @@
(define-derived-mode derived-tests--parent-mode prog-mode "P"
:after-hook
(let ((f (let ((x "S")) (lambda () x))))
- (insert (format "AFP=%s " (let ((x "D")) (funcall f)))))
+ (insert (format "AFP=%s " (let ((x "D")) x (funcall f)))))
(insert "PB "))
(define-derived-mode derived-tests--child-mode derived-tests--parent-mode "C"
:after-hook
(let ((f (let ((x "S")) (lambda () x))))
- (insert (format "AFC=%s " (let ((x "D")) (funcall f)))))
+ (insert (format "AFC=%s " (let ((x "D")) x (funcall f)))))
(insert "CB "))
(ert-deftest derived-tests-after-hook-lexical ()
@@ -40,4 +40,25 @@
(derived-tests--child-mode)
(should (equal (buffer-string) "PB CB MH AFP=S AFC=S ")))))
+(declare-function mode-a "derived-tests")
+(declare-function mode-b "derived-tests")
+(declare-function mode-c "derived-tests")
+(ert-deftest test-add-font-lock ()
+ (define-derived-mode mode-a fundamental-mode "mode-a"
+ (font-lock-add-keywords nil `(("a" 0 'font-lock-keyword-face))))
+ (define-derived-mode mode-b mode-a "mode-b"
+ (font-lock-add-keywords nil `(("b" 0 'font-lock-builtin-face))))
+ (define-derived-mode mode-c mode-b "mode-c"
+ (font-lock-add-keywords nil `(("c" 0 'font-lock-constant-face))))
+
+ (with-temp-buffer
+ (mode-c)
+ (should (equal font-lock-keywords
+ '(t (("c" 0 'font-lock-constant-face)
+ ("b" 0 'font-lock-builtin-face)
+ ("a" 0 'font-lock-keyword-face))
+ ("c" (0 'font-lock-constant-face))
+ ("b" (0 'font-lock-builtin-face))
+ ("a" (0 'font-lock-keyword-face)))))))
+
;;; derived-tests.el ends here
diff --git a/test/lisp/emacs-lisp/easy-mmode-tests.el b/test/lisp/emacs-lisp/easy-mmode-tests.el
index 0a3bbb189ba..f6d07196727 100644
--- a/test/lisp/emacs-lisp/easy-mmode-tests.el
+++ b/test/lisp/emacs-lisp/easy-mmode-tests.el
@@ -60,6 +60,4 @@
(easy-mmode-test-mode 'toggle)
(should (eq easy-mmode-test-mode t))))
-(provide 'easy-mmode-tests)
-
;;; easy-mmode-tests.el ends here
diff --git a/test/lisp/emacs-lisp/edebug-tests.el b/test/lisp/emacs-lisp/edebug-tests.el
index 4aae2870a3a..008e1e467ba 100644
--- a/test/lisp/emacs-lisp/edebug-tests.el
+++ b/test/lisp/emacs-lisp/edebug-tests.el
@@ -53,22 +53,20 @@ Since `should' failures which happen inside `post-command-hook' will
be trapped by the command loop, this preserves them until we get
back to the top level.")
-(defvar edebug-tests-keymap
- (let ((map (make-sparse-keymap)))
- (define-key map "@" 'edebug-tests-call-instrumented-func)
- (define-key map "C-u" 'universal-argument)
- (define-key map "C-p" 'previous-line)
- (define-key map "C-n" 'next-line)
- (define-key map "C-b" 'backward-char)
- (define-key map "C-a" 'move-beginning-of-line)
- (define-key map "C-e" 'move-end-of-line)
- (define-key map "C-k" 'kill-line)
- (define-key map "M-x" 'execute-extended-command)
- (define-key map "C-M-x" 'eval-defun)
- (define-key map "C-x X b" 'edebug-set-breakpoint)
- (define-key map "C-x X w" 'edebug-where)
- map)
- "Keys used by the keyboard macros in Edebug's tests.")
+(defvar-keymap edebug-tests-keymap
+ :doc "Keys used by the keyboard macros in Edebug's tests."
+ "@" 'edebug-tests-call-instrumented-func
+ "C-u" 'universal-argument
+ "C-p" 'previous-line
+ "C-n" 'next-line
+ "C-b" 'backward-char
+ "C-a" 'move-beginning-of-line
+ "C-e" 'move-end-of-line
+ "C-k" 'kill-line
+ "M-x" 'execute-extended-command
+ "C-M-x" 'eval-defun
+ "C-x X b" 'edebug-set-breakpoint
+ "C-x X w" 'edebug-where)
;;; Macros for defining tests:
@@ -107,27 +105,27 @@ back to the top level.")
"Set up the environment for an Edebug test BODY, run it, and clean up."
(declare (debug (body)))
`(edebug-tests-with-default-config
- (let ((edebug-tests-failure-in-post-command nil)
- (edebug-tests-temp-file (make-temp-file "edebug-tests-" nil ".el"))
- (find-file-suppress-same-file-warnings t))
- (edebug-tests-setup-code-file edebug-tests-temp-file)
- (ert-with-message-capture
- edebug-tests-messages
- (unwind-protect
- (with-current-buffer (find-file edebug-tests-temp-file)
- (read-only-mode)
- (setq lexical-binding t)
- (eval-buffer)
- ,@body
- (when edebug-tests-failure-in-post-command
- (signal (car edebug-tests-failure-in-post-command)
- (cdr edebug-tests-failure-in-post-command))))
- (unload-feature 'edebug-test-code)
- (with-current-buffer (find-file-noselect edebug-tests-temp-file)
- (set-buffer-modified-p nil))
- (ignore-errors (kill-buffer (find-file-noselect
- edebug-tests-temp-file)))
- (ignore-errors (delete-file edebug-tests-temp-file)))))))
+ (ert-with-temp-file edebug-tests-temp-file
+ :suffix ".el"
+ (let ((edebug-tests-failure-in-post-command nil)
+ (find-file-suppress-same-file-warnings t))
+ (edebug-tests-setup-code-file edebug-tests-temp-file)
+ (ert-with-message-capture
+ edebug-tests-messages
+ (unwind-protect
+ (with-current-buffer (find-file edebug-tests-temp-file)
+ (read-only-mode)
+ (setq lexical-binding t)
+ (eval-buffer)
+ ,@body
+ (when edebug-tests-failure-in-post-command
+ (signal (car edebug-tests-failure-in-post-command)
+ (cdr edebug-tests-failure-in-post-command))))
+ (unload-feature 'edebug-test-code)
+ (with-current-buffer (find-file-noselect edebug-tests-temp-file)
+ (set-buffer-modified-p nil))
+ (ignore-errors (kill-buffer (find-file-noselect
+ edebug-tests-temp-file)))))))))
;; The following macro and its support functions implement an extension
;; to keyboard macros to allow interleaving of keyboard macro
@@ -860,7 +858,8 @@ test and possibly others should be updated."
(let ((inhibit-read-only t))
(delete-region (point-min) (point-max))
(insert "`1"))
- (edebug-eval-defun nil)
+ (with-suppressed-warnings ((obsolete edebug-eval-defun))
+ (edebug-eval-defun nil))
;; `eval-defun' outputs its message to the echo area in a rather
;; funny way, so the "1" and the " (#o1, #x1, ?\C-a)" end up placed
;; there in separate pieces (via `print' rather than via `message').
@@ -870,7 +869,8 @@ test and possibly others should be updated."
(setq edebug-initial-mode 'go)
;; In Bug#23651 Edebug would hang reading `1.
- (edebug-eval-defun t)))
+ (with-suppressed-warnings ((obsolete edebug-eval-defun))
+ (edebug-eval-defun t))))
(ert-deftest edebug-tests-trivial-comma ()
"Edebug can read a trivial comma expression (Bug#23651)."
@@ -879,7 +879,8 @@ test and possibly others should be updated."
(delete-region (point-min) (point-max))
(insert ",1")
(read-only-mode)
- (should-error (edebug-eval-defun t))))
+ (with-suppressed-warnings ((obsolete edebug-eval-defun))
+ (should-error (edebug-eval-defun t)))))
(ert-deftest edebug-tests-circular-read-syntax ()
"Edebug can instrument code using circular read object syntax (Bug#23660)."
@@ -1103,5 +1104,14 @@ This avoids potential duplicate definitions (Bug#41988)."
(edebug-initial-mode 'Go-nonstop))
(eval-buffer))))
+(ert-deftest edebug-test-dot-reader ()
+ (with-temp-buffer
+ (insert "(defun x () `(t .,t))")
+ (goto-char (point-min))
+ (should (equal (save-excursion
+ (edebug-read-storing-offsets (current-buffer)))
+ (save-excursion
+ (read (current-buffer)))))))
+
(provide 'edebug-tests)
;;; edebug-tests.el ends here
diff --git a/test/lisp/emacs-lisp/eieio-tests/eieio-test-methodinvoke.el b/test/lisp/emacs-lisp/eieio-tests/eieio-test-methodinvoke.el
index be627b01012..af19c122b9f 100644
--- a/test/lisp/emacs-lisp/eieio-tests/eieio-test-methodinvoke.el
+++ b/test/lisp/emacs-lisp/eieio-tests/eieio-test-methodinvoke.el
@@ -55,6 +55,9 @@
;;; Code:
(require 'eieio)
+;; FIXME: See Bug#52971.
+(with-no-warnings
+ (require 'eieio-compat))
(require 'ert)
(defvar eieio-test-method-order-list nil
@@ -85,37 +88,40 @@
(defclass eitest-B-base2 () ())
(defclass eitest-B (eitest-B-base1 eitest-B-base2) ())
-(defmethod eitest-F :BEFORE ((_p eitest-B-base1))
- (eieio-test-method-store :BEFORE 'eitest-B-base1))
+(with-suppressed-warnings ((obsolete defmethod)
+ (obsolete defgeneric)
+ (obsolete call-next-method)
+ (obsolete next-method-p))
+ (defmethod eitest-F :BEFORE ((_p eitest-B-base1))
+ (eieio-test-method-store :BEFORE 'eitest-B-base1))
-(defmethod eitest-F :BEFORE ((_p eitest-B-base2))
- (eieio-test-method-store :BEFORE 'eitest-B-base2))
+ (defmethod eitest-F :BEFORE ((_p eitest-B-base2))
+ (eieio-test-method-store :BEFORE 'eitest-B-base2))
-(defmethod eitest-F :BEFORE ((_p eitest-B))
- (eieio-test-method-store :BEFORE 'eitest-B))
+ (defmethod eitest-F :BEFORE ((_p eitest-B))
+ (eieio-test-method-store :BEFORE 'eitest-B))
-(defmethod eitest-F ((_p eitest-B))
- (eieio-test-method-store :PRIMARY 'eitest-B)
- (call-next-method))
-
-(defmethod eitest-F ((_p eitest-B-base1))
- (eieio-test-method-store :PRIMARY 'eitest-B-base1)
- (call-next-method))
+ (defmethod eitest-F ((_p eitest-B))
+ (eieio-test-method-store :PRIMARY 'eitest-B)
+ (call-next-method))
-(defmethod eitest-F ((_p eitest-B-base2))
- (eieio-test-method-store :PRIMARY 'eitest-B-base2)
- (when (next-method-p)
+ (defmethod eitest-F ((_p eitest-B-base1))
+ (eieio-test-method-store :PRIMARY 'eitest-B-base1)
(call-next-method))
- )
-(defmethod eitest-F :AFTER ((_p eitest-B-base1))
- (eieio-test-method-store :AFTER 'eitest-B-base1))
+ (defmethod eitest-F ((_p eitest-B-base2))
+ (eieio-test-method-store :PRIMARY 'eitest-B-base2)
+ (when (next-method-p)
+ (call-next-method)))
-(defmethod eitest-F :AFTER ((_p eitest-B-base2))
- (eieio-test-method-store :AFTER 'eitest-B-base2))
+ (defmethod eitest-F :AFTER ((_p eitest-B-base1))
+ (eieio-test-method-store :AFTER 'eitest-B-base1))
-(defmethod eitest-F :AFTER ((_p eitest-B))
- (eieio-test-method-store :AFTER 'eitest-B))
+ (defmethod eitest-F :AFTER ((_p eitest-B-base2))
+ (eieio-test-method-store :AFTER 'eitest-B-base2))
+
+ (defmethod eitest-F :AFTER ((_p eitest-B))
+ (eieio-test-method-store :AFTER 'eitest-B)))
(ert-deftest eieio-test-method-order-list-3 ()
(let ((eieio-test-method-order-list nil)
@@ -138,9 +144,11 @@
;;; Test static invocation
;;
-(defmethod eitest-H :STATIC ((_class eitest-A))
- "No need to do work in here."
- 'moose)
+(with-suppressed-warnings ((obsolete defmethod)
+ (obsolete defgeneric))
+ (defmethod eitest-H :STATIC ((_class eitest-A))
+ "No need to do work in here."
+ 'moose))
(ert-deftest eieio-test-method-order-list-4 ()
;; Both of these situations should succeed.
@@ -149,17 +157,19 @@
;;; Return value from :PRIMARY
;;
-(defmethod eitest-I :BEFORE ((_a eitest-A))
- (eieio-test-method-store :BEFORE 'eitest-A)
- ":before")
+(with-suppressed-warnings ((obsolete defmethod)
+ (obsolete defgeneric))
+ (defmethod eitest-I :BEFORE ((_a eitest-A))
+ (eieio-test-method-store :BEFORE 'eitest-A)
+ ":before")
-(defmethod eitest-I :PRIMARY ((_a eitest-A))
- (eieio-test-method-store :PRIMARY 'eitest-A)
- ":primary")
+ (defmethod eitest-I :PRIMARY ((_a eitest-A))
+ (eieio-test-method-store :PRIMARY 'eitest-A)
+ ":primary")
-(defmethod eitest-I :AFTER ((_a eitest-A))
- (eieio-test-method-store :AFTER 'eitest-A)
- ":after")
+ (defmethod eitest-I :AFTER ((_a eitest-A))
+ (eieio-test-method-store :AFTER 'eitest-A)
+ ":after"))
(ert-deftest eieio-test-method-order-list-5 ()
(let ((eieio-test-method-order-list nil)
@@ -175,16 +185,18 @@
(defclass C-base2 () ())
(defclass C (C-base1 C-base2) ())
-;; Just use the obsolete name once, to make sure it also works.
-(defmethod constructor :STATIC ((_p C-base1) &rest _args)
- (eieio-test-method-store :STATIC 'C-base1)
- (if (next-method-p) (call-next-method))
- )
+(with-suppressed-warnings ((obsolete defmethod)
+ (obsolete defgeneric)
+ (obsolete next-method-p)
+ (obsolete call-next-method))
+ ;; Just use the obsolete name once, to make sure it also works.
+ (defmethod constructor :STATIC ((_p C-base1) &rest _args)
+ (eieio-test-method-store :STATIC 'C-base1)
+ (if (next-method-p) (call-next-method)))
-(defmethod make-instance :STATIC ((_p C-base2) &rest _args)
- (eieio-test-method-store :STATIC 'C-base2)
- (if (next-method-p) (call-next-method))
- )
+ (defmethod make-instance :STATIC ((_p C-base2) &rest _args)
+ (eieio-test-method-store :STATIC 'C-base2)
+ (if (next-method-p) (call-next-method))))
(cl-defmethod make-instance ((_p (subclass C)) &rest _args)
(eieio-test-method-store :STATIC 'C)
@@ -215,29 +227,32 @@
(defclass D-base2 (D-base0) () :method-invocation-order :depth-first)
(defclass D (D-base1 D-base2) () :method-invocation-order :depth-first)
-(defmethod eitest-F ((_p D))
- "D"
- (eieio-test-method-store :PRIMARY 'D)
- (call-next-method))
-
-(defmethod eitest-F ((_p D-base0))
- "D-base0"
- (eieio-test-method-store :PRIMARY 'D-base0)
- ;; This should have no next
- ;; (when (next-method-p) (call-next-method))
- )
+(with-suppressed-warnings ((obsolete defmethod)
+ (obsolete defgeneric)
+ (obsolete call-next-method)
+ (obsolete next-method-p))
+ (defmethod eitest-F ((_p D))
+ "D"
+ (eieio-test-method-store :PRIMARY 'D)
+ (call-next-method))
-(defmethod eitest-F ((_p D-base1))
- "D-base1"
- (eieio-test-method-store :PRIMARY 'D-base1)
- (call-next-method))
+ (defmethod eitest-F ((_p D-base0))
+ "D-base0"
+ (eieio-test-method-store :PRIMARY 'D-base0)
+ ;; This should have no next
+ ;; (when (next-method-p) (call-next-method))
+ )
-(defmethod eitest-F ((_p D-base2))
- "D-base2"
- (eieio-test-method-store :PRIMARY 'D-base2)
- (when (next-method-p)
+ (defmethod eitest-F ((_p D-base1))
+ "D-base1"
+ (eieio-test-method-store :PRIMARY 'D-base1)
(call-next-method))
- )
+
+ (defmethod eitest-F ((_p D-base2))
+ "D-base2"
+ (eieio-test-method-store :PRIMARY 'D-base2)
+ (when (next-method-p)
+ (call-next-method))))
(ert-deftest eieio-test-method-order-list-7 ()
(let ((eieio-test-method-order-list nil)
@@ -258,25 +273,28 @@
(defclass E-base2 (E-base0) () :method-invocation-order :breadth-first)
(defclass E (E-base1 E-base2) () :method-invocation-order :breadth-first)
-(defmethod eitest-F ((_p E))
- (eieio-test-method-store :PRIMARY 'E)
- (call-next-method))
-
-(defmethod eitest-F ((_p E-base0))
- (eieio-test-method-store :PRIMARY 'E-base0)
- ;; This should have no next
- ;; (when (next-method-p) (call-next-method))
- )
+(with-suppressed-warnings ((obsolete defmethod)
+ (obsolete defgeneric)
+ (obsolete next-method-p)
+ (obsolete call-next-method))
+ (defmethod eitest-F ((_p E))
+ (eieio-test-method-store :PRIMARY 'E)
+ (call-next-method))
-(defmethod eitest-F ((_p E-base1))
- (eieio-test-method-store :PRIMARY 'E-base1)
- (call-next-method))
+ (defmethod eitest-F ((_p E-base0))
+ (eieio-test-method-store :PRIMARY 'E-base0)
+ ;; This should have no next
+ ;; (when (next-method-p) (call-next-method))
+ )
-(defmethod eitest-F ((_p E-base2))
- (eieio-test-method-store :PRIMARY 'E-base2)
- (when (next-method-p)
+ (defmethod eitest-F ((_p E-base1))
+ (eieio-test-method-store :PRIMARY 'E-base1)
(call-next-method))
- )
+
+ (defmethod eitest-F ((_p E-base2))
+ (eieio-test-method-store :PRIMARY 'E-base2)
+ (when (next-method-p)
+ (call-next-method))))
(ert-deftest eieio-test-method-order-list-8 ()
(let ((eieio-test-method-order-list nil)
@@ -295,24 +313,32 @@
(defclass eitest-Ja ()
())
-(defmethod initialize-instance :after ((_this eitest-Ja) &rest _slots)
- ;(message "+Ja")
- ;; FIXME: Using next-method-p in an after-method is invalid!
- (when (next-method-p)
- (call-next-method))
- ;(message "-Ja")
- )
+(with-suppressed-warnings ((obsolete defmethod)
+ (obsolete defgeneric)
+ (obsolete next-method-p)
+ (obsolete call-next-method))
+ (defmethod initialize-instance :after ((_this eitest-Ja) &rest _slots)
+ ;;(message "+Ja")
+ ;; FIXME: Using next-method-p in an after-method is invalid!
+ (when (next-method-p)
+ (call-next-method))
+ ;;(message "-Ja")
+ ))
(defclass eitest-Jb ()
())
-(defmethod initialize-instance :after ((_this eitest-Jb) &rest _slots)
- ;(message "+Jb")
- ;; FIXME: Using next-method-p in an after-method is invalid!
- (when (next-method-p)
- (call-next-method))
- ;(message "-Jb")
- )
+(with-suppressed-warnings ((obsolete defmethod)
+ (obsolete defgeneric)
+ (obsolete next-method-p)
+ (obsolete call-next-method))
+ (defmethod initialize-instance :after ((_this eitest-Jb) &rest _slots)
+ ;;(message "+Jb")
+ ;; FIXME: Using next-method-p in an after-method is invalid!
+ (when (next-method-p)
+ (call-next-method))
+ ;;(message "-Jb")
+ ))
(defclass eitest-Jc (eitest-Jb)
())
@@ -320,12 +346,16 @@
(defclass eitest-Jd (eitest-Jc eitest-Ja)
())
-(defmethod initialize-instance ((_this eitest-Jd) &rest _slots)
- ;(message "+Jd")
- (when (next-method-p)
- (call-next-method))
- ;(message "-Jd")
- )
+(with-suppressed-warnings ((obsolete defmethod)
+ (obsolete defgeneric)
+ (obsolete next-method-p)
+ (obsolete call-next-method))
+ (defmethod initialize-instance ((_this eitest-Jd) &rest _slots)
+ ;;(message "+Jd")
+ (when (next-method-p)
+ (call-next-method))
+ ;;(message "-Jd")
+ ))
(ert-deftest eieio-test-method-order-list-9 ()
(should (eitest-Jd)))
@@ -345,32 +375,36 @@
(defclass CNM-2 (CNM-1-1 CNM-1-2)
())
-(defmethod CNM-M ((this CNM-0) args)
- (push (cons 'CNM-0 (copy-sequence args))
- eieio-test-call-next-method-arguments)
- (when (next-method-p)
- (call-next-method
- this (cons 'CNM-0 args))))
-
-(defmethod CNM-M ((this CNM-1-1) args)
- (push (cons 'CNM-1-1 (copy-sequence args))
- eieio-test-call-next-method-arguments)
- (when (next-method-p)
- (call-next-method
- this (cons 'CNM-1-1 args))))
-
-(defmethod CNM-M ((_this CNM-1-2) args)
- (push (cons 'CNM-1-2 (copy-sequence args))
- eieio-test-call-next-method-arguments)
- (when (next-method-p)
- (call-next-method)))
-
-(defmethod CNM-M ((this CNM-2) args)
- (push (cons 'CNM-2 (copy-sequence args))
- eieio-test-call-next-method-arguments)
- (when (next-method-p)
- (call-next-method
- this (cons 'CNM-2 args))))
+(with-suppressed-warnings ((obsolete defmethod)
+ (obsolete defgeneric)
+ (obsolete next-method-p)
+ (obsolete call-next-method))
+ (defmethod CNM-M ((this CNM-0) args)
+ (push (cons 'CNM-0 (copy-sequence args))
+ eieio-test-call-next-method-arguments)
+ (when (next-method-p)
+ (call-next-method
+ this (cons 'CNM-0 args))))
+
+ (defmethod CNM-M ((this CNM-1-1) args)
+ (push (cons 'CNM-1-1 (copy-sequence args))
+ eieio-test-call-next-method-arguments)
+ (when (next-method-p)
+ (call-next-method
+ this (cons 'CNM-1-1 args))))
+
+ (defmethod CNM-M ((_this CNM-1-2) args)
+ (push (cons 'CNM-1-2 (copy-sequence args))
+ eieio-test-call-next-method-arguments)
+ (when (next-method-p)
+ (call-next-method)))
+
+ (defmethod CNM-M ((this CNM-2) args)
+ (push (cons 'CNM-2 (copy-sequence args))
+ eieio-test-call-next-method-arguments)
+ (when (next-method-p)
+ (call-next-method
+ this (cons 'CNM-2 args)))))
(ert-deftest eieio-test-method-order-list-10 ()
(let ((eieio-test-call-next-method-arguments nil))
diff --git a/test/lisp/emacs-lisp/eieio-tests/eieio-test-persist.el b/test/lisp/emacs-lisp/eieio-tests/eieio-test-persist.el
index fcd2f2f45a6..e839e1262fa 100644
--- a/test/lisp/emacs-lisp/eieio-tests/eieio-test-persist.el
+++ b/test/lisp/emacs-lisp/eieio-tests/eieio-test-persist.el
@@ -99,7 +99,7 @@ This is usually a symbol that starts with `:'."
(defclass persist-simple (eieio-persistent)
((slot1 :initarg :slot1
:type symbol
- :initform moose)
+ :initform 'moose)
(slot2 :initarg :slot2
:initform "foo")
(slot3 :initform 2))
diff --git a/test/lisp/emacs-lisp/eieio-tests/eieio-tests.el b/test/lisp/emacs-lisp/eieio-tests/eieio-tests.el
index c03b3854e49..9b27d4ab938 100644
--- a/test/lisp/emacs-lisp/eieio-tests/eieio-tests.el
+++ b/test/lisp/emacs-lisp/eieio-tests/eieio-tests.el
@@ -27,18 +27,26 @@
(require 'ert)
(require 'eieio)
(require 'eieio-base)
+;; FIXME: See Bug#52971.
+(with-no-warnings
+ (require 'eieio-compat))
(require 'eieio-opt)
(eval-when-compile (require 'cl-lib))
+;; Silence byte-compiler.
+(eval-when-compile
+ (dolist (slot '(:a :b ooga-booga :derived-value missing-slot))
+ (cl-pushnew slot eieio--known-slot-names)))
+
;;; Code:
;; Set up some test classes
(defclass class-a ()
((water :initarg :water
- :initform h20
+ :initform 'h20
:type symbol
:documentation "Detail about water.")
- (classslot :initform penguin
+ (classslot :initform 'penguin
:type symbol
:documentation "A class allocated slot."
:allocation :class)
@@ -50,6 +58,9 @@
)
"Class A.")
+;; Silence compiler warning about `water' not being a class-allocated slot.
+(defclass eieio-tests--dummy () ((water :allocation :class)))
+
(defclass class-b ()
((land :initform "Sc"
:type string
@@ -61,40 +72,41 @@
:documentation "Detail about amphibian on land and water."))
"Class A and B combined.")
-(defclass class-c ()
- ((slot-1 :initarg :moose
- :initform moose
- :type symbol
- :allocation :instance
- :documentation "First slot testing slot arguments."
- :custom symbol
- :label "Wild Animal"
- :group borg
- :protection :public)
- (slot-2 :initarg :penguin
- :initform "penguin"
- :type string
- :allocation :instance
- :documentation "Second slot testing slot arguments."
- :custom string
- :label "Wild bird"
- :group vorlon
- :accessor get-slot-2
- :protection :private)
- (slot-3 :initarg :emu
- :initform emu
- :type symbol
- :allocation :class
- :documentation "Third slot test class allocated accessor"
- :custom symbol
- :label "Fuzz"
- :group tokra
- :accessor get-slot-3
- :protection :private)
- )
- (:custom-groups (foo))
- "A class for testing slot arguments."
- )
+(with-no-warnings ; FIXME: Make more specific.
+ (defclass class-c ()
+ ((slot-1 :initarg :moose
+ :initform 'moose
+ :type symbol
+ :allocation :instance
+ :documentation "First slot testing slot arguments."
+ :custom symbol
+ :label "Wild Animal"
+ :group borg
+ :protection :public)
+ (slot-2 :initarg :penguin
+ :initform "penguin"
+ :type string
+ :allocation :instance
+ :documentation "Second slot testing slot arguments."
+ :custom string
+ :label "Wild bird"
+ :group vorlon
+ :accessor get-slot-2
+ :protection :private)
+ (slot-3 :initarg :emu
+ :initform 'emu
+ :type symbol
+ :allocation :class
+ :documentation "Third slot test class allocated accessor"
+ :custom symbol
+ :label "Fuzz"
+ :group tokra
+ :accessor get-slot-3
+ :protection :private)
+ )
+ (:custom-groups (foo))
+ "A class for testing slot arguments."
+ ))
(defclass class-subc (class-c)
((slot-1 ;; :initform moose - don't override this
@@ -132,21 +144,25 @@
;; (error "invalid-slot-type thrown when eieio-error-unsupported-class-tags is nil")
;; )))
+;; Silence byte-compiler.
+(declare-function eitest-subordinate--eieio-childp nil)
+(declare-function class-alloc-initarg--eieio-childp nil)
(ert-deftest eieio-test-01-mix-alloc-initarg ()
;; Only run this test if the message framework thingy works.
- (when (and (message "foo") (string= "foo" (current-message)))
+ (skip-unless (and (message "foo") (string= "foo" (current-message))))
- ;; Defining this class should generate a warning(!) message that
- ;; you should not mix :initarg with class allocated slots.
+ ;; Defining this class should generate a warning(!) message that
+ ;; you should not mix :initarg with class allocated slots.
+ (with-no-warnings ; FIXME: Make more specific.
(defclass class-alloc-initarg ()
((throwwarning :initarg :throwwarning
- :allocation :class))
- "Throw a warning mixing allocation class and an initarg.")
+ :allocation :class))
+ "Throw a warning mixing allocation class and an initarg."))
- ;; Check that message is there
- (should (current-message))
- (should (string-match "Class allocated slots do not need :initarg"
- (current-message)))))
+ ;; Check that message is there
+ (should (current-message))
+ (should (string-match "Class allocated slots do not need :initarg"
+ (current-message))))
(defclass abstract-class ()
((some-slot :initarg :some-slot
@@ -160,30 +176,33 @@
;; error
(should-error (abstract-class)))
-(defgeneric generic1 () "First generic function.")
+(with-suppressed-warnings ((obsolete defgeneric))
+ (defgeneric generic1 () "First generic function."))
(ert-deftest eieio-test-03-generics ()
- (defun anormalfunction () "A plain function for error testing." nil)
- (should-error
- (progn
- (defgeneric anormalfunction ()
- "Attempt to turn it into a generic.")))
-
- ;; Check that generic-p works
- (should (generic-p 'generic1))
-
- (defmethod generic1 ((c class-a))
- "Method on generic1."
- 'monkey)
-
- (defmethod generic1 (not-an-object)
- "Method generic1 that can take a non-object."
- not-an-object)
-
- (let ((ans-obj (generic1 (class-a)))
- (ans-num (generic1 666)))
- (should (eq ans-obj 'monkey))
- (should (eq ans-num 666))))
+ (with-suppressed-warnings ((obsolete defmethod)
+ (obsolete defgeneric))
+ (defun anormalfunction () "A plain function for error testing." nil)
+ (should-error
+ (progn
+ (defgeneric anormalfunction ()
+ "Attempt to turn it into a generic.")))
+
+ ;; Check that generic-p works
+ (should (generic-p 'generic1))
+
+ (defmethod generic1 ((_c class-a))
+ "Method on generic1."
+ 'monkey)
+
+ (defmethod generic1 (not-an-object)
+ "Method generic1 that can take a non-object."
+ not-an-object)
+
+ (let ((ans-obj (generic1 (class-a)))
+ (ans-num (generic1 666)))
+ (should (eq ans-obj 'monkey))
+ (should (eq ans-num 666)))))
(defclass static-method-class ()
((some-slot :initform nil
@@ -191,12 +210,17 @@
:documentation "A slot."))
:documentation "A class used for testing static methods.")
-(defmethod static-method-class-method :STATIC ((c static-method-class) value)
- "Test static methods.
+(with-suppressed-warnings ((obsolete defmethod)
+ (obsolete defgeneric))
+ (defmethod static-method-class-method :STATIC ((c static-method-class) value)
+ "Test static methods.
Argument C is the class bound to this static method."
- (if (eieio-object-p c) (setq c (eieio-object-class c)))
- (oset-default c some-slot value))
+ (if (eieio-object-p c) (setq c (eieio-object-class c)))
+ (oset-default c some-slot value)))
+;; Silence byte-compiler.
+(declare-function static-method-class-2 nil)
+(declare-function static-method-class-2--eieio-childp nil)
(ert-deftest eieio-test-04-static-method ()
;; Call static method on a class and see if it worked
(static-method-class-method 'static-method-class 'class)
@@ -209,11 +233,13 @@ Argument C is the class bound to this static method."
()
"A second class after the previous for static methods.")
- (defmethod static-method-class-method :STATIC ((c static-method-class-2) value)
- "Test static methods.
+ (with-suppressed-warnings ((obsolete defmethod)
+ (obsolete defgeneric))
+ (defmethod static-method-class-method :STATIC ((c static-method-class-2) value)
+ "Test static methods.
Argument C is the class bound to this static method."
- (if (eieio-object-p c) (setq c (eieio-object-class c)))
- (oset-default c some-slot (intern (concat "moose-" (symbol-name value)))))
+ (if (eieio-object-p c) (setq c (eieio-object-class c)))
+ (oset-default c some-slot (intern (concat "moose-" (symbol-name value))))))
(static-method-class-method 'static-method-class-2 'class)
(should (eq (oref-default 'static-method-class-2 some-slot) 'moose-class))
@@ -240,64 +266,71 @@ Argument C is the class bound to this static method."
(should (make-instance 'class-a :water 'cho))
(should (make-instance 'class-b)))
-(defmethod class-cn ((a class-a))
- "Try calling `call-next-method' when there isn't one.
+(with-suppressed-warnings ((obsolete defmethod)
+ (obsolete defgeneric))
+ (defmethod class-cn ((_a class-a))
+ "Try calling `call-next-method' when there isn't one.
Argument A is object of type symbol `class-a'."
- (call-next-method))
+ (with-suppressed-warnings ((obsolete call-next-method))
+ (call-next-method)))
-(defmethod no-next-method ((a class-a) &rest args)
- "Override signal throwing for variable `class-a'.
+ (defmethod no-next-method ((_a class-a) &rest _args)
+ "Override signal throwing for variable `class-a'.
Argument A is the object of class variable `class-a'."
- 'moose)
+ 'moose))
(ert-deftest eieio-test-08-call-next-method ()
;; Play with call-next-method
(should (eq (class-cn eitest-ab) 'moose)))
-(defmethod no-applicable-method ((b class-b) method &rest args)
- "No need.
+(with-suppressed-warnings ((obsolete defmethod)
+ (obsolete defgeneric))
+ (defmethod no-applicable-method ((_b class-b) _method &rest _args)
+ "No need.
Argument B is for booger.
METHOD is the method that was attempting to be called."
- 'moose)
+ 'moose))
(ert-deftest eieio-test-09-no-applicable-method ()
;; Non-existing methods.
(should (eq (class-cn eitest-b) 'moose)))
-(defmethod class-fun ((a class-a))
- "Fun with class A."
- 'moose)
+(with-suppressed-warnings ((obsolete defmethod)
+ (obsolete defgeneric))
+ (defmethod class-fun ((_a class-a))
+ "Fun with class A."
+ 'moose)
-(defmethod class-fun ((b class-b))
- "Fun with class B."
- (error "Class B fun should not be called")
- )
+ (defmethod class-fun ((_b class-b))
+ "Fun with class B."
+ (error "Class B fun should not be called"))
-(defmethod class-fun-foo ((b class-b))
- "Foo Fun with class B."
- 'moose)
+ (defmethod class-fun-foo ((_b class-b))
+ "Foo Fun with class B."
+ 'moose)
-(defmethod class-fun2 ((a class-a))
- "More fun with class A."
- 'moose)
+ (defmethod class-fun2 ((_a class-a))
+ "More fun with class A."
+ 'moose)
-(defmethod class-fun2 ((b class-b))
- "More fun with class B."
- (error "Class B fun2 should not be called")
- )
+ (defmethod class-fun2 ((_b class-b))
+ "More fun with class B."
+ (error "Class B fun2 should not be called"))
-(defmethod class-fun2 ((ab class-ab))
- "More fun with class AB."
- (call-next-method))
+ (defmethod class-fun2 ((_ab class-ab))
+ "More fun with class AB."
+ (with-suppressed-warnings ((obsolete call-next-method))
+ (call-next-method)))
-;; How about if B is the only slot?
-(defmethod class-fun3 ((b class-b))
- "Even More fun with class B."
- 'moose)
+ ;; How about if B is the only slot?
+ (defmethod class-fun3 ((_b class-b))
+ "Even More fun with class B."
+ 'moose)
-(defmethod class-fun3 ((ab class-ab))
- "Even More fun with class AB."
- (call-next-method))
+ (defmethod class-fun3 ((_ab class-ab))
+ "Even More fun with class AB."
+ (with-suppressed-warnings ((obsolete call-next-method))
+ (call-next-method))))
(ert-deftest eieio-test-10-multiple-inheritance ()
;; play with methods and mi
@@ -314,20 +347,22 @@ METHOD is the method that was attempting to be called."
(defvar class-fun-value-seq '())
-(defmethod class-fun-value :BEFORE ((a class-a))
- "Return `before', and push `before' in `class-fun-value-seq'."
- (push 'before class-fun-value-seq)
- 'before)
-
-(defmethod class-fun-value :PRIMARY ((a class-a))
- "Return `primary', and push `primary' in `class-fun-value-seq'."
- (push 'primary class-fun-value-seq)
- 'primary)
-
-(defmethod class-fun-value :AFTER ((a class-a))
- "Return `after', and push `after' in `class-fun-value-seq'."
- (push 'after class-fun-value-seq)
- 'after)
+(with-suppressed-warnings ((obsolete defmethod)
+ (obsolete defgeneric))
+ (defmethod class-fun-value :BEFORE ((_a class-a))
+ "Return `before', and push `before' in `class-fun-value-seq'."
+ (push 'before class-fun-value-seq)
+ 'before)
+
+ (defmethod class-fun-value :PRIMARY ((_a class-a))
+ "Return `primary', and push `primary' in `class-fun-value-seq'."
+ (push 'primary class-fun-value-seq)
+ 'primary)
+
+ (defmethod class-fun-value :AFTER ((_a class-a))
+ "Return `after', and push `after' in `class-fun-value-seq'."
+ (push 'after class-fun-value-seq)
+ 'after))
(ert-deftest eieio-test-12-generic-function-call ()
;; Test value of a generic function call
@@ -343,20 +378,23 @@ METHOD is the method that was attempting to be called."
;;
(ert-deftest eieio-test-13-init-methods ()
- (defmethod initialize-instance ((a class-a) &rest slots)
- "Initialize the slots of class-a."
- (call-next-method)
- (if (/= (oref a test-tag) 1)
- (error "shared-initialize test failed."))
- (oset a test-tag 2))
-
- (defmethod shared-initialize ((a class-a) &rest slots)
- "Shared initialize method for class-a."
- (call-next-method)
- (oset a test-tag 1))
-
- (let ((ca (class-a)))
- (should (= (oref ca test-tag) 2))))
+ (with-suppressed-warnings ((obsolete defmethod)
+ (obsolete defgeneric)
+ (obsolete call-next-method))
+ (defmethod initialize-instance ((a class-a) &rest _slots)
+ "Initialize the slots of class-a."
+ (call-next-method)
+ (if (/= (oref a test-tag) 1)
+ (error "shared-initialize test failed."))
+ (oset a test-tag 2))
+
+ (defmethod shared-initialize ((a class-a) &rest _slots)
+ "Shared initialize method for class-a."
+ (call-next-method)
+ (oset a test-tag 1))
+
+ (let ((ca (class-a)))
+ (should (= (oref ca test-tag) 2)))))
;;; Perform slot testing
@@ -368,10 +406,11 @@ METHOD is the method that was attempting to be called."
(should (oref eitest-ab amphibian)))
(ert-deftest eieio-test-15-slot-missing ()
-
- (defmethod slot-missing ((ab class-ab) &rest foo)
- "If a slot in AB is unbound, return something cool. FOO."
- 'moose)
+ (with-suppressed-warnings ((obsolete defmethod)
+ (obsolete defgeneric))
+ (defmethod slot-missing ((_ab class-ab) &rest _foo)
+ "If a slot in AB is unbound, return something cool. FOO."
+ 'moose))
(should (eq (oref eitest-ab ooga-booga) 'moose))
(should-error (oref eitest-a ooga-booga) :type 'invalid-slot-name))
@@ -391,17 +430,20 @@ METHOD is the method that was attempting to be called."
(defclass virtual-slot-class ()
((base-value :initarg :base-value))
"Class has real slot :base-value and simulated slot :derived-value.")
-(defmethod slot-missing ((vsc virtual-slot-class)
- slot-name operation &optional new-value)
- "Simulate virtual slot derived-value."
- (cond
- ((or (eq slot-name :derived-value)
- (eq slot-name 'derived-value))
- (with-slots (base-value) vsc
- (if (eq operation 'oref)
- (+ base-value 1)
- (setq base-value (- new-value 1)))))
- (t (call-next-method))))
+(with-suppressed-warnings ((obsolete defmethod)
+ (obsolete defgeneric))
+ (defmethod slot-missing ((vsc virtual-slot-class)
+ slot-name operation &optional new-value)
+ "Simulate virtual slot derived-value."
+ (cond
+ ((or (eq slot-name :derived-value)
+ (eq slot-name 'derived-value))
+ (with-slots (base-value) vsc
+ (if (eq operation 'oref)
+ (+ base-value 1)
+ (setq base-value (- new-value 1)))))
+ (t (with-suppressed-warnings ((obsolete call-next-method))
+ (call-next-method))))))
(ert-deftest eieio-test-17-virtual-slot ()
(setq eitest-vsca (virtual-slot-class :base-value 1))
@@ -424,35 +466,37 @@ METHOD is the method that was attempting to be called."
(should (= (oref eitest-vscb :derived-value) 5)))
(ert-deftest eieio-test-18-slot-unbound ()
-
- (defmethod slot-unbound ((a class-a) &rest foo)
- "If a slot in A is unbound, ignore FOO."
- 'moose)
-
- (should (eq (oref eitest-a water) 'moose))
-
- ;; Check if oset of unbound works
- (oset eitest-a water 'moose)
- (should (eq (oref eitest-a water) 'moose))
-
- ;; oref/oref-default comparison
- (should-not (eq (oref eitest-a water) (oref-default eitest-a water)))
-
- ;; oset-default -> oref/oref-default comparison
- (oset-default (eieio-object-class eitest-a) water 'moose)
- (should (eq (oref eitest-a water) (oref-default eitest-a water)))
-
- ;; After setting 'water to 'moose, make sure a new object has
- ;; the right stuff.
- (oset-default (eieio-object-class eitest-a) water 'penguin)
- (should (eq (oref (class-a) water) 'penguin))
-
- ;; Revert the above
- (defmethod slot-unbound ((a class-a) &rest foo)
- "If a slot in A is unbound, ignore FOO."
- ;; Disable the old slot-unbound so we can run this test
- ;; more than once
- (call-next-method)))
+ (with-suppressed-warnings ((obsolete defmethod)
+ (obsolete defgeneric))
+ (defmethod slot-unbound ((_a class-a) &rest _foo)
+ "If a slot in A is unbound, ignore FOO."
+ 'moose)
+
+ (should (eq (oref eitest-a water) 'moose))
+
+ ;; Check if oset of unbound works
+ (oset eitest-a water 'moose)
+ (should (eq (oref eitest-a water) 'moose))
+
+ ;; oref/oref-default comparison
+ (should-not (eq (oref eitest-a water) (oref-default eitest-a water)))
+
+ ;; oset-default -> oref/oref-default comparison
+ (oset-default (eieio-object-class eitest-a) water 'moose)
+ (should (eq (oref eitest-a water) (oref-default eitest-a water)))
+
+ ;; After setting 'water to 'moose, make sure a new object has
+ ;; the right stuff.
+ (oset-default (eieio-object-class eitest-a) water 'penguin)
+ (should (eq (oref (class-a) water) 'penguin))
+
+ ;; Revert the above
+ (defmethod slot-unbound ((_a class-a) &rest _foo)
+ "If a slot in A is unbound, ignore FOO."
+ ;; Disable the old slot-unbound so we can run this test
+ ;; more than once
+ (with-suppressed-warnings ((obsolete call-next-method))
+ (call-next-method)))))
(ert-deftest eieio-test-19-slot-type-checking ()
;; Slot type checking
@@ -489,7 +533,7 @@ METHOD is the method that was attempting to be called."
(defclass inittest nil
((staticval :initform 1)
- (symval :initform eieio-test-permuting-value)
+ (symval :initform 'eieio-test-permuting-value)
(evalval :initform (symbol-value 'eieio-test-permuting-value))
(evalnow :initform (symbol-value 'eieio-test-permuting-value)
:allocation :class)
@@ -506,8 +550,10 @@ METHOD is the method that was attempting to be called."
(should (eq (oref eitest-pvinit evalval) 2))
(should (eq (oref eitest-pvinit evalnow) 1)))
+;; Silence byte-compiler.
(defvar eitest-tests nil)
-
+(declare-function eitest-superior nil)
+(declare-function eitest-superior--eieio-childp nil)
(ert-deftest eieio-test-22-init-forms-dont-match-runnable ()
;; Init forms with types that don't match the runnable.
(defclass eitest-subordinate nil
@@ -515,7 +561,7 @@ METHOD is the method that was attempting to be called."
"Test class that will be a calculated value.")
(defclass eitest-superior nil
- ((sub :initform (eitest-subordinate)
+ ((sub :initform (funcall #'eitest-subordinate)
:type eitest-subordinate))
"A class with an initform that creates a class.")
@@ -555,7 +601,10 @@ METHOD is the method that was attempting to be called."
(should-not (cl-typep listooa '(list-of class-b)))
(should-not (cl-typep listoob '(list-of class-a)))))
+;; Silence byte-compiler.
(defvar eitest-t1 nil)
+(declare-function eieio-tests-initform-not-evaluated-when-initarg-is-present nil)
+(declare-function eieio-tests-initform-not-evaluated-when-initarg-is-present--eieio-childp nil)
(ert-deftest eieio-test-25-slot-tests ()
(setq eitest-t1 (class-c))
;; Slot initialization
@@ -617,12 +666,14 @@ METHOD is the method that was attempting to be called."
()
"Protection testing baseclass.")
-(defmethod prot0-slot-2 ((s2 prot-0))
- "Try to access slot-2 from this class which doesn't have it.
+(with-suppressed-warnings ((obsolete defmethod)
+ (obsolete defgeneric))
+ (defmethod prot0-slot-2 ((s2 prot-0))
+ "Try to access slot-2 from this class which doesn't have it.
The object S2 passed in will be of class prot-1, which does have
the slot. This could be allowed, and currently is in EIEIO.
Needed by the eieio persistent base class."
- (oref s2 slot-2))
+ (oref s2 slot-2)))
(defclass prot-1 (prot-0)
((slot-1 :initarg :slot-1
@@ -640,26 +691,28 @@ Needed by the eieio persistent base class."
nil
"A class for testing the :protection option.")
-(defmethod prot1-slot-2 ((s2 prot-1))
- "Try to access slot-2 in S2."
- (oref s2 slot-2))
+(with-suppressed-warnings ((obsolete defmethod)
+ (obsolete defgeneric))
+ (defmethod prot1-slot-2 ((s2 prot-1))
+ "Try to access slot-2 in S2."
+ (oref s2 slot-2))
-(defmethod prot1-slot-2 ((s2 prot-2))
- "Try to access slot-2 in S2."
- (oref s2 slot-2))
+ (defmethod prot1-slot-2 ((s2 prot-2))
+ "Try to access slot-2 in S2."
+ (oref s2 slot-2))
-(defmethod prot1-slot-3-only ((s2 prot-1))
- "Try to access slot-3 in S2.
+ (defmethod prot1-slot-3-only ((s2 prot-1))
+ "Try to access slot-3 in S2.
Do not override for `prot-2'."
- (oref s2 slot-3))
+ (oref s2 slot-3))
-(defmethod prot1-slot-3 ((s2 prot-1))
- "Try to access slot-3 in S2."
- (oref s2 slot-3))
+ (defmethod prot1-slot-3 ((s2 prot-1))
+ "Try to access slot-3 in S2."
+ (oref s2 slot-3))
-(defmethod prot1-slot-3 ((s2 prot-2))
- "Try to access slot-3 in S2."
- (oref s2 slot-3))
+ (defmethod prot1-slot-3 ((s2 prot-2))
+ "Try to access slot-3 in S2."
+ (oref s2 slot-3)))
(defvar eitest-p1 nil)
(defvar eitest-p2 nil)
@@ -729,7 +782,7 @@ Do not override for `prot-2'."
(should (eq (oref eitest-II3 slot3) 'penguin)))
(defclass slotattr-base ()
- ((initform :initform init)
+ ((initform :initform 'init)
(type :type list)
(initarg :initarg :initarg)
(protection :protection :private)
@@ -744,7 +797,7 @@ Do not override for `prot-2'."
Subclasses to override slot attributes.")
(defclass slotattr-ok (slotattr-base)
- ((initform :initform no-init)
+ ((initform :initform 'no-init)
(initarg :initarg :initblarg)
(custom :custom string
:label "One String"
@@ -778,28 +831,29 @@ Subclasses to override slot attributes.")
(let ((obj (slotattr-ok)))
(should (eq (oref obj initform) 'no-init))))
-(defclass slotattr-class-base ()
- ((initform :allocation :class
- :initform init)
- (type :allocation :class
- :type list)
- (initarg :allocation :class
- :initarg :initarg)
- (protection :allocation :class
- :protection :private)
- (custom :allocation :class
- :custom (repeat string)
- :label "Custom Strings"
- :group moose)
- (docstring :allocation :class
- :documentation
- "Replace the doc-string for this property.")
- )
- "Baseclass we will attempt to subclass.
-Subclasses to override slot attributes.")
+(with-no-warnings ; FIXME: Make more specific.
+ (defclass slotattr-class-base ()
+ ((initform :allocation :class
+ :initform 'init)
+ (type :allocation :class
+ :type list)
+ (initarg :allocation :class
+ :initarg :initarg)
+ (protection :allocation :class
+ :protection :private)
+ (custom :allocation :class
+ :custom (repeat string)
+ :label "Custom Strings"
+ :group moose)
+ (docstring :allocation :class
+ :documentation
+ "Replace the doc-string for this property.")
+ )
+ "Baseclass we will attempt to subclass.
+Subclasses to override slot attributes."))
(defclass slotattr-class-ok (slotattr-class-base)
- ((initform :initform no-init)
+ ((initform :initform 'no-init)
(initarg :initarg :initblarg)
(custom :custom string
:label "One String"
@@ -861,7 +915,7 @@ Subclasses to override slot attributes.")
(should (setq eitest-CLONETEST2 (clone eitest-CLONETEST1))))
(defclass IT (eieio-instance-tracker)
- ((tracking-symbol :initform IT-list)
+ ((tracking-symbol :initform 'IT-list)
(slot1 :initform 'die))
"Instance Tracker test object.")
@@ -914,13 +968,20 @@ Subclasses to override slot attributes.")
(defclass eieio--testing () ())
-(defmethod constructor :static ((_x eieio--testing) newname &rest _args)
- (list newname 2))
+(with-suppressed-warnings ((obsolete defmethod)
+ (obsolete defgeneric))
+ (defmethod constructor :static ((_x eieio--testing) newname &rest _args)
+ (list newname 2)))
(ert-deftest eieio-test-37-obsolete-name-in-constructor ()
;; FIXME repeated intermittent failures on hydra and elsewhere (bug#24503).
:tags '(:unstable)
- (should (equal (eieio--testing "toto") '("toto" 2))))
+ ;; Disable byte-compiler "Warning: Obsolete name arg "toto" to
+ ;; constructor eieio--testing". This could be made more specific
+ ;; with changes to `with-suppressed-warnings', but it's not worth
+ ;; the hassle for just this one test.
+ (with-no-warnings
+ (should (equal (eieio--testing "toto") '("toto" 2)))))
(ert-deftest eieio-autoload ()
"Tests to see whether reftex-auc has been autoloaded"
@@ -969,6 +1030,21 @@ Subclasses to override slot attributes.")
(should (eieio-instance-inheritor-slot-boundp C :b))
(should-not (eieio-instance-inheritor-slot-boundp C :c))))
+;;;; Interaction with defstruct
+
+(cl-defstruct eieio-test--struct a b (c nil :read-only t))
+
+(ert-deftest eieio-test-defstruct-slot-value ()
+ (let ((x (make-eieio-test--struct :a 'A :b 'B :c 'C)))
+ (should (eq (eieio-test--struct-a x)
+ (slot-value x 'a)))
+ (should (eq (eieio-test--struct-b x)
+ (slot-value x 'b)))
+ (should (eq (eieio-test--struct-c x)
+ (slot-value x 'c)))
+ (setf (slot-value x 'a) 1)
+ (should (eq (eieio-test--struct-a x) 1))
+ (should-error (setf (slot-value x 'c) 3) :type 'eieio-read-only)))
(provide 'eieio-tests)
diff --git a/test/lisp/emacs-lisp/ert-tests.el b/test/lisp/emacs-lisp/ert-tests.el
index e93ec18406c..84c28e11315 100644
--- a/test/lisp/emacs-lisp/ert-tests.el
+++ b/test/lisp/emacs-lisp/ert-tests.el
@@ -39,10 +39,11 @@
(defun ert-self-test ()
"Run ERT's self-tests and make sure they actually ran."
(let ((window-configuration (current-window-configuration)))
- (let ((ert--test-body-was-run nil))
+ (let ((ert--test-body-was-run nil)
+ (ert--output-buffer-name " *ert self-tests*"))
;; The buffer name chosen here should not compete with the default
;; results buffer name for completion in `switch-to-buffer'.
- (let ((stats (ert-run-tests-interactively "^ert-" " *ert self-tests*")))
+ (let ((stats (ert-run-tests-interactively "^ert-")))
(cl-assert ert--test-body-was-run)
(if (zerop (ert-stats-completed-unexpected stats))
;; Hide results window only when everything went well.
@@ -376,8 +377,11 @@ This macro is used to test if macroexpansion in `should' works."
(test (make-ert-test :body test-body))
(result (ert-run-test test)))
(should (ert-test-failed-p result))
- (should (eq (backtrace-frame-fun (car (ert-test-failed-backtrace result)))
- 'signal))))
+ (should (memq (backtrace-frame-fun (car (ert-test-failed-backtrace result)))
+ ;;; This is `ert-fail' on nativecomp and `signal'
+ ;;; otherwise. It's not clear whether that's a bug
+ ;;; or not (bug#51308).
+ '(ert-fail signal)))))
(ert-deftest ert-test-messages ()
:tags '(:causes-redisplay)
@@ -494,6 +498,12 @@ This macro is used to test if macroexpansion in `should' works."
(should (equal (ert-select-tests '(tag b) (list test)) (list test)))
(should (equal (ert-select-tests '(tag c) (list test)) '()))))
+(ert-deftest ert-test-select-undefined ()
+ (let* ((symbol (make-symbol "ert-not-a-test"))
+ (data (should-error (ert-select-tests symbol t)
+ :type 'ert-test-unbound)))
+ (should (eq (cadr data) symbol))))
+
;;; Tests for utility functions.
(ert-deftest ert-test-parse-keys-and-body ()
@@ -519,17 +529,18 @@ This macro is used to test if macroexpansion in `should' works."
:body (lambda () (ert-skip
"skip message")))))
(let ((ert-debug-on-error nil))
- (let* ((buffer-name (generate-new-buffer-name " *ert-test-run-tests*"))
- (messages nil)
- (mock-message-fn
- (lambda (format-string &rest args)
- (push (apply #'format format-string args) messages))))
+ (cl-letf* ((buffer-name (generate-new-buffer-name
+ " *ert-test-run-tests*"))
+ (ert--output-buffer-name buffer-name)
+ (messages nil)
+ ((symbol-function 'message)
+ (lambda (format-string &rest args)
+ (push (apply #'format format-string args) messages))))
(save-window-excursion
(unwind-protect
(let ((case-fold-search nil))
(ert-run-tests-interactively
- `(member ,passing-test ,failing-test, skipped-test) buffer-name
- mock-message-fn)
+ `(member ,passing-test ,failing-test, skipped-test))
(should (equal messages `(,(concat
"Ran 3 tests, 1 results were "
"as expected, 1 unexpected, "
@@ -551,6 +562,69 @@ This macro is used to test if macroexpansion in `should' works."
(when (get-buffer buffer-name)
(kill-buffer buffer-name))))))))
+(ert-deftest ert-test-run-tests-batch ()
+ (let* ((complex-list '((:1 (:2 (:3 (:4 (:5 (:6 "abc"))))))))
+ (long-list (make-list 11 1))
+ (failing-test-1
+ (make-ert-test :name 'failing-test-1
+ :body (lambda () (should (equal complex-list 1)))))
+ (failing-test-2
+ (make-ert-test :name 'failing-test-2
+ :body (lambda () (should (equal long-list 1))))))
+ (let ((ert-debug-on-error nil)
+ messages)
+ (cl-letf* (((symbol-function 'message)
+ (lambda (format-string &rest args)
+ (push (apply #'format format-string args) messages))))
+ (save-window-excursion
+ (unwind-protect
+ (let ((case-fold-search nil)
+ (ert-batch-backtrace-right-margin nil)
+ (ert-batch-print-level 10)
+ (ert-batch-print-length 11))
+ (ert-run-tests-batch
+ `(member ,failing-test-1 ,failing-test-2))))))
+ (let ((long-text "(different-types[ \t\n]+(1 1 1 1 1 1 1 1 1 1 1)[ \t\n]+1)))[ \t\n]*$")
+ (complex-text "(different-types[ \t\n]+((:1[ \t\n]+(:2[ \t\n]+(:3[ \t\n]+(:4[ \t\n]+(:5[ \t\n]+(:6[ \t\n]+\"abc\")))))))[ \t\n]+1)))[ \t\n]*$")
+ found-long
+ found-complex)
+ (cl-loop for msg in (reverse messages)
+ do
+ (unless found-long
+ (setq found-long (string-match long-text msg)))
+ (unless found-complex
+ (setq found-complex (string-match complex-text msg))))
+ (should found-long)
+ (should found-complex)))))
+
+(ert-deftest ert-test-run-tests-batch-expensive ()
+ :tags (if (getenv "EMACS_EMBA_CI") '(:unstable))
+ (let* ((complex-list '((:1 (:2 (:3 (:4 (:5 (:6 "abc"))))))))
+ (failing-test-1
+ (make-ert-test :name 'failing-test-1
+ :body (lambda () (should (equal complex-list 1))))))
+ (let ((ert-debug-on-error nil)
+ messages)
+ (cl-letf* (((symbol-function 'message)
+ (lambda (format-string &rest args)
+ (push (apply #'format format-string args) messages))))
+ (save-window-excursion
+ (unwind-protect
+ (let ((case-fold-search nil)
+ (ert-batch-backtrace-right-margin nil)
+ (ert-batch-backtrace-line-length nil)
+ (ert-batch-print-level 6)
+ (ert-batch-print-length 11))
+ (ert-run-tests-batch
+ `(member ,failing-test-1))))))
+ (let ((frame "ert-fail(((should (equal complex-list 1)) :form (equal ((:1 (:2 (:3 (:4 (:5 (:6 \"abc\"))))))) 1) :value nil :explanation (different-types ((:1 (:2 (:3 (:4 (:5 (:6 \"abc\"))))))) 1)))")
+ found-frame)
+ (cl-loop for msg in (reverse messages)
+ do
+ (unless found-frame
+ (setq found-frame (cl-search frame msg :test 'equal))))
+ (should found-frame)))))
+
(ert-deftest ert-test-special-operator-p ()
(should (ert--special-operator-p 'if))
(should-not (ert--special-operator-p 'car))
@@ -695,49 +769,40 @@ This macro is used to test if macroexpansion in `should' works."
(should (equal (ert--abbreviate-string "bar" 0 t) "")))
(ert-deftest ert-test-explain-equal-string-properties ()
- (should
- (equal (ert--explain-equal-including-properties #("foo" 0 1 (a b))
- "foo")
- '(char 0 "f"
- (different-properties-for-key a (different-atoms b nil))
- context-before ""
- context-after "oo")))
- (should (equal (ert--explain-equal-including-properties
+ (should-not (ert--explain-equal-including-properties-rec "foo" "foo"))
+ (should-not (ert--explain-equal-including-properties-rec
+ #("foo" 0 3 (a b))
+ (propertize "foo" 'a 'b)))
+ (should-not (ert--explain-equal-including-properties-rec
+ #("foo" 0 3 (a b c d))
+ (propertize "foo" 'a 'b 'c 'd)))
+ (should-not (ert--explain-equal-including-properties-rec
+ #("foo" 0 3 (a (t)))
+ (propertize "foo" 'a (list t))))
+
+ (should (equal (ert--explain-equal-including-properties-rec
+ #("foo" 0 3 (a b c e))
+ (propertize "foo" 'a 'b 'c 'd))
+ '(char 0 "f" (different-properties-for-key c (different-atoms e d))
+ context-before ""
+ context-after "oo")))
+ (should (equal (ert--explain-equal-including-properties-rec
+ #("foo" 0 1 (a b))
+ "foo")
+ '(char 0 "f"
+ (different-properties-for-key a (different-atoms b nil))
+ context-before ""
+ context-after "oo")))
+ (should (equal (ert--explain-equal-including-properties-rec
#("foo" 1 3 (a b))
#("goo" 0 1 (c d)))
'(array-elt 0 (different-atoms (?f "#x66" "?f")
(?g "#x67" "?g")))))
- (should
- (equal (ert--explain-equal-including-properties
- #("foo" 0 1 (a b c d) 1 3 (a b))
- #("foo" 0 1 (c d a b) 1 2 (a foo)))
- '(char 1 "o" (different-properties-for-key a (different-atoms b foo))
- context-before "f" context-after "o"))))
-
-(ert-deftest ert-test-equal-including-properties ()
- (should (equal-including-properties "foo" "foo"))
- (should (ert-equal-including-properties "foo" "foo"))
-
- (should (equal-including-properties #("foo" 0 3 (a b))
- (propertize "foo" 'a 'b)))
- (should (ert-equal-including-properties #("foo" 0 3 (a b))
- (propertize "foo" 'a 'b)))
-
- (should (equal-including-properties #("foo" 0 3 (a b c d))
- (propertize "foo" 'a 'b 'c 'd)))
- (should (ert-equal-including-properties #("foo" 0 3 (a b c d))
- (propertize "foo" 'a 'b 'c 'd)))
-
- (should-not (equal-including-properties #("foo" 0 3 (a b c e))
- (propertize "foo" 'a 'b 'c 'd)))
- (should-not (ert-equal-including-properties #("foo" 0 3 (a b c e))
- (propertize "foo" 'a 'b 'c 'd)))
-
- ;; This is bug 6581.
- (should-not (equal-including-properties #("foo" 0 3 (a (t)))
- (propertize "foo" 'a (list t))))
- (should (ert-equal-including-properties #("foo" 0 3 (a (t)))
- (propertize "foo" 'a (list t)))))
+ (should (equal (ert--explain-equal-including-properties-rec
+ #("foo" 0 1 (a b c d) 1 3 (a b))
+ #("foo" 0 1 (c d a b) 1 2 (a foo)))
+ '(char 1 "o" (different-properties-for-key a (different-atoms b foo))
+ context-before "f" context-after "o"))))
(ert-deftest ert-test-stats-set-test-and-result ()
(let* ((test-1 (make-ert-test :name 'test-1
@@ -804,7 +869,7 @@ This macro is used to test if macroexpansion in `should' works."
(ert-deftest ert-test-with-demoted-errors ()
"Check that ERT correctly handles `with-demoted-errors'."
:expected-result :failed ;; FIXME! Bug#11218
- (should-not (with-demoted-errors (error "Foo"))))
+ (should-not (with-demoted-errors "FOO: %S" (error "Foo"))))
(ert-deftest ert-test-fail-inside-should ()
"Check that `ert-fail' inside `should' works correctly."
@@ -820,6 +885,9 @@ This macro is used to test if macroexpansion in `should' works."
"Check that `lexical-binding' in `ert-deftest' has the file value."
(should (equal lexical-binding t)))
+(ert-deftest ert-test-get-explainer ()
+ (should (eq (ert--get-explainer 'string-equal) 'ert--explain-string-equal))
+ (should (eq (ert--get-explainer 'string=) 'ert--explain-string-equal)))
(provide 'ert-tests)
diff --git a/test/lisp/emacs-lisp/ert-x-tests.el b/test/lisp/emacs-lisp/ert-x-tests.el
index afa2105c48d..38698041102 100644
--- a/test/lisp/emacs-lisp/ert-x-tests.el
+++ b/test/lisp/emacs-lisp/ert-x-tests.el
@@ -90,10 +90,10 @@
"foo baz")))
(ert-deftest ert-propertized-string ()
- (should (ert-equal-including-properties
+ (should (equal-including-properties
(ert-propertized-string "a" '(a b) "b" '(c t) "cd")
#("abcd" 1 2 (a b) 2 4 (c t))))
- (should (ert-equal-including-properties
+ (should (equal-including-properties
(ert-propertized-string "foo " '(face italic) "bar" " baz" nil
" quux")
#("foo bar baz quux" 4 11 (face italic)))))
@@ -103,23 +103,27 @@
(ert-deftest ert-test-run-tests-interactively-2 ()
:tags '(:causes-redisplay)
- (let* ((passing-test (make-ert-test :name 'passing-test
- :body (lambda () (ert-pass))))
- (failing-test (make-ert-test :name 'failing-test
- :body (lambda ()
- (ert-info ((propertize "foo\nbar"
- 'a 'b))
- (ert-fail
- "failure message")))))
- (skipped-test (make-ert-test :name 'skipped-test
- :body (lambda () (ert-skip
- "skip message"))))
- (ert-debug-on-error nil)
- (buffer-name (generate-new-buffer-name "*ert-test-run-tests*"))
- (messages nil)
- (mock-message-fn
- (lambda (format-string &rest args)
- (push (apply #'format format-string args) messages))))
+ (cl-letf* ((passing-test (make-ert-test
+ :name 'passing-test
+ :body (lambda () (ert-pass))))
+ (failing-test (make-ert-test
+ :name 'failing-test
+ :body (lambda ()
+ (ert-info ((propertize "foo\nbar"
+ 'a 'b))
+ (ert-fail
+ "failure message")))))
+ (skipped-test (make-ert-test
+ :name 'skipped-test
+ :body (lambda () (ert-skip
+ "skip message"))))
+ (ert-debug-on-error nil)
+ (messages nil)
+ (buffer-name (generate-new-buffer-name "*ert-test-run-tests*"))
+ ((symbol-function 'message)
+ (lambda (format-string &rest args)
+ (push (apply #'format format-string args) messages)))
+ (ert--output-buffer-name buffer-name))
(cl-flet ((expected-string (with-font-lock-p)
(ert-propertized-string
"Selector: (member <passing-test> <failing-test> "
@@ -152,21 +156,19 @@
"failing-test"
nil "\n Info: " '(a b) "foo\n"
nil " " '(a b) "bar"
- nil "\n (ert-test-failed \"failure message\")\n\n\n"
- )))
+ nil "\n (ert-test-failed \"failure message\")\n\n\n")))
(save-window-excursion
(unwind-protect
(let ((case-fold-search nil))
(ert-run-tests-interactively
- `(member ,passing-test ,failing-test ,skipped-test) buffer-name
- mock-message-fn)
+ `(member ,passing-test ,failing-test ,skipped-test))
(should (equal messages `(,(concat
"Ran 3 tests, 1 results were "
"as expected, 1 unexpected, "
"1 skipped"))))
(with-current-buffer buffer-name
(font-lock-mode 0)
- (should (ert-equal-including-properties
+ (should (equal-including-properties
(ert-filter-string (buffer-string)
'("Started at:\\(.*\\)$" 1)
'("Finished at:\\(.*\\)$" 1))
@@ -175,7 +177,7 @@
;; pretend we are.
(let ((noninteractive nil))
(font-lock-mode 1))
- (should (ert-equal-including-properties
+ (should (equal-including-properties
(ert-filter-string (buffer-string)
'("Started at:\\(.*\\)$" 1)
'("Finished at:\\(.*\\)$" 1))
@@ -271,6 +273,62 @@ desired effect."
(cl-loop for x in '(0 1 2 3 4 t) do
(should (equal (c x) (lisp x))))))
+(ert-deftest ert-x-tests--with-temp-file-generate-suffix ()
+ (should (equal (ert--with-temp-file-generate-suffix "foo.el") "-foo"))
+ (should (equal (ert--with-temp-file-generate-suffix "foo-test.el") "-foo"))
+ (should (equal (ert--with-temp-file-generate-suffix "foo-tests.el") "-foo"))
+ (should (equal (ert--with-temp-file-generate-suffix "foo-bar-baz.el")
+ "-foo-bar-baz"))
+ (should (equal (ert--with-temp-file-generate-suffix "/foo/bar/baz.el")
+ "-baz")))
+
+(ert-deftest ert-x-tests-with-temp-file ()
+ (let (saved)
+ (ert-with-temp-file fil
+ (setq saved fil)
+ (should (file-exists-p fil))
+ (should (file-regular-p fil)))
+ (should-not (file-exists-p saved))))
+
+(ert-deftest ert-x-tests-with-temp-file/handle-error ()
+ (let (saved)
+ (ignore-errors
+ (ert-with-temp-file fil
+ (setq saved fil)
+ (error "foo")))
+ (should-not (file-exists-p saved))))
+
+(ert-deftest ert-x-tests-with-temp-file/prefix-and-suffix-kwarg ()
+ (ert-with-temp-file fil
+ :prefix "foo"
+ :suffix "bar"
+ (should (string-match "foo.*bar" fil))))
+
+(ert-deftest ert-x-tests-with-temp-file/text-kwarg ()
+ (ert-with-temp-file fil
+ :text "foobar3"
+ (let ((buf (find-file-noselect fil)))
+ (unwind-protect
+ (with-current-buffer buf
+ (should (equal (buffer-string) "foobar3")))
+ (kill-buffer buf)))))
+
+(ert-deftest ert-x-tests-with-temp-file/unknown-kwarg-signals-error ()
+ (should-error
+ (ert-with-temp-file fil :foo "foo" nil)))
+
+(ert-deftest ert-x-tests-with-temp-directory ()
+ (let (saved)
+ (ert-with-temp-directory dir
+ (setq saved dir)
+ (should (file-exists-p dir))
+ (should (file-directory-p dir))
+ (should (equal dir (file-name-as-directory dir))))
+ (should-not (file-exists-p saved))))
+
+(ert-deftest ert-x-tests-with-temp-directory/text-signals-error ()
+ (should-error
+ (ert-with-temp-directory dir :text "foo" nil)))
(provide 'ert-x-tests)
diff --git a/test/lisp/emacs-lisp/find-func-tests.el b/test/lisp/emacs-lisp/find-func-tests.el
index d29d9ff6563..420c61acb55 100644
--- a/test/lisp/emacs-lisp/find-func-tests.el
+++ b/test/lisp/emacs-lisp/find-func-tests.el
@@ -95,6 +95,13 @@ expected function symbol and function library, respectively."
(advice-remove #'mark-sexp 'my-message))
(ert-deftest find-func-tests--find-library-verbose ()
+ (unwind-protect
+ (progn
+ (advice-add 'dired :before #'ignore)
+ ;; bug#41104
+ (should (equal (find-function-library #'dired) '(dired . "dired"))))
+ (advice-remove 'dired #'ignore))
+
(find-function-library #'join-line nil t)
(with-current-buffer "*Messages*"
(save-excursion
diff --git a/test/lisp/emacs-lisp/generator-tests.el b/test/lisp/emacs-lisp/generator-tests.el
index 298e7c8d415..b7a21d49b2f 100644
--- a/test/lisp/emacs-lisp/generator-tests.el
+++ b/test/lisp/emacs-lisp/generator-tests.el
@@ -74,7 +74,7 @@ identical output."
(cps-testcase cps-prog1-b (prog1 1))
(cps-testcase cps-prog1-c (prog2 1 2 3))
(cps-testcase cps-quote (progn 'hello))
-(cps-testcase cps-function (progn #'hello))
+(cps-testcase cps-function (progn #'message))
(cps-testcase cps-and-fail (and 1 nil 2))
(cps-testcase cps-and-succeed (and 1 2 3))
@@ -85,9 +85,9 @@ identical output."
(cps-testcase cps-or-empty (or))
(cps-testcase cps-let* (let* ((i 10)) i))
-(cps-testcase cps-let*-shadow-empty (let* ((i 10)) (let (i) i)))
+(cps-testcase cps-let*-shadow-empty (let* ((i 10)) i (let ((i nil)) i)))
(cps-testcase cps-let (let ((i 10)) i))
-(cps-testcase cps-let-shadow-empty (let ((i 10)) (let (i) i)))
+(cps-testcase cps-let-shadow-empty (let ((i 10)) i (let ((i nil)) i)))
(cps-testcase cps-let-novars (let nil 42))
(cps-testcase cps-let*-novars (let* nil 42))
@@ -95,7 +95,7 @@ identical output."
(let ((a 5) (b 6)) (let ((a b) (b a)) (list a b))))
(cps-testcase cps-let*-parallel
- (let* ((a 5) (b 6)) (let* ((a b) (b a)) (list a b))))
+ (let* ((a 5) (b 6)) a (let* ((a b) (b a)) (list a b))))
(cps-testcase cps-while-dynamic
(setq *cps-test-i* 0)
@@ -219,7 +219,7 @@ identical output."
(should (eql (iter-next it -1) 42))
(should (eql (iter-next it -1) -1))))
-(ert-deftest cps-loop ()
+(ert-deftest cps-loop-2 ()
(should
(equal (cl-loop for x iter-by (mygenerator 42)
collect x)
@@ -307,6 +307,7 @@ identical output."
(1+ it)))))))
-2)))
+(defun generator-tests-edebug ()) ; silence byte-compiler
(ert-deftest generator-tests-edebug ()
"Check that Bug#40434 is fixed."
(with-temp-buffer
diff --git a/test/lisp/emacs-lisp/gv-tests.el b/test/lisp/emacs-lisp/gv-tests.el
index 0b1f9d0cf01..0757e3c7aa5 100644
--- a/test/lisp/emacs-lisp/gv-tests.el
+++ b/test/lisp/emacs-lisp/gv-tests.el
@@ -21,22 +21,21 @@
(require 'edebug)
(require 'ert)
+(require 'ert-x)
(eval-when-compile (require 'cl-lib))
(cl-defmacro gv-tests--in-temp-dir ((elvar elcvar)
(&rest filebody)
&rest body)
(declare (indent 2))
- `(let ((default-directory (make-temp-file "gv-test" t)))
- (unwind-protect
- (let ((,elvar "gv-test-deffoo.el")
- (,elcvar "gv-test-deffoo.elc"))
- (with-temp-file ,elvar
- (insert ";; -*- lexical-binding: t; -*-\n")
- (dolist (form ',filebody)
- (pp form (current-buffer))))
- ,@body)
- (delete-directory default-directory t))))
+ `(ert-with-temp-directory default-directory
+ (let ((,elvar "gv-test-deffoo.el")
+ (,elcvar "gv-test-deffoo.elc"))
+ (with-temp-file ,elvar
+ (insert ";; -*- lexical-binding: t; -*-\n")
+ (dolist (form ',filebody)
+ (pp form (current-buffer))))
+ ,@body)))
(ert-deftest gv-define-expander-in-file ()
(gv-tests--in-temp-dir (el elc)
diff --git a/test/lisp/emacs-lisp/let-alist-tests.el b/test/lisp/emacs-lisp/let-alist-tests.el
index 042e57e92f9..c4e4feaad30 100644
--- a/test/lisp/emacs-lisp/let-alist-tests.el
+++ b/test/lisp/emacs-lisp/let-alist-tests.el
@@ -82,7 +82,7 @@
(ert-deftest let-alist-list-to-sexp ()
"Check that multiple dots are handled correctly."
- (should (= 1 (eval (let-alist--list-to-sexp '(a b c d) ''((d (c (b (a . 1)))))))))
+ (should (= 1 (eval (let-alist--list-to-sexp '(a b c d) ''((d (c (b (a . 1)))))) t)))
(should (equal (let-alist--access-sexp '.foo.bar.baz 'var)
'(cdr (assq 'baz (cdr (assq 'bar (cdr (assq 'foo var))))))))
(should (equal (let-alist--access-sexp '..foo.bar.baz 'var) '.foo.bar.baz)))
diff --git a/test/lisp/emacs-lisp/lisp-tests.el b/test/lisp/emacs-lisp/lisp-tests.el
index 7d14f5545be..901447ecd27 100644
--- a/test/lisp/emacs-lisp/lisp-tests.el
+++ b/test/lisp/emacs-lisp/lisp-tests.el
@@ -213,6 +213,7 @@
(should-error (forward-sexp)))) ;; FIXME: Shouldn't be an error.
;; Test some core Elisp rules.
+(defvar c-e-x)
(ert-deftest core-elisp-tests-1-defvar-in-let ()
"Test some core Elisp rules."
(with-temp-buffer
@@ -235,7 +236,7 @@
(should (or (not mark-active) (mark)))))
(ert-deftest core-elisp-tests-3-backquote ()
- (should (eq 3 (eval ``,,'(+ 1 2)))))
+ (should (eq 3 (eval ``,,'(+ 1 2) t))))
;; Test up-list and backward-up-list.
(defun lisp-run-up-list-test (fn data start instructions)
@@ -324,7 +325,7 @@ start."
(declare (indent 1) (debug (def-form body)))
(let* ((var-pos nil)
(text (with-temp-buffer
- (insert (eval contents))
+ (insert (eval contents t))
(goto-char (point-min))
(while (re-search-forward elisp-test-point-position-regex nil t)
(push (list (intern (match-string-no-properties 1))
diff --git a/test/lisp/emacs-lisp/macroexp-resources/m1.el b/test/lisp/emacs-lisp/macroexp-resources/m1.el
index acffe6b8b61..88c51e75261 100644
--- a/test/lisp/emacs-lisp/macroexp-resources/m1.el
+++ b/test/lisp/emacs-lisp/macroexp-resources/m1.el
@@ -5,23 +5,23 @@
;; Author: Stefan Monnier <monnier@iro.umontreal.ca>
;; Keywords:
-;; This program is free software; you can redistribute it and/or modify
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
-;; This program is distributed in the hope that it will be useful,
+;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
-;; along with this program. If not, see <https://www.gnu.org/licenses/>.
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
-;;
-
;;; Code:
(defconst macroexp--m1-tests-filename (macroexp-file-name))
diff --git a/test/lisp/emacs-lisp/macroexp-resources/m2.el b/test/lisp/emacs-lisp/macroexp-resources/m2.el
index 0bb8d02a135..cebe4cac125 100644
--- a/test/lisp/emacs-lisp/macroexp-resources/m2.el
+++ b/test/lisp/emacs-lisp/macroexp-resources/m2.el
@@ -5,23 +5,23 @@
;; Author: Stefan Monnier <monnier@iro.umontreal.ca>
;; Keywords:
-;; This program is free software; you can redistribute it and/or modify
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
-;; This program is distributed in the hope that it will be useful,
+;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
-;; along with this program. If not, see <https://www.gnu.org/licenses/>.
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
-;;
-
;;; Code:
(defconst macroexp--m2-tests-filename (macroexp-file-name))
diff --git a/test/lisp/emacs-lisp/macroexp-resources/vk.el b/test/lisp/emacs-lisp/macroexp-resources/vk.el
new file mode 100644
index 00000000000..d9ca33671ef
--- /dev/null
+++ b/test/lisp/emacs-lisp/macroexp-resources/vk.el
@@ -0,0 +1,130 @@
+;;; vk.el --- test code for macroexp-tests -*- lexical-binding: t -*-
+
+;; Copyright (C) 2021-2022 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'macroexp)
+
+(defmacro vk-variable-kind (var)
+ (if (macroexp--dynamic-variable-p var) ''dyn ''lex))
+
+(defvar vk-a 1)
+(defconst vk-b 2)
+(defvar vk-c)
+
+(defun vk-f1 (x)
+ (defvar vk-u1)
+ (let ((vk-a 10)
+ (vk-b 20)
+ (vk-c 30)
+ (vk-u1 40)
+ (y 50))
+ (ignore vk-a vk-b vk-c vk-u1 x y)
+ (list
+ (vk-variable-kind vk-a) ; dyn
+ (vk-variable-kind vk-b) ; dyn
+ (vk-variable-kind vk-c) ; dyn
+ (vk-variable-kind vk-u1) ; dyn
+ (vk-variable-kind x) ; lex
+ (vk-variable-kind y)))) ; lex
+
+(eval-and-compile
+ (defvar vk-u2)
+ (defun vk-f2 (x)
+ (defvar vk-v2)
+ (let ((vk-u2 11)
+ (vk-v2 12)
+ (y 13))
+ (ignore vk-u2 vk-v2 x y)
+ (list
+ (vk-variable-kind vk-u2) ; dyn
+ (vk-variable-kind vk-v2) ; dyn
+ (vk-variable-kind x) ; lex
+ (vk-variable-kind y))))) ; lex
+
+(eval-when-compile
+ (defvar vk-u3)
+ (defun vk-f3 (x)
+ (defvar vk-v3)
+ (let ((vk-a 23)
+ (vk-b 24)
+ (vk-u3 25)
+ (vk-v3 26)
+ (y 27))
+ (ignore vk-a vk-b vk-u3 vk-v3 x y)
+ (list
+ (vk-variable-kind vk-a) ; dyn
+ (vk-variable-kind vk-b) ; dyn
+ (vk-variable-kind vk-u3) ; dyn
+ (vk-variable-kind vk-v3) ; dyn
+ (vk-variable-kind x) ; lex
+ (vk-variable-kind y))))) ; lex
+
+(defconst vk-val3 (eval-when-compile (vk-f3 0)))
+
+(defconst vk-f4 '(lambda (x)
+ (defvar vk-v4)
+ (let ((vk-v4 31)
+ (y 32))
+ (ignore vk-v4 x y)
+ (list
+ (vk-variable-kind vk-a) ; dyn
+ (vk-variable-kind vk-b) ; dyn
+ (vk-variable-kind vk-v4) ; dyn
+ (vk-variable-kind x) ; dyn
+ (vk-variable-kind y))))) ; dyn
+
+(defconst vk-f5 '(closure (t) (x)
+ (defvar vk-v5)
+ (let ((vk-v5 41)
+ (y 42))
+ (ignore vk-v5 x y)
+ (list
+ (vk-variable-kind vk-a) ; dyn
+ (vk-variable-kind vk-b) ; dyn
+ (vk-variable-kind vk-v5) ; dyn
+ (vk-variable-kind x) ; lex
+ (vk-variable-kind y))))) ; lex
+
+(defun vk-f6 ()
+ (eval '(progn
+ (defvar vk-v6)
+ (let ((vk-v6 51)
+ (y 52))
+ (ignore vk-v6 y)
+ (list
+ (vk-variable-kind vk-a) ; dyn
+ (vk-variable-kind vk-b) ; dyn
+ (vk-variable-kind vk-v6) ; dyn
+ (vk-variable-kind vk-y)))))) ; dyn
+
+(defun vk-f7 ()
+ (eval '(progn
+ (defvar vk-v7)
+ (let ((vk-v7 51)
+ (y 52))
+ (ignore vk-v7 y)
+ (list
+ (vk-variable-kind vk-a) ; dyn
+ (vk-variable-kind vk-b) ; dyn
+ (vk-variable-kind vk-v7) ; dyn
+ (vk-variable-kind vk-y)))) ; lex
+ t))
+
+(provide 'vk)
diff --git a/test/lisp/emacs-lisp/macroexp-tests.el b/test/lisp/emacs-lisp/macroexp-tests.el
index ee400626a26..4e6bd8b8fcd 100644
--- a/test/lisp/emacs-lisp/macroexp-tests.el
+++ b/test/lisp/emacs-lisp/macroexp-tests.el
@@ -5,25 +5,28 @@
;; Author: Stefan Monnier <monnier@iro.umontreal.ca>
;; Keywords:
-;; This program is free software; you can redistribute it and/or modify
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
-;; This program is distributed in the hope that it will be useful,
+;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
-;; along with this program. If not, see <https://www.gnu.org/licenses/>.
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
-;;
-
;;; Code:
+(require 'macroexp)
+(require 'ert-x)
+
(ert-deftest macroexp--tests-fgrep ()
(should (equal (macroexp--fgrep '((x) (y)) '([x] z ((u))))
'((x))))
@@ -67,6 +70,58 @@
(should (equal "m1.el"
(file-name-nondirectory macroexp--m1-tests-comp-filename)))))
+(defun macroexp-tests--run-emacs (&rest args)
+ "Run Emacs in batch mode with ARGS, return output."
+ (let ((emacs (expand-file-name invocation-name invocation-directory)))
+ (with-temp-buffer
+ (let ((res (apply #'call-process emacs nil t nil
+ "-Q" "--batch" args))
+ (output (buffer-string)))
+ (unless (equal res 0)
+ (message "%s" output)
+ (error "Inferior Emacs exited with status %S" res))
+ output))))
+
+(defun macroexp-tests--eval-in-subprocess (file expr)
+ (let ((output (macroexp-tests--run-emacs
+ "-l" file (format "--eval=(print %S)" expr))))
+ (car (read-from-string output))))
+
+(defun macroexp-tests--byte-compile-in-subprocess (file)
+ "Byte-compile FILE using a subprocess to avoid contaminating the lisp state."
+ (let ((output (macroexp-tests--run-emacs "-f" "batch-byte-compile" file)))
+ (when output
+ (message "%s" output))))
+
+(ert-deftest macroexp--tests-dynamic-variable-p ()
+ "Test `macroexp--dynamic-variable-p'."
+ (let* ((vk-el (ert-resource-file "vk.el"))
+ (vk-elc (concat vk-el "c"))
+ (expr '(list (vk-f1 0)
+ (vk-f2 0)
+ vk-val3
+ (funcall vk-f4 0)
+ (funcall vk-f5 0)
+ (vk-f6)
+ (vk-f7))))
+ ;; We compile and run the test in separate processes for complete
+ ;; isolation between test cases.
+ (should (equal (macroexp-tests--eval-in-subprocess vk-el expr)
+ '((dyn dyn dyn dyn lex lex)
+ (dyn dyn lex lex)
+ (dyn dyn dyn dyn lex lex)
+ (dyn dyn dyn dyn dyn)
+ (dyn dyn dyn lex lex)
+ (dyn dyn dyn dyn)
+ (dyn dyn dyn lex))))
+ (macroexp-tests--byte-compile-in-subprocess vk-el)
+ (should (equal (macroexp-tests--eval-in-subprocess vk-elc expr)
+ '((dyn dyn dyn dyn lex lex)
+ (dyn dyn lex lex)
+ (dyn dyn dyn dyn lex lex)
+ (dyn dyn dyn dyn dyn)
+ (dyn dyn dyn lex lex)
+ (dyn dyn dyn dyn)
+ (dyn dyn dyn lex))))))
-(provide 'macroexp-tests)
;;; macroexp-tests.el ends here
diff --git a/test/lisp/emacs-lisp/map-tests.el b/test/lisp/emacs-lisp/map-tests.el
index 4fca8b36199..314a1c9e302 100644
--- a/test/lisp/emacs-lisp/map-tests.el
+++ b/test/lisp/emacs-lisp/map-tests.el
@@ -422,9 +422,6 @@ Evaluate BODY for each created map."
(should (map-every-p (lambda (k _v) (zerop k)) map))))
(ert-deftest test-map-into ()
- ;; This test is unstable in Emacs 28, but the problem has been fixed
- ;; in Emacs 29 (bug#46722).
- :tags '(:unstable)
(let* ((plist '(a 1 b 2))
(alist '((a . 1) (b . 2)))
(ht (map-into alist 'hash-table))
@@ -443,9 +440,6 @@ Evaluate BODY for each created map."
(ert-deftest test-map-into-hash-test ()
"Test `map-into' with different hash-table test functions."
- ;; This test is unstable in Emacs 28, but the problem has been fixed
- ;; in Emacs 29 (bug#46722).
- :tags '(:unstable)
(should (eq (hash-table-test (map-into () 'hash-table)) #'equal))
(should (eq (hash-table-test (map-into () '(hash-table))) #'eql))
(should (eq (hash-table-test (map-into () '(hash-table :test eq))) #'eq))
@@ -476,9 +470,6 @@ Evaluate BODY for each created map."
(ert-deftest test-map-merge ()
"Test `map-merge'."
- ;; This test is unstable in Emacs 28, but the problem has been fixed
- ;; in Emacs 29 (bug#46722).
- :tags '(:unstable)
(should (equal (sort (map-merge 'list '(a 1) '((b . 2) (c . 3))
#s(hash-table data (c 4)))
(lambda (x y) (string< (car x) (car y))))
@@ -488,9 +479,6 @@ Evaluate BODY for each created map."
(should (equal (map-merge 'plist () '(:a 1)) '(:a 1))))
(ert-deftest test-map-merge-with ()
- ;; This test is unstable in Emacs 28, but the problem has been fixed
- ;; in Emacs 29 (bug#46722).
- :tags '(:unstable)
(should (equal (sort (map-merge-with 'list #'+
'((1 . 2))
'((1 . 3) (2 . 4))
@@ -503,9 +491,6 @@ Evaluate BODY for each created map."
(ert-deftest test-map-merge-empty ()
"Test merging of empty maps."
- ;; This test is unstable in Emacs 28, but the problem has been fixed
- ;; in Emacs 29 (bug#46722).
- :tags '(:unstable)
(should-not (map-merge 'list))
(should-not (map-merge 'alist))
(should-not (map-merge 'plist))
diff --git a/test/lisp/emacs-lisp/multisession-tests.el b/test/lisp/emacs-lisp/multisession-tests.el
new file mode 100644
index 00000000000..5807c27bd20
--- /dev/null
+++ b/test/lisp/emacs-lisp/multisession-tests.el
@@ -0,0 +1,207 @@
+;;; multisession-tests.el --- Tests for multisession.el -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021-2022 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'multisession)
+(require 'ert)
+(require 'ert-x)
+(require 'cl-lib)
+
+(declare-function sqlite-close "sqlite.c")
+
+(ert-deftest multi-test-sqlite-simple ()
+ (skip-unless (sqlite-available-p))
+ (ert-with-temp-file dir
+ :directory t
+ (let ((user-init-file "/tmp/foo.el")
+ (multisession-storage 'sqlite)
+ (multisession-directory dir))
+ (unwind-protect
+ (progn
+ (define-multisession-variable multisession--foo 0
+ ""
+ :synchronized t)
+ (should (= (multisession-value multisession--foo) 0))
+ (cl-incf (multisession-value multisession--foo))
+ (should (= (multisession-value multisession--foo) 1))
+ (call-process
+ (concat invocation-directory invocation-name)
+ nil t nil
+ "-Q" "-batch"
+ "--eval" (prin1-to-string
+ `(progn
+ (require 'multisession)
+ (let ((multisession-directory ,dir)
+ (multisession-storage 'sqlite)
+ (user-init-file "/tmp/foo.el"))
+ (define-multisession-variable multisession--foo 0
+ ""
+ :synchronized t)
+ (cl-incf (multisession-value multisession--foo))))))
+ (should (= (multisession-value multisession--foo) 2)))
+ (sqlite-close multisession--db)
+ (setq multisession--db nil)))))
+
+(ert-deftest multi-test-sqlite-busy ()
+ (skip-unless (sqlite-available-p))
+ (ert-with-temp-file dir
+ :directory t
+ (let ((user-init-file "/tmp/foo.el")
+ (multisession-directory dir)
+ (multisession-storage 'sqlite)
+ proc)
+ (unwind-protect
+ (progn
+ (define-multisession-variable multisession--bar 0
+ ""
+ :synchronized t)
+ (should (= (multisession-value multisession--bar) 0))
+ (cl-incf (multisession-value multisession--bar))
+ (should (= (multisession-value multisession--bar) 1))
+ (setq proc
+ (start-process
+ "other-emacs"
+ nil
+ (concat invocation-directory invocation-name)
+ "-Q" "-batch"
+ "--eval" (prin1-to-string
+ `(progn
+ (require 'multisession)
+ (let ((multisession-directory ,dir)
+ (multisession-storage 'sqlite)
+ (user-init-file "/tmp/bar.el"))
+ (define-multisession-variable multisession--bar 0
+ "" :synchronized t)
+ (dotimes (i 100)
+ (cl-incf (multisession-value multisession--bar))))))))
+ (while (process-live-p proc)
+ (ignore-error 'sqlite-locked-error
+ (message "multisession--bar %s" (multisession-value multisession--bar))
+ ;;(cl-incf (multisession-value multisession--bar))
+ )
+ (sleep-for 0.1))
+ (message "multisession--bar ends up as %s" (multisession-value multisession--bar))
+ (should (< (multisession-value multisession--bar) 1003)))
+ (sqlite-close multisession--db)
+ (setq multisession--db nil)))))
+
+(ert-deftest multi-test-files-simple ()
+ (ert-with-temp-file dir
+ :directory t
+ (let ((user-init-file "/tmp/sfoo.el")
+ (multisession-storage 'files)
+ (multisession-directory dir))
+ (define-multisession-variable multisession--sfoo 0
+ ""
+ :synchronized t)
+ (should (= (multisession-value multisession--sfoo) 0))
+ (cl-incf (multisession-value multisession--sfoo))
+ (should (= (multisession-value multisession--sfoo) 1))
+ ;; On Windows and Haiku, we don't have sub-second resolution, so
+ ;; let some time pass to make the "later" logic work.
+ (when (memq system-type '(windows-nt haiku))
+ (sleep-for 0.6))
+ (call-process
+ (concat invocation-directory invocation-name)
+ nil t nil
+ "-Q" "-batch"
+ "--eval" (prin1-to-string
+ `(progn
+ (require 'multisession)
+ (let ((multisession-directory ,dir)
+ (multisession-storage 'files)
+ (user-init-file "/tmp/sfoo.el"))
+ (define-multisession-variable multisession--sfoo 0
+ ""
+ :synchronized t)
+ (cl-incf (multisession-value multisession--sfoo))))))
+ (should (= (multisession-value multisession--sfoo) 2)))))
+
+(ert-deftest multi-test-files-busy ()
+ (skip-unless (sqlite-available-p))
+ (ert-with-temp-file dir
+ :directory t
+ (let ((user-init-file "/tmp/foo.el")
+ (multisession-storage 'files)
+ (multisession-directory dir)
+ proc)
+ (define-multisession-variable multisession--sbar 0
+ ""
+ :synchronized t)
+ (should (= (multisession-value multisession--sbar) 0))
+ (cl-incf (multisession-value multisession--sbar))
+ (should (= (multisession-value multisession--sbar) 1))
+ (setq proc
+ (start-process
+ "other-emacs"
+ nil
+ (concat invocation-directory invocation-name)
+ "-Q" "-batch"
+ "--eval" (prin1-to-string
+ `(progn
+ (require 'multisession)
+ (let ((multisession-directory ,dir)
+ (multisession-storage 'files)
+ (user-init-file "/tmp/sbar.el"))
+ (define-multisession-variable multisession--sbar 0
+ "" :synchronized t)
+ (dotimes (i 100)
+ (cl-incf (multisession-value multisession--sbar))))))))
+ (while (process-live-p proc)
+ (message "multisession--sbar %s" (multisession-value multisession--sbar))
+ ;;(cl-incf (multisession-value multisession--sbar))
+ (sleep-for 0.1))
+ (message "multisession--sbar ends up as %s" (multisession-value multisession--sbar))
+ (should (< (multisession-value multisession--sbar) 200)))))
+
+(ert-deftest multi-test-files-some-values ()
+ (ert-with-temp-file dir
+ :directory t
+ (let ((user-init-file "/tmp/sfoo.el")
+ (multisession-storage 'files)
+ (multisession-directory dir))
+ (define-multisession-variable multisession--foo1 nil)
+ (should (eq (multisession-value multisession--foo1) nil))
+ (setf (multisession-value multisession--foo1) nil)
+ (should (eq (multisession-value multisession--foo1) nil))
+ (setf (multisession-value multisession--foo1) t)
+ (should (eq (multisession-value multisession--foo1) t))
+
+ (define-multisession-variable multisession--foo2 t)
+ (setf (multisession-value multisession--foo2) nil)
+ (should (eq (multisession-value multisession--foo2) nil))
+ (setf (multisession-value multisession--foo2) t)
+ (should (eq (multisession-value multisession--foo2) t))
+
+ (define-multisession-variable multisession--foo3 t)
+ (should-error (setf (multisession-value multisession--foo3) (make-marker)))
+
+ (let ((string (with-temp-buffer
+ (set-buffer-multibyte nil)
+ (insert 0 1 2)
+ (buffer-string))))
+ (should-not (multibyte-string-p string))
+ (define-multisession-variable multisession--foo4 nil)
+ (setf (multisession-value multisession--foo4) string)
+ (should (equal (multisession-value multisession--foo4) string))))))
+
+;;; multisession-tests.el ends here
diff --git a/test/lisp/emacs-lisp/nadvice-tests.el b/test/lisp/emacs-lisp/nadvice-tests.el
index f21624cfd87..a675986b90b 100644
--- a/test/lisp/emacs-lisp/nadvice-tests.el
+++ b/test/lisp/emacs-lisp/nadvice-tests.el
@@ -153,13 +153,13 @@ function being an around advice."
(ert-deftest advice-test-call-interactively ()
"Check interaction between advice on call-interactively and called-interactively-p."
- (defun sm-test7.4 () (interactive) (cons 1 (called-interactively-p)))
- (let ((old (symbol-function 'call-interactively)))
+ (let ((sm-test7.4 (lambda () (interactive) (cons 1 (called-interactively-p))))
+ (old (symbol-function 'call-interactively)))
(unwind-protect
(progn
(advice-add 'call-interactively :before #'ignore)
- (should (equal (sm-test7.4) '(1 . nil)))
- (should (equal (call-interactively 'sm-test7.4) '(1 . t))))
+ (should (equal (funcall sm-test7.4) '(1 . nil)))
+ (should (equal (call-interactively sm-test7.4) '(1 . t))))
(advice-remove 'call-interactively #'ignore)
(should (eq (symbol-function 'call-interactively) old)))))
@@ -204,6 +204,15 @@ function being an around advice."
(remove-function (var sm-test10) sm-advice)
(should (equal (funcall sm-test10 5) 15))))
+(ert-deftest advice-test-print ()
+ (let ((x (list 'cdr)))
+ (add-function :after (car x) 'car)
+ (should (equal (cl-prin1-to-string (car x))
+ "#f(advice car :after cdr)"))
+ (add-function :before (car x) 'first)
+ (should (equal (cl-prin1-to-string (car x))
+ "#f(advice first :before #f(advice car :after cdr))"))))
+
;; Local Variables:
;; no-byte-compile: t
;; End:
diff --git a/test/lisp/emacs-lisp/oclosure-tests.el b/test/lisp/emacs-lisp/oclosure-tests.el
new file mode 100644
index 00000000000..00b008845c0
--- /dev/null
+++ b/test/lisp/emacs-lisp/oclosure-tests.el
@@ -0,0 +1,166 @@
+;;; oclosure-tests.e; --- Tests for Open Closures -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021-2022 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'ert)
+(require 'oclosure)
+(require 'cl-lib)
+(require 'eieio)
+
+(oclosure-define (oclosure-test
+ (:copier oclosure-test-copy)
+ (:copier oclosure-test-copy1 (fst)))
+ "Simple OClosure."
+ fst snd (name :mutable t))
+
+(cl-defmethod oclosure-test-gen ((_x compiled-function)) "#<bytecode>")
+
+(cl-defmethod oclosure-test-gen ((_x cons)) "#<cons>")
+
+(cl-defmethod oclosure-test-gen ((_x oclosure))
+ (format "#<oclosure:%s>" (cl-call-next-method)))
+
+(cl-defmethod oclosure-test-gen ((_x oclosure-test))
+ (format "#<oclosure-test:%s>" (cl-call-next-method)))
+
+(ert-deftest oclosure-test ()
+ (let* ((i 42)
+ (ocl1 (oclosure-lambda (oclosure-test (fst 1) (snd 2) (name "hi"))
+ ()
+ (list fst snd i)))
+ (ocl2 (oclosure-lambda (oclosure-test (name (cl-incf i)) (fst (cl-incf i)))
+ ()
+ (list fst snd 152 i))))
+ (should (equal (list (oclosure-test--fst ocl1)
+ (oclosure-test--snd ocl1)
+ (oclosure-test--name ocl1))
+ '(1 2 "hi")))
+ (should (equal (list (oclosure-test--fst ocl2)
+ (oclosure-test--snd ocl2)
+ (oclosure-test--name ocl2))
+ '(44 nil 43)))
+ (should (equal (funcall ocl1) '(1 2 44)))
+ (should (equal (funcall ocl2) '(44 nil 152 44)))
+ (should (equal (funcall (oclosure-test-copy ocl1 :fst 7)) '(7 2 44)))
+ (should (equal (funcall (oclosure-test-copy1 ocl1 9)) '(9 2 44)))
+ (should (cl-typep ocl1 'oclosure-test))
+ (should (cl-typep ocl1 'oclosure))
+ (should (member (oclosure-test-gen ocl1)
+ '("#<oclosure-test:#<oclosure:#<cons>>>"
+ "#<oclosure-test:#<oclosure:#<bytecode>>>")))
+ (should (stringp (documentation #'oclosure-test--fst)))
+ ))
+
+(ert-deftest oclosure-test-limits ()
+ (defvar byte-compile-debug)
+ (should
+ (condition-case err
+ (let ((lexical-binding t)
+ (byte-compile-debug t))
+ (byte-compile '(lambda ()
+ (let ((inc-fst nil))
+ (oclosure-lambda (oclosure-test (fst 'foo)) ()
+ (setq inc-fst (lambda () (setq fst (1+ fst))))
+ fst))))
+ nil)
+ (error
+ (and (eq 'error (car err))
+ (string-match "fst.*mutated" (cadr err))))))
+ (should
+ (condition-case err
+ (progn (macroexpand-all '(oclosure-define oclosure--foo a a))
+ nil)
+ (error
+ (and (eq 'error (car err))
+ (string-match "Duplicate slot name: a$" (cadr err))))))
+ (should
+ (condition-case err
+ (progn (macroexpand-all
+ '(oclosure-define (oclosure--foo (:parent oclosure-test)) fst))
+ nil)
+ (error
+ (and (eq 'error (car err))
+ (string-match "Duplicate slot name: fst$" (cadr err))))))
+ (should
+ (condition-case err
+ (progn (macroexpand '(oclosure-lambda (oclosure-test (fst 1) (fst 2))
+ () fst))
+ nil)
+ (error
+ (and (eq 'error (car err))
+ (string-match "Duplicate slot: fst$" (cadr err)))))))
+
+(cl-defmethod oclosure-interactive-form ((ot oclosure-test))
+ (let ((snd (oclosure-test--snd ot)))
+ (if (stringp snd) (list 'interactive snd))))
+
+(ert-deftest oclosure-test-interactive-form ()
+ (should (equal (interactive-form
+ (oclosure-lambda (oclosure-test (fst 1) (snd 2)) () fst))
+ nil))
+ (should (equal (interactive-form
+ (oclosure-lambda (oclosure-test (fst 1) (snd 2)) ()
+ (interactive "r")
+ fst))
+ '(interactive "r")))
+ (should (equal (interactive-form
+ (oclosure-lambda (oclosure-test (fst 1) (snd "P")) () fst))
+ '(interactive "P")))
+ (should (not (commandp
+ (oclosure-lambda (oclosure-test (fst 1) (snd 2)) () fst))))
+ (should (commandp
+ (oclosure-lambda (oclosure-test (fst 1) (snd "P")) () fst))))
+
+(oclosure-define (oclosure-test-mut
+ (:parent oclosure-test)
+ (:copier oclosure-test-mut-copy))
+ "Simple OClosure with a mutable field."
+ (mut :mutable t))
+
+(ert-deftest oclosure-test-mutate ()
+ (let* ((f (oclosure-lambda (oclosure-test-mut (fst 0) (mut 3))
+ (x)
+ (+ x fst mut)))
+ (f2 (oclosure-test-mut-copy f :fst 50)))
+ (should (equal (oclosure-test-mut--mut f) 3))
+ (should (equal (funcall f 5) 8))
+ (should (equal (funcall f2 5) 58))
+ (cl-incf (oclosure-test-mut--mut f) 7)
+ (should (equal (oclosure-test-mut--mut f) 10))
+ (should (equal (funcall f 5) 15))
+ (should (equal (funcall f2 15) 68))))
+
+(ert-deftest oclosure-test-slot-value ()
+ (require 'eieio)
+ (let ((ocl (oclosure-lambda
+ (oclosure-test (fst 'fst1) (snd 'snd1) (name 'name1))
+ (x)
+ (list name fst snd x))))
+ (should (equal 'fst1 (slot-value ocl 'fst)))
+ (should (equal 'snd1 (slot-value ocl 'snd)))
+ (should (equal 'name1 (slot-value ocl 'name)))
+ (setf (slot-value ocl 'name) 'new-name)
+ (should (equal 'new-name (slot-value ocl 'name)))
+ (should (equal '(new-name fst1 snd1 arg) (funcall ocl 'arg)))
+ (should-error (setf (slot-value ocl 'fst) 'new-fst) :type 'setting-constant)
+ (should (equal 'fst1 (slot-value ocl 'fst)))
+ ))
+
+;;; oclosure-tests.el ends here.
diff --git a/test/lisp/emacs-lisp/package-resources/macro-builtin-package-1.0/macro-builtin-aux.el b/test/lisp/emacs-lisp/package-resources/macro-builtin-package-1.0/macro-builtin-aux.el
new file mode 100644
index 00000000000..724f88ec9ea
--- /dev/null
+++ b/test/lisp/emacs-lisp/package-resources/macro-builtin-package-1.0/macro-builtin-aux.el
@@ -0,0 +1,12 @@
+;;; macro-builtin-aux.el --- laksd -*- lexical-binding: t; -*-
+
+;; Author: Artur Malabarba <emacs@endlessparentheses.com>
+
+;;; Code:
+
+(defun macro-builtin-aux-1 ( &rest forms)
+ "Description"
+ `(progn ,@forms))
+
+(provide 'macro-builtin-aux)
+;;; macro-builtin-aux.el ends here
diff --git a/test/lisp/emacs-lisp/package-resources/macro-builtin-package-1.0/macro-builtin.el b/test/lisp/emacs-lisp/package-resources/macro-builtin-package-1.0/macro-builtin.el
new file mode 100644
index 00000000000..828968a0576
--- /dev/null
+++ b/test/lisp/emacs-lisp/package-resources/macro-builtin-package-1.0/macro-builtin.el
@@ -0,0 +1,21 @@
+;;; macro-builtin.el --- laksd -*- lexical-binding: t; -*-
+
+;; Author: Artur Malabarba <emacs@endlessparentheses.com>
+;; Keywords: tools
+;; Version: 1.0
+
+;;; Code:
+
+(require 'macro-builtin-aux)
+
+(defmacro macro-builtin-1 ( &rest forms)
+ "Description"
+ `(progn ,@forms))
+
+(defun macro-builtin-func ()
+ ""
+ (macro-builtin-1 'a 'b)
+ (macro-builtin-aux-1 'a 'b))
+
+(provide 'macro-builtin)
+;;; macro-builtin.el ends here
diff --git a/test/lisp/emacs-lisp/package-resources/macro-builtin-package-2.0/macro-builtin-aux.el b/test/lisp/emacs-lisp/package-resources/macro-builtin-package-2.0/macro-builtin-aux.el
new file mode 100644
index 00000000000..9f257d9d22c
--- /dev/null
+++ b/test/lisp/emacs-lisp/package-resources/macro-builtin-package-2.0/macro-builtin-aux.el
@@ -0,0 +1,16 @@
+;;; macro-builtin-aux.el --- laksd -*- lexical-binding: t; -*-
+
+;; Author: Artur Malabarba <emacs@endlessparentheses.com>
+
+;;; Code:
+
+(defmacro macro-builtin-aux-1 ( &rest forms)
+ "Description"
+ `(progn ,@forms))
+
+(defmacro macro-builtin-aux-3 ( &rest _)
+ "Description"
+ 90)
+
+(provide 'macro-builtin-aux)
+;;; macro-builtin-aux.el ends here
diff --git a/test/lisp/emacs-lisp/package-resources/macro-builtin-package-2.0/macro-builtin.el b/test/lisp/emacs-lisp/package-resources/macro-builtin-package-2.0/macro-builtin.el
new file mode 100644
index 00000000000..5d241c082d0
--- /dev/null
+++ b/test/lisp/emacs-lisp/package-resources/macro-builtin-package-2.0/macro-builtin.el
@@ -0,0 +1,30 @@
+;;; macro-builtin.el --- laksd -*- lexical-binding: t; -*-
+
+;; Author: Artur Malabarba <emacs@endlessparentheses.com>
+;; Keywords: tools
+;; Version: 2.0
+
+;;; Code:
+
+(require 'macro-builtin-aux)
+
+(defmacro macro-builtin-1 ( &rest forms)
+ "Description"
+ `(progn ,(cadr (car forms))))
+
+
+(defun macro-builtin-func ()
+ ""
+ (list (macro-builtin-1 '1 'b)
+ (macro-builtin-aux-1 'a 'b)))
+
+(defmacro macro-builtin-3 (&rest _)
+ "Description"
+ 10)
+
+(defun macro-builtin-10-and-90 ()
+ ""
+ (list (macro-builtin-3 haha) (macro-builtin-aux-3 hehe)))
+
+(provide 'macro-builtin)
+;;; macro-builtin.el ends here
diff --git a/test/lisp/emacs-lisp/package-tests.el b/test/lisp/emacs-lisp/package-tests.el
index 69c14050b96..d7a55998c20 100644
--- a/test/lisp/emacs-lisp/package-tests.el
+++ b/test/lisp/emacs-lisp/package-tests.el
@@ -115,57 +115,55 @@
&rest body)
"Set up temporary locations and variables for testing."
(declare (indent 1) (debug (([&rest form]) body)))
- `(let* ((package-test-user-dir (make-temp-file "pkg-test-user-dir-" t))
- (process-environment (cons (format "HOME=%s" package-test-user-dir)
- process-environment))
- (package-user-dir package-test-user-dir)
- (package-gnupghome-dir (expand-file-name "gnupg" package-user-dir))
- (package-archives `(("gnu" . ,(or ,location package-test-data-dir))))
- (default-directory package-test-file-dir)
- abbreviated-home-dir
- package--initialized
- package-alist
- ,@(if update-news
- '(package-update-news-on-upload t)
- (list (cl-gensym)))
- ,@(if upload-base
- '((package-test-archive-upload-base (make-temp-file "pkg-archive-base-" t))
- (package-archive-upload-base package-test-archive-upload-base))
- (list (cl-gensym)))) ;; Dummy value so `let' doesn't try to bind nil
- (let ((buf (get-buffer "*Packages*")))
- (when (buffer-live-p buf)
- (kill-buffer buf)))
- (unwind-protect
- (progn
- ,(if basedir `(cd ,basedir))
- (unless (file-directory-p package-user-dir)
- (mkdir package-user-dir))
- (cl-letf (((symbol-function 'yes-or-no-p) (lambda (&rest _) t))
- ((symbol-function 'y-or-n-p) (lambda (&rest _) t)))
- ,@(when install
- `((package-initialize)
- (package-refresh-contents)
- (mapc 'package-install ,install)))
- (with-temp-buffer
- ,(if file
- `(insert-file-contents ,file))
- ,@body)))
-
- (when ,upload-base
- (dolist (f '("archive-contents"
- "simple-single-1.3.el"
- "simple-single-1.4.el"
- "simple-single-readme.txt"))
- (ignore-errors
- (delete-file
- (expand-file-name f package-test-archive-upload-base))))
- (delete-directory package-test-archive-upload-base))
- (when (file-directory-p package-test-user-dir)
- (delete-directory package-test-user-dir t))
-
- (when (and (boundp 'package-test-archive-upload-base)
- (file-directory-p package-test-archive-upload-base))
- (delete-directory package-test-archive-upload-base t)))))
+ `(ert-with-temp-directory package-test-user-dir
+ (let* ((process-environment (cons (format "HOME=%s" package-test-user-dir)
+ process-environment))
+ (package-user-dir package-test-user-dir)
+ (package-gnupghome-dir (expand-file-name "gnupg" package-user-dir))
+ (package-archives `(("gnu" . ,(or ,location package-test-data-dir))))
+ (default-directory package-test-file-dir)
+ abbreviated-home-dir
+ package--initialized
+ package-alist
+ ,@(if update-news
+ '(package-update-news-on-upload t)
+ (list (cl-gensym)))
+ ,@(if upload-base
+ '((package-test-archive-upload-base (make-temp-file "pkg-archive-base-" t))
+ (package-archive-upload-base package-test-archive-upload-base))
+ (list (cl-gensym)))) ;; Dummy value so `let' doesn't try to bind nil
+ (let ((buf (get-buffer "*Packages*")))
+ (when (buffer-live-p buf)
+ (kill-buffer buf)))
+ (unwind-protect
+ (progn
+ ,(if basedir `(cd ,basedir))
+ (unless (file-directory-p package-user-dir)
+ (mkdir package-user-dir))
+ (cl-letf (((symbol-function 'yes-or-no-p) (lambda (&rest _) t))
+ ((symbol-function 'y-or-n-p) (lambda (&rest _) t)))
+ ,@(when install
+ `((package-initialize)
+ (package-refresh-contents)
+ (mapc 'package-install ,install)))
+ (with-temp-buffer
+ ,(if file
+ `(insert-file-contents ,file))
+ ,@body)))
+
+ (when ,upload-base
+ (dolist (f '("archive-contents"
+ "simple-single-1.3.el"
+ "simple-single-1.4.el"
+ "simple-single-readme.txt"))
+ (ignore-errors
+ (delete-file
+ (expand-file-name f package-test-archive-upload-base))))
+ (delete-directory package-test-archive-upload-base))
+
+ (when (and (boundp 'package-test-archive-upload-base)
+ (file-directory-p package-test-archive-upload-base))
+ (delete-directory package-test-archive-upload-base t))))))
(defmacro with-fake-help-buffer (&rest body)
"Execute BODY in a temp buffer which is treated as the \"*Help*\" buffer."
@@ -342,9 +340,13 @@ but with a different end of line convention (bug#48137)."
(declare-function macro-problem-func "macro-problem" ())
(declare-function macro-problem-10-and-90 "macro-problem" ())
+(declare-function macro-builtin-func "macro-builtin" ())
+(declare-function macro-builtin-10-and-90 "macro-builtin" ())
(ert-deftest package-test-macro-compilation ()
- "Install a package which includes a dependency."
+ "\"Activation has to be done before compilation, so that if we're
+ upgrading and macros have changed we load the new definitions
+ before compiling.\" -- package.el"
(with-package-test (:basedir (ert-resource-directory))
(package-install-file (expand-file-name "macro-problem-package-1.0/"))
(require 'macro-problem)
@@ -357,6 +359,32 @@ but with a different end of line convention (bug#48137)."
;; `macro-problem-10-and-90' depends on an entirely new macro from `macro-aux'.
(should (equal (macro-problem-10-and-90) '(10 90)))))
+(ert-deftest package-test-macro-compilation-gz ()
+ "Built-in's can be superseded as well."
+ (with-package-test (:basedir (ert-resource-directory))
+ (let ((dir (expand-file-name "macro-builtin-package-1.0")))
+ (unwind-protect
+ (let ((load-path load-path))
+ (add-to-list 'load-path (directory-file-name dir))
+ (byte-recompile-directory dir 0 t)
+ (mapc (lambda (f) (call-process "gzip" nil nil nil f))
+ (directory-files-recursively dir "\\`[^\\.].*\\.el\\'"))
+ (require 'macro-builtin)
+ (should (member (expand-file-name "macro-builtin-aux.elc" dir)
+ (mapcar #'car load-history)))
+ ;; `macro-builtin-func' uses a macro from `macro-aux'.
+ (should (equal (macro-builtin-func) '(progn a b)))
+ (package-install-file (expand-file-name "macro-builtin-package-2.0/"))
+ ;; After upgrading, `macro-builtin-func' depends on a new version
+ ;; of the macro from `macro-builtin-aux'.
+ (should (equal (macro-builtin-func) '(1 b)))
+ ;; `macro-builtin-10-and-90' depends on an entirely new macro from `macro-aux'.
+ (should (equal (macro-builtin-10-and-90) '(10 90))))
+ (mapc #'delete-file
+ (directory-files-recursively dir "\\`[^\\.].*\\.elc\\'"))
+ (mapc (lambda (f) (call-process "gunzip" nil nil nil f))
+ (directory-files-recursively dir "\\`[^\\.].*\\.el\\.gz\\'"))))))
+
(ert-deftest package-test-install-two-dependencies ()
"Install a package which includes a dependency."
(with-package-test ()
@@ -685,25 +713,23 @@ but with a different end of line convention (bug#48137)."
(defvar epg-config--program-alist) ; Silence byte-compiler.
(ert-deftest package-test-signed ()
"Test verifying package signature."
- (skip-unless (let ((homedir (make-temp-file "package-test" t)))
- (unwind-protect
- (let ((process-environment
- (cons (concat "HOME=" homedir)
- process-environment)))
- (require 'epg-config)
- (defvar epg-config--program-alist)
- (epg-find-configuration
- 'OpenPGP nil
- ;; By default we require gpg2 2.1+ due to some
- ;; practical problems with pinentry. But this
- ;; test works fine with 2.0 as well.
- (let ((prog-alist (copy-tree epg-config--program-alist)))
- (setf (alist-get "gpg2"
- (alist-get 'OpenPGP prog-alist)
- nil nil #'equal)
- "2.0")
- prog-alist)))
- (delete-directory homedir t))))
+ (skip-unless (ert-with-temp-directory homedir
+ (let ((process-environment
+ (cons (concat "HOME=" homedir)
+ process-environment)))
+ (require 'epg-config)
+ (defvar epg-config--program-alist)
+ (epg-find-configuration
+ 'OpenPGP nil
+ ;; By default we require gpg2 2.1+ due to some
+ ;; practical problems with pinentry. But this
+ ;; test works fine with 2.0 as well.
+ (let ((prog-alist (copy-tree epg-config--program-alist)))
+ (setf (alist-get "gpg2"
+ (alist-get 'OpenPGP prog-alist)
+ nil nil #'equal)
+ "2.0")
+ prog-alist)))))
(let* ((keyring (expand-file-name "key.pub" package-test-data-dir))
(package-test-data-dir (ert-resource-file "signed")))
(with-package-test ()
diff --git a/test/lisp/emacs-lisp/pcase-tests.el b/test/lisp/emacs-lisp/pcase-tests.el
index ea4119bf9a3..80607990808 100644
--- a/test/lisp/emacs-lisp/pcase-tests.el
+++ b/test/lisp/emacs-lisp/pcase-tests.el
@@ -107,8 +107,11 @@
(should (equal (pcase 1
((cl-type (integer 0 2)) 'integer-0<=n<=2))
'integer-0<=n<=2))
- (should-error (pcase 1
- ((cl-type notatype) 'integer))))
+ (should-error
+ ;; Avoid error at compile time due to compiler macro.
+ (eval '(pcase 1
+ ((cl-type notatype) 'integer))
+ t)))
(ert-deftest pcase-tests-setq ()
(should (equal (let (a b)
diff --git a/test/lisp/emacs-lisp/pp-resources/code-formats.erts b/test/lisp/emacs-lisp/pp-resources/code-formats.erts
new file mode 100644
index 00000000000..c3e3023cb19
--- /dev/null
+++ b/test/lisp/emacs-lisp/pp-resources/code-formats.erts
@@ -0,0 +1,142 @@
+Code:
+ (lambda ()
+ (emacs-lisp-mode)
+ (let ((code (read (current-buffer))))
+ (erase-buffer)
+ (pp-emacs-lisp-code code)
+ (untabify (point-min) (point-max))))
+
+Name: code-formats1
+
+=-=
+(defun foo (bar)
+ "Yes."
+ (let ((a 1)
+ (b 2))
+ (zot 1 2 (funcall bar 2))))
+=-=-=
+
+
+Name: code-formats2
+
+=-=
+(defun pp-emacs-lisp-code (sexp)
+ "Insert SEXP into the current buffer, formatted as Emacs Lisp code."
+ (require 'edebug)
+ (let ((start (point))
+ (standard-output (current-buffer)))
+ (pp--insert-lisp sexp)
+ (insert "\n")
+ (goto-char start)
+ (indent-sexp)))
+=-=-=
+
+
+Name: code-formats3
+
+=-=
+(defun foo (bar)
+ "Yes."
+ (let ((a 1)
+ (b 2))
+ (zot-zot-zot-zot-zot-zot 1 2 (funcall
+ bar-bar-bar-bar-bar-bar-bar-bar-bar-bar
+ 2))))
+=-=-=
+
+
+Name: code-formats4
+
+=-=
+(defun foo (bar)
+ "Yes."
+ (let ((a 1)
+ (b 2)
+ foo bar zotfoo bar zotfoo bar zotfoo bar zotfoo bar zotfoo bar zotfoo
+ bar zot)
+ (zot 1 2 (funcall bar 2))))
+=-=-=
+
+
+Name: code-formats5
+
+=-=
+(defgroup pp ()
+ "Pretty printer for Emacs Lisp."
+ :prefix "pp-"
+ :group 'lisp)
+=-=-=
+
+Name: code-formats6
+
+=-=
+(defcustom pp-escape-newlines t
+ "Value of `print-escape-newlines' used by pp-* functions."
+ :type 'boolean
+ :group 'pp)
+=-=-=
+
+Name: code-formats7
+
+=-=
+(defun pp (object &optional stream)
+ (princ (pp-to-string object) (or stream standard-output)))
+=-=-=
+
+
+Name: code-formats8
+
+=-=
+(defun pp-eval-expression (expression)
+ "Evaluate EXPRESSION and pretty-print its value.
+Also add the value to the front of the list in the variable `values'."
+ (interactive (list (read--expression "Eval: ")))
+ (message "Evaluating...")
+ (let ((result (eval expression lexical-binding)))
+ (values--store-value result)
+ (pp-display-expression result "*Pp Eval Output*")))
+=-=-=
+
+Name: code-formats9
+
+=-=
+(lambda ()
+ (interactive)
+ 1)
+=-=-=
+
+
+Name: code-formats10
+
+=-=
+(funcall foo (concat "zot" (if (length> site 0) site
+ "bar")
+ "+"
+ (string-replace " " "+" query)))
+=-=-=
+
+
+Name: code-formats11
+
+=-=
+(lambda ()
+ [(foo bar) (foo bar)])
+=-=-=
+
+Name: code-formats12
+
+=-=
+(global-set-key (kbd "s-x") #'kill-region)
+=-=-=
+
+Name: code-formats13
+
+=-=
+'("a")
+=-=-=
+
+Name: code-formats14
+
+=-=
+'("a" . "b")
+=-=-=
diff --git a/test/lisp/emacs-lisp/pp-tests.el b/test/lisp/emacs-lisp/pp-tests.el
index d74ef32f9f4..01ac572c537 100644
--- a/test/lisp/emacs-lisp/pp-tests.el
+++ b/test/lisp/emacs-lisp/pp-tests.el
@@ -20,6 +20,7 @@
;;; Code:
(require 'pp)
+(require 'ert-x)
(ert-deftest pp-print-quote ()
(should (string= (pp-to-string 'quote) "quote"))
@@ -32,4 +33,7 @@
(should (string= (pp-to-string '(quotefoo)) "(quotefoo)\n"))
(should (string= (pp-to-string '(a b)) "(a b)\n")))
+(ert-deftest test-indentation ()
+ (ert-test-erts-file (ert-resource-file "code-formats.erts")))
+
;;; pp-tests.el ends here.
diff --git a/test/lisp/emacs-lisp/range-tests.el b/test/lisp/emacs-lisp/range-tests.el
new file mode 100644
index 00000000000..660110aa1fb
--- /dev/null
+++ b/test/lisp/emacs-lisp/range-tests.el
@@ -0,0 +1,65 @@
+;;; range-tests.el --- Tests for range.el -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021-2022 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'range)
+(require 'ert)
+(require 'ert-x)
+
+(ert-deftest ranges ()
+ (should (equal (range-compress-list '(2 3 4 5 9 11 12 13))
+ '((2 . 5) 9 (11 . 13))))
+ (should (equal (range-uncompress '((2 . 5) 9 (11 . 13)))
+ '(2 3 4 5 9 11 12 13)))
+ (should (equal (range-normalize '(1 . 2))
+ '((1 . 2))))
+ (should (equal (range-difference '((1 . 10))
+ '((2 . 7)))
+ '(1 (8 . 10))))
+ (should (equal (range-intersection '((2 . 5) 9 (11 . 13))
+ '((5 . 12)))
+ '(5 9 (11 . 12))))
+ (should (equal (range-add-list '((2 . 5) 9 (11 . 13))
+ '(10 11 12 15 16 17))
+ '((2 . 5) (9 . 10) (11 . 13) (15 . 17))))
+ (should (equal (range-remove (copy-tree '((2 . 5) 9 (11 . 13)))
+ '((5 . 9)))
+ '((2 . 4) (11 . 13))))
+ (should (range-member-p 9 '((2 . 5) 9 (11 . 13))))
+ (should (range-member-p 12 '((2 . 5) 9 (11 . 13))))
+ (should (equal (range-list-intersection
+ '(4 5 6 7 8 9)
+ '((2 . 5) 9 (11 . 13)))
+ '(4 5 9)))
+ (should (equal (range-list-difference
+ '(4 5 6 7 8 9)
+ '((2 . 5) 9 (11 . 13)))
+ '(6 7 8)))
+ (should (equal (range-length '((2 . 5) 9 (11 . 13)))
+ 8))
+ (should (equal (range-concat '((2 . 5) 9 (11 . 13))
+ '(6 (12 . 15)))
+ '((2 . 6) 9 (11 . 15)))))
+
+;;; range-tests.el ends here
diff --git a/test/lisp/emacs-lisp/ring-tests.el b/test/lisp/emacs-lisp/ring-tests.el
index 5331af9ca7f..6bbcd94f201 100644
--- a/test/lisp/emacs-lisp/ring-tests.el
+++ b/test/lisp/emacs-lisp/ring-tests.el
@@ -199,7 +199,7 @@
(should (= (ring-size ring) 3))
(should (equal (ring-elements ring) '(5 4 3)))))
-(ert-deftest ring-tests-insert ()
+(ert-deftest ring-tests-insert-2 ()
(let ((ring (make-ring 2)))
(ring-insert+extend ring :a)
(ring-insert+extend ring :b)
diff --git a/test/lisp/emacs-lisp/rmc-tests.el b/test/lisp/emacs-lisp/rmc-tests.el
index 11499b6b0e7..385b0fe44a5 100644
--- a/test/lisp/emacs-lisp/rmc-tests.el
+++ b/test/lisp/emacs-lisp/rmc-tests.el
@@ -22,14 +22,42 @@
;;; Commentary:
-;;
-
;;; Code:
(require 'ert)
(require 'rmc)
+(require 'cl-lib)
(eval-when-compile (require 'cl-lib))
+(ert-deftest test-rmc--add-key-description ()
+ (cl-letf (((symbol-function 'display-supports-face-attributes-p) (lambda (_ _) t)))
+ (should (equal (rmc--add-key-description '(?y "yes"))
+ '(?y . "yes")))
+ (should (equal (rmc--add-key-description '(?n "foo"))
+ '(?n . "n foo")))
+ (should (equal (rmc--add-key-description '(?\s "foo bar"))
+ `(?\s . "SPC foo bar")))))
+
+(ert-deftest test-rmc--add-key-description/with-attributes ()
+ (cl-letf (((symbol-function 'display-supports-face-attributes-p) (lambda (_ _) t)))
+ (should (equal-including-properties
+ (rmc--add-key-description '(?y "yes"))
+ `(?y . ,(concat (propertize "y" 'face 'read-multiple-choice-face) "es"))))
+ (should (equal-including-properties
+ (rmc--add-key-description '(?n "foo"))
+ `(?n . ,(concat (propertize "n" 'face 'read-multiple-choice-face) " foo"))))
+ (should (equal-including-properties
+ (rmc--add-key-description '(?\s "foo bar"))
+ `(?\s . ,(concat (propertize "SPC" 'face 'read-multiple-choice-face) " foo bar"))))))
+
+(ert-deftest test-rmc--add-key-description/non-graphical-display ()
+ (cl-letf (((symbol-function 'display-supports-face-attributes-p) (lambda (_ _) nil)))
+ (should (equal-including-properties
+ (rmc--add-key-description '(?y "yes"))
+ '(?y . "[Y]es")))
+ (should (equal-including-properties
+ (rmc--add-key-description '(?n "foo"))
+ `(?n . ,(concat (propertize "n" 'face 'help-key-binding) " foo"))))))
(ert-deftest test-read-multiple-choice ()
(dolist (char '(?y ?n))
@@ -38,6 +66,26 @@
(should (equal (list char str)
(read-multiple-choice "Do it? " '((?y "yes") (?n "no"))))))))
+(ert-deftest test-read-multiple-choice-help ()
+ (let ((chars '(?o ?a))
+ help)
+ (cl-letf* (((symbol-function #'read-event)
+ (lambda ()
+ (message "chars %S" chars)
+ (when (= 1 (length chars))
+ (with-current-buffer "*Multiple Choice Help*"
+ (setq help (buffer-string))))
+ (pop chars))))
+ (read-multiple-choice
+ "Choose:"
+ '((?a "aaa")
+ (?b "bbb")
+ (?c "ccc" "a really long description of ccc")))
+ (should (equal help "Choose:
+
+a: [A]aa b: [B]bb c: [C]cc
+ a really long
+ description of ccc
+ \n")))))
-(provide 'rmc-tests)
;;; rmc-tests.el ends here
diff --git a/test/lisp/emacs-lisp/seq-tests.el b/test/lisp/emacs-lisp/seq-tests.el
index 228c5c1991e..d979604910e 100644
--- a/test/lisp/emacs-lisp/seq-tests.el
+++ b/test/lisp/emacs-lisp/seq-tests.el
@@ -173,16 +173,18 @@ Evaluate BODY for each created sequence.
(should (seq-find #'null '(1 2 3) 'sentinel)))
(ert-deftest test-seq-contains ()
- (with-test-sequences (seq '(3 4 5 6))
- (should (seq-contains seq 3))
- (should-not (seq-contains seq 7)))
- (with-test-sequences (seq '())
- (should-not (seq-contains seq 3))
- (should-not (seq-contains seq nil))))
+ (with-suppressed-warnings ((obsolete seq-contains))
+ (with-test-sequences (seq '(3 4 5 6))
+ (should (seq-contains seq 3))
+ (should-not (seq-contains seq 7)))
+ (with-test-sequences (seq '())
+ (should-not (seq-contains seq 3))
+ (should-not (seq-contains seq nil)))))
(ert-deftest test-seq-contains-should-return-the-elt ()
- (with-test-sequences (seq '(3 4 5 6))
- (should (= 5 (seq-contains seq 5)))))
+ (with-suppressed-warnings ((obsolete seq-contains))
+ (with-test-sequences (seq '(3 4 5 6))
+ (should (= 5 (seq-contains seq 5))))))
(ert-deftest test-seq-contains-p ()
(with-test-sequences (seq '(3 4 5 6))
@@ -404,7 +406,7 @@ Evaluate BODY for each created sequence.
(let ((seq '(1 (2 (3 (4))))))
(seq-let (_ (_ (_ (a)))) seq
(should (= a 4))))
- (let (seq)
+ (let ((seq nil))
(seq-let (a b c) seq
(should (null a))
(should (null b))
@@ -428,7 +430,7 @@ Evaluate BODY for each created sequence.
(seq '(1 (2 (3 (4))))))
(seq-setq (_ (_ (_ (a)))) seq)
(should (= a 4)))
- (let (seq a b c)
+ (let ((seq nil) a b c)
(seq-setq (a b c) seq)
(should (null a))
(should (null b))
@@ -509,5 +511,26 @@ Evaluate BODY for each created sequence.
(should (equal (seq-difference '(1 nil) '(2 nil))
'(1)))))
+(ert-deftest test-seq-split ()
+ (let ((seq [0 1 2 3 4 5 6 7 8 9 10]))
+ (should (equal seq (car (seq-split seq 20))))
+ (should (equal seq (car (seq-split seq 11))))
+ (should (equal (seq-split seq 10)
+ '([0 1 2 3 4 5 6 7 8 9] [10])))
+ (should (equal (seq-split seq 5)
+ '([0 1 2 3 4] [5 6 7 8 9] [10])))
+ (should (equal (seq-split seq 1)
+ '([0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10])))
+ (should-error (seq-split seq 0))
+ (should-error (seq-split seq -10)))
+ (let ((seq '(0 1 2 3 4 5 6 7 8 9)))
+ (should (equal (seq-split seq 5)
+ '((0 1 2 3 4) (5 6 7 8 9)))))
+ (let ((seq "0123456789"))
+ (should (equal (seq-split seq 2)
+ '("01" "23" "45" "67" "89")))
+ (should (equal (seq-split seq 3)
+ '("012" "345" "678" "9")))))
+
(provide 'seq-tests)
;;; seq-tests.el ends here
diff --git a/test/lisp/emacs-lisp/shortdoc-tests.el b/test/lisp/emacs-lisp/shortdoc-tests.el
index 1c4125e3010..8515b9fdfb9 100644
--- a/test/lisp/emacs-lisp/shortdoc-tests.el
+++ b/test/lisp/emacs-lisp/shortdoc-tests.el
@@ -44,6 +44,17 @@
(should (shortdoc-tests--tree-contains expr fun))))
(setq props (cddr props))))))))
+(ert-deftest shortdoc-all-groups-work ()
+ "Test that all defined shortdoc groups display correctly."
+ (dolist (group (mapcar (lambda (x) (car x)) shortdoc--groups))
+ (let ((buf-name (format "*Shortdoc %s*" group)) buf)
+ (unwind-protect
+ (progn
+ (shortdoc-display-group group)
+ (should (setq buf (get-buffer buf-name))))
+ (when buf
+ (kill-buffer buf))))))
+
(provide 'shortdoc-tests)
;;; shortdoc-tests.el ends here
diff --git a/test/lisp/emacs-lisp/subr-x-tests.el b/test/lisp/emacs-lisp/subr-x-tests.el
index 7d5aca7ba4a..99c0e822155 100644
--- a/test/lisp/emacs-lisp/subr-x-tests.el
+++ b/test/lisp/emacs-lisp/subr-x-tests.el
@@ -169,13 +169,13 @@
"no")
"no"))
(should (equal
- (let (z)
+ (let ((z nil))
(if-let* (z (a 1) (b 2) (c 3))
"yes"
"no"))
"no"))
(should (equal
- (let (d)
+ (let ((d nil))
(if-let* ((a 1) (b 2) (c 3) d)
"yes"
"no"))
@@ -191,7 +191,7 @@
(ert-deftest subr-x-test-if-let*-and-laziness-is-preserved ()
"Test `if-let' respects `and' laziness."
- (let (a-called b-called c-called)
+ (let ((a-called nil) (b-called nil) c-called)
(should (equal
(if-let* ((a nil)
(b (setq b-called t))
@@ -199,7 +199,7 @@
"yes"
(list a-called b-called c-called))
(list nil nil nil))))
- (let (a-called b-called c-called)
+ (let ((a-called nil) (b-called nil) c-called)
(should (equal
(if-let* ((a (setq a-called t))
(b nil)
@@ -207,12 +207,12 @@
"yes"
(list a-called b-called c-called))
(list t nil nil))))
- (let (a-called b-called c-called)
+ (let ((a-called nil) (b-called nil) c-called)
(should (equal
(if-let* ((a (setq a-called t))
- (b (setq b-called t))
- (c nil)
- (d (setq c-called t)))
+ (b (setq b-called t))
+ (c nil)
+ (d (setq c-called t)))
"yes"
(list a-called b-called c-called))
(list t t nil)))))
@@ -329,12 +329,12 @@
"no")
nil))
(should (equal
- (let (z)
+ (let ((z nil))
(when-let* (z (a 1) (b 2) (c 3))
"no"))
nil))
(should (equal
- (let (d)
+ (let ((d nil))
(when-let* ((a 1) (b 2) (c 3) d)
"no"))
nil)))
@@ -348,7 +348,7 @@
(ert-deftest subr-x-test-when-let*-and-laziness-is-preserved ()
"Test `when-let' respects `and' laziness."
- (let (a-called b-called c-called)
+ (let ((a-called nil) (b-called nil) (c-called nil))
(should (equal
(progn
(when-let* ((a nil)
@@ -357,7 +357,7 @@
"yes")
(list a-called b-called c-called))
(list nil nil nil))))
- (let (a-called b-called c-called)
+ (let ((a-called nil) (b-called nil) (c-called nil))
(should (equal
(progn
(when-let* ((a (setq a-called t))
@@ -366,7 +366,7 @@
"yes")
(list a-called b-called c-called))
(list t nil nil))))
- (let (a-called b-called c-called)
+ (let ((a-called nil) (b-called nil) (c-called nil))
(should (equal
(progn
(when-let* ((a (setq a-called t))
@@ -607,21 +607,36 @@
(should (equal (string-limit "foó" 4 nil 'utf-8) "fo\303\263"))
(should (equal (string-limit "foóa" 4 nil 'utf-8) "fo\303\263"))
(should (equal (string-limit "foóá" 4 nil 'utf-8) "fo\303\263"))
+ (should (equal (string-limit "foóá" 2 nil 'utf-8-with-signature)
+ ""))
(should (equal (string-limit "foóá" 4 nil 'utf-8-with-signature)
- "fo\303\263"))
+ "\357\273\277f"))
(should (equal (string-limit "foóa" 4 nil 'iso-8859-1) "fo\363a"))
(should (equal (string-limit "foóá" 4 nil 'iso-8859-1) "fo\363\341"))
- (should (equal (string-limit "foóá" 4 nil 'utf-16) "\000f\000o"))
+ (should (equal (string-limit "foóá" 3 nil 'utf-16) ""))
+ (should (equal (string-limit "foóá" 6 nil 'utf-16) "\376\377\000f\000o"))
(should (equal (string-limit "foó" 10 t 'utf-8) "fo\303\263"))
(should (equal (string-limit "foó" 3 t 'utf-8) "o\303\263"))
(should (equal (string-limit "foó" 4 t 'utf-8) "fo\303\263"))
(should (equal (string-limit "foóa" 4 t 'utf-8) "o\303\263a"))
(should (equal (string-limit "foóá" 4 t 'utf-8) "\303\263\303\241"))
- (should (equal (string-limit "foóá" 2 t 'utf-8-with-signature) "\303\241"))
+ (should (equal (string-limit "foóá" 2 t 'utf-8-with-signature)
+ ""))
(should (equal (string-limit "foóa" 4 t 'iso-8859-1) "fo\363a"))
(should (equal (string-limit "foóá" 4 t 'iso-8859-1) "fo\363\341"))
- (should (equal (string-limit "foóá" 4 t 'utf-16) "\000\363\000\341")))
+ (should (equal (string-limit "foóá" 6 t 'utf-16) "\376\377\000\363\000\341")))
+
+(ert-deftest subr-string-limit-glyphs ()
+ (should (equal (encode-coding-string "Hello, 👼🏻🧑🏼‍🤝‍🧑🏻" 'utf-8)
+ "Hello, \360\237\221\274\360\237\217\273\360\237\247\221\360\237\217\274\342\200\215\360\237\244\235\342\200\215\360\237\247\221\360\237\217\273"))
+ (should (= (length (encode-coding-string "Hello, 👼🏻🧑🏼‍🤝‍🧑🏻" 'utf-8)) 41))
+ (should (equal (string-limit "Hello, 👼🏻🧑🏼‍🤝‍🧑🏻" 100 nil 'utf-8)
+ "Hello, \360\237\221\274\360\237\217\273\360\237\247\221\360\237\217\274\342\200\215\360\237\244\235\342\200\215\360\237\247\221\360\237\217\273"))
+ (should (equal (string-limit "Hello, 👼🏻🧑🏼‍🤝‍🧑🏻" 15 nil 'utf-8)
+ "Hello, \360\237\221\274\360\237\217\273"))
+ (should (equal (string-limit "Hello, 👼🏻🧑🏼‍🤝‍🧑🏻" 10 nil 'utf-8)
+ "Hello, ")))
(ert-deftest subr-string-lines ()
(should (equal (string-lines "foo") '("foo")))
@@ -638,5 +653,118 @@
(should (equal (string-chop-newline "foo\nbar\n") "foo\nbar"))
(should (equal (string-chop-newline "foo\nbar") "foo\nbar")))
+(ert-deftest subr-ensure-empty-lines ()
+ (should
+ (equal
+ (with-temp-buffer
+ (insert "foo")
+ (goto-char (point-min))
+ (ensure-empty-lines 2)
+ (buffer-string))
+ "\n\nfoo"))
+ (should
+ (equal
+ (with-temp-buffer
+ (insert "foo")
+ (ensure-empty-lines 2)
+ (buffer-string))
+ "foo\n\n\n"))
+ (should
+ (equal
+ (with-temp-buffer
+ (insert "foo\n")
+ (ensure-empty-lines 2)
+ (buffer-string))
+ "foo\n\n\n"))
+ (should
+ (equal
+ (with-temp-buffer
+ (insert "foo\n\n\n\n\n")
+ (ensure-empty-lines 2)
+ (buffer-string))
+ "foo\n\n\n"))
+ (should
+ (equal
+ (with-temp-buffer
+ (insert "foo\n\n\n")
+ (ensure-empty-lines 0)
+ (buffer-string))
+ "foo\n")))
+
+(ert-deftest subr-x-test-add-display-text-property ()
+ (with-temp-buffer
+ (insert "Foo bar zot gazonk")
+ (add-display-text-property 4 8 'height 2.0)
+ (add-display-text-property 2 12 'raise 0.5)
+ (should (equal (get-text-property 2 'display) '(raise 0.5)))
+ (should (equal (get-text-property 5 'display)
+ '((raise 0.5) (height 2.0))))
+ (should (equal (get-text-property 9 'display) '(raise 0.5))))
+ (with-temp-buffer
+ (insert "Foo bar zot gazonk")
+ (put-text-property 4 8 'display [(height 2.0)])
+ (add-display-text-property 2 12 'raise 0.5)
+ (should (equal (get-text-property 2 'display) '(raise 0.5)))
+ (should (equal (get-text-property 5 'display)
+ [(raise 0.5) (height 2.0)]))
+ (should (equal (get-text-property 9 'display) '(raise 0.5)))))
+
+(ert-deftest subr-x-named-let ()
+ (let ((funs ()))
+ (named-let loop
+ ((rest '(1 42 3))
+ (sum 0))
+ (when rest
+ ;; Here, we make sure that the variables are distinct in every
+ ;; iteration, since a naive tail-call optimization would tend to end up
+ ;; with a single `sum' variable being shared by all the closures.
+ (push (lambda () sum) funs)
+ ;; Here we add a dummy `sum' variable which shadows the `sum' iteration
+ ;; variable since a naive tail-call optimization could also trip here
+ ;; thinking it can `(setq sum ...)' to set the iteration
+ ;; variable's value.
+ (let ((sum sum))
+ (loop (cdr rest) (+ sum (car rest))))))
+ (should (equal (mapcar #'funcall funs) '(43 1 0)))))
+
+(ert-deftest test-with-buffer-unmodified-if-unchanged ()
+ (with-temp-buffer
+ (with-buffer-unmodified-if-unchanged
+ (insert "t"))
+ (should (buffer-modified-p)))
+
+ (with-temp-buffer
+ (with-buffer-unmodified-if-unchanged
+ (insert "t")
+ (delete-char -1))
+ (should-not (buffer-modified-p)))
+
+ ;; Shouldn't error.
+ (should
+ (with-temp-buffer
+ (with-buffer-unmodified-if-unchanged
+ (insert "t")
+ (delete-char -1)
+ (kill-buffer))))
+
+ (with-temp-buffer
+ (let ((outer (current-buffer)))
+ (with-temp-buffer
+ (let ((inner (current-buffer)))
+ (with-buffer-unmodified-if-unchanged
+ (insert "t")
+ (delete-char -1)
+ (set-buffer outer))
+ (with-current-buffer inner
+ (should-not (buffer-modified-p))))))))
+
+(ert-deftest subr-x--hash-table-keys-and-values ()
+ (let ((h (make-hash-table)))
+ (puthash 'a 1 h)
+ (puthash 'c 3 h)
+ (puthash 'b 2 h)
+ (should (equal (sort (hash-table-keys h) #'string<) '(a b c)))
+ (should (equal (sort (hash-table-values h) #'<) '(1 2 3)))))
+
(provide 'subr-x-tests)
;;; subr-x-tests.el ends here
diff --git a/test/lisp/emacs-lisp/testcover-resources/testcases.el b/test/lisp/emacs-lisp/testcover-resources/testcases.el
index 1d5821146c8..46040be1a6c 100644
--- a/test/lisp/emacs-lisp/testcover-resources/testcases.el
+++ b/test/lisp/emacs-lisp/testcover-resources/testcases.el
@@ -424,7 +424,7 @@
(defmacro testcover-testcase-nth-case (arg vec)
(declare (indent 1)
(debug (form (vector &rest form))))
- `(eval (aref ,vec%%% ,arg%%%))%%%)
+ `(eval (aref ,vec%%% ,arg%%%) t)%%%)
(defun testcover-testcase-use-nth-case (choice val)
(testcover-testcase-nth-case choice
diff --git a/test/lisp/emacs-lisp/testcover-tests.el b/test/lisp/emacs-lisp/testcover-tests.el
index 8bb6b6f0150..39cd3175c26 100644
--- a/test/lisp/emacs-lisp/testcover-tests.el
+++ b/test/lisp/emacs-lisp/testcover-tests.el
@@ -45,34 +45,34 @@ testcases.el. This can be used to create test cases if Testcover
is working correctly on a code sample. OPTARGS are optional
arguments for `testcover-start'."
(interactive "r")
- (let ((tempfile (make-temp-file "testcover-tests-" nil ".el"))
- (find-file-suppress-same-file-warnings t)
- (code (buffer-substring beg end))
- (marked-up-code))
- (unwind-protect
- (progn
- (with-temp-file tempfile
- (insert code))
- (save-current-buffer
- (let ((buf (find-file-noselect tempfile)))
- (set-buffer buf)
- (apply 'testcover-start (cons tempfile optargs))
- (testcover-mark-all buf)
- (dolist (overlay (overlays-in (point-min) (point-max)))
- (let ((ov-face (overlay-get overlay 'face)))
- (goto-char (overlay-end overlay))
- (cond
- ((eq ov-face 'testcover-nohits) (insert "!!!"))
- ((eq ov-face 'testcover-1value) (insert "%%%"))
- (t nil))))
- (setq marked-up-code (buffer-string)))
- (set-buffer-modified-p nil)))
- (ignore-errors (kill-buffer (find-file-noselect tempfile)))
- (ignore-errors (delete-file tempfile)))
-
- ;; Now replace the original code with the marked up code.
- (delete-region beg end)
- (insert marked-up-code))))
+ (ert-with-temp-file tempfile
+ :suffix ".el"
+ (let ((find-file-suppress-same-file-warnings t)
+ (code (buffer-substring beg end))
+ (marked-up-code))
+ (unwind-protect
+ (progn
+ (with-temp-file tempfile
+ (insert code))
+ (save-current-buffer
+ (let ((buf (find-file-noselect tempfile)))
+ (set-buffer buf)
+ (apply 'testcover-start (cons tempfile optargs))
+ (testcover-mark-all buf)
+ (dolist (overlay (overlays-in (point-min) (point-max)))
+ (let ((ov-face (overlay-get overlay 'face)))
+ (goto-char (overlay-end overlay))
+ (cond
+ ((eq ov-face 'testcover-nohits) (insert "!!!"))
+ ((eq ov-face 'testcover-1value) (insert "%%%"))
+ (t nil))))
+ (setq marked-up-code (buffer-string)))
+ (set-buffer-modified-p nil)))
+ (ignore-errors (kill-buffer (find-file-noselect tempfile))))
+
+ ;; Now replace the original code with the marked up code.
+ (delete-region beg end)
+ (insert marked-up-code)))))
(eval-and-compile
(defun testcover-tests-unmarkup-region (beg end)
@@ -99,32 +99,32 @@ arguments for `testcover-start'."
(eval-and-compile
(defun testcover-tests-run-test-case (marked-up-code)
"Test the operation of Testcover on the string MARKED-UP-CODE."
- (let ((tempfile (make-temp-file "testcover-tests-" nil ".el"))
- (find-file-suppress-same-file-warnings t))
- (unwind-protect
- (progn
- (with-temp-file tempfile
- (insert marked-up-code))
- ;; Remove the marks and mark the code up again. The original
- ;; and recreated versions should match.
- (save-current-buffer
- (set-buffer (find-file-noselect tempfile))
- ;; Fail the test if the debugger tries to become active,
- ;; which can happen if Testcover fails to attach itself
- ;; correctly. Note that this will prevent debugging
- ;; these tests using Edebug.
- (cl-letf (((symbol-function #'edebug-default-enter)
- (lambda (&rest _args)
- (ert-fail "Debugger invoked during test run"))))
- (dolist (byte-compile '(t nil))
- (testcover-tests-unmarkup-region (point-min) (point-max))
- (unwind-protect
- (testcover-tests-markup-region (point-min) (point-max) byte-compile)
- (set-buffer-modified-p nil))
- (should (string= marked-up-code
- (buffer-string)))))))
- (ignore-errors (kill-buffer (find-file-noselect tempfile)))
- (ignore-errors (delete-file tempfile))))))
+ (ert-with-temp-file tempfile
+ :suffix ".el"
+ (let ((find-file-suppress-same-file-warnings t))
+ (unwind-protect
+ (progn
+ (with-temp-file tempfile
+ (insert marked-up-code))
+ ;; Remove the marks and mark the code up again. The original
+ ;; and recreated versions should match.
+ (save-current-buffer
+ (set-buffer (find-file-noselect tempfile))
+ ;; Fail the test if the debugger tries to become active,
+ ;; which can happen if Testcover fails to attach itself
+ ;; correctly. Note that this will prevent debugging
+ ;; these tests using Edebug.
+ (cl-letf (((symbol-function #'edebug-default-enter)
+ (lambda (&rest _args)
+ (ert-fail "Debugger invoked during test run"))))
+ (dolist (byte-compile '(t nil))
+ (testcover-tests-unmarkup-region (point-min) (point-max))
+ (unwind-protect
+ (testcover-tests-markup-region (point-min) (point-max) byte-compile)
+ (set-buffer-modified-p nil))
+ (should (string= marked-up-code
+ (buffer-string)))))))
+ (ignore-errors (kill-buffer (find-file-noselect tempfile))))))))
;; Convert test case file to ert-defmethod.
diff --git a/test/lisp/emacs-lisp/text-property-search-tests.el b/test/lisp/emacs-lisp/text-property-search-tests.el
index d137572f304..98fdd55e85f 100644
--- a/test/lisp/emacs-lisp/text-property-search-tests.el
+++ b/test/lisp/emacs-lisp/text-property-search-tests.el
@@ -156,20 +156,19 @@
;;;; Position after search.
-(defun text-property-search--pos-test (fun pos &optional reverse)
+(ert-deftest text-property-search-forward/point-at-beginning ()
(with-temp-buffer
- (insert (concat "foo "
- (propertize "bar" 'x t)
- " baz"))
- (goto-char (if reverse (point-max) (point-min)))
- (funcall fun 'x t)
- (should (= (point) pos))))
-
-(ert-deftest text-property-search-forward-point-at-beginning ()
- (text-property-search--pos-test #'text-property-search-forward 5))
-
-(ert-deftest text-property-search-backward-point-at-end ()
- (text-property-search--pos-test #'text-property-search-backward 8 t))
+ (insert (concat "1234" (propertize "567" 'x t) "890"))
+ (goto-char (point-min))
+ (text-property-search-forward 'x t)
+ (should (= (point) 5))))
+
+(ert-deftest text-property-search-backward/point-at-end ()
+ (with-temp-buffer
+ (insert (concat "1234" (propertize "567" 'x t) "890"))
+ (goto-char (point-max))
+ (text-property-search-backward 'x t)
+ (should (= (point) 8))))
(provide 'text-property-search-tests)
diff --git a/test/lisp/emacs-lisp/timer-tests.el b/test/lisp/emacs-lisp/timer-tests.el
index 1123596113e..4d974cfd9d7 100644
--- a/test/lisp/emacs-lisp/timer-tests.el
+++ b/test/lisp/emacs-lisp/timer-tests.el
@@ -37,7 +37,8 @@
(ert-deftest timer-tests-debug-timer-check ()
;; This function exists only if --enable-checking.
(skip-unless (fboundp 'debug-timer-check))
- (should (debug-timer-check)))
+ (when (fboundp 'debug-timer-check) ; silence byte-compiler
+ (should (debug-timer-check))))
(ert-deftest timer-test-multiple-of-time ()
(should (time-equal-p
diff --git a/test/lisp/emacs-lisp/vtable-tests.el b/test/lisp/emacs-lisp/vtable-tests.el
new file mode 100644
index 00000000000..627d9f9c5df
--- /dev/null
+++ b/test/lisp/emacs-lisp/vtable-tests.el
@@ -0,0 +1,42 @@
+;;; vtable-tests.el --- Tests for vtable.el -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'vtable)
+(require 'ert)
+(require 'ert-x)
+
+(ert-deftest test-vstable-compute-columns ()
+ (should
+ (equal (mapcar
+ (lambda (column)
+ (vtable-column-align column))
+ (vtable--compute-columns
+ (make-vtable :columns '("a" "b" "c")
+ :objects '(("foo" 1 2)
+ ("bar" 3 :zot))
+ :insert nil)))
+ '(left right left))))
+
+;;; vtable-tests.el ends here
diff --git a/test/lisp/emulation/viper-tests.el b/test/lisp/emulation/viper-tests.el
index d2f5988442d..1d2bf46b199 100644
--- a/test/lisp/emulation/viper-tests.el
+++ b/test/lisp/emulation/viper-tests.el
@@ -21,7 +21,8 @@
;;; Code:
-
+(require 'ert)
+(require 'ert-x)
(require 'viper)
(defun viper-test-undo-kmacro (kmacro)
@@ -30,47 +31,42 @@
This function makes as many attempts as possible to clean up
after itself, although it will leave a buffer called
*viper-test-buffer* if it fails (this is deliberate!)."
- (let (
- ;; Viper just turns itself off during batch use.
- (noninteractive nil)
- ;; Switch off start up message or it will chew the key presses.
- (viper-inhibit-startup-message 't)
- ;; Select an expert-level for the same reason.
- (viper-expert-level 5)
- ;; viper loads this even with -q so make sure it's empty!
- (viper-custom-file-name (make-temp-file "viper-tests" nil ".elc"))
- (before-buffer (current-buffer)))
- (unwind-protect
- (progn
- ;; viper-mode is essentially global, so set it here.
- (viper-mode)
- ;; We must switch to buffer because we are using a keyboard macro
- ;; which appears to not go to the current-buffer but what ever is
- ;; currently taking keyboard events. We use a named buffer because
- ;; then we can see what it in it if it all goes wrong.
- (switch-to-buffer
- (get-buffer-create
- "*viper-test-buffer*"))
- (erase-buffer)
- ;; The new buffer fails to enter vi state so set it.
- (viper-change-state-to-vi)
- ;; Run the macro.
- (execute-kbd-macro kmacro)
- (let ((rtn
- (buffer-substring-no-properties
- (point-min)
- (point-max))))
- ;; Kill the buffer iff the macro succeeds.
- (kill-buffer)
- rtn))
- ;; Switch everything off and restore the buffer.
- (toggle-viper-mode)
- (delete-file viper-custom-file-name)
- (switch-to-buffer before-buffer))))
-
-(ert-deftest viper-test-go ()
- "Test that this file is running."
- (should t))
+ (ert-with-temp-file viper-custom-file-name
+ ;; viper loads this even with -q so make sure it's empty!
+ :prefix "emacs-viper-tests" :suffix ".elc"
+ (let (;; Viper just turns itself off during batch use.
+ (noninteractive nil)
+ ;; Switch off start up message or it will chew the key presses.
+ (viper-inhibit-startup-message 't)
+ ;; Select an expert-level for the same reason.
+ (viper-expert-level 5)
+ (before-buffer (current-buffer)))
+ (unwind-protect
+ (progn
+ ;; viper-mode is essentially global, so set it here.
+ (viper-mode)
+ ;; We must switch to buffer because we are using a keyboard macro
+ ;; which appears to not go to the current-buffer but what ever is
+ ;; currently taking keyboard events. We use a named buffer because
+ ;; then we can see what it in it if it all goes wrong.
+ (switch-to-buffer
+ (get-buffer-create
+ "*viper-test-buffer*"))
+ (erase-buffer)
+ ;; The new buffer fails to enter vi state so set it.
+ (viper-change-state-to-vi)
+ ;; Run the macro.
+ (execute-kbd-macro kmacro)
+ (let ((rtn
+ (buffer-substring-no-properties
+ (point-min)
+ (point-max))))
+ ;; Kill the buffer iff the macro succeeds.
+ (kill-buffer)
+ rtn))
+ ;; Switch everything off and restore the buffer.
+ (toggle-viper-mode)
+ (switch-to-buffer before-buffer)))))
(ert-deftest viper-test-fix ()
"Test that the viper kmacro fixture is working."
diff --git a/test/lisp/epg-tests.el b/test/lisp/epg-tests.el
index 6354f926912..65aaafd9f18 100644
--- a/test/lisp/epg-tests.el
+++ b/test/lisp/epg-tests.el
@@ -58,48 +58,45 @@
(cl-defmacro with-epg-tests ((&optional &key require-passphrase
require-public-key
require-secret-key)
- &rest body)
+ &rest body)
"Set up temporary locations and variables for testing."
(declare (indent 1) (debug (sexp body)))
- `(let* ((epg-tests-home-directory (make-temp-file "epg-tests-homedir" t))
- (process-environment
- (append
- (list "GPG_AGENT_INFO"
- (format "GNUPGHOME=%s" epg-tests-home-directory))
- process-environment)))
- (unwind-protect
- ;; GNUPGHOME is needed to find a usable gpg, so we can't
- ;; check whether to skip any earlier (Bug#23561).
- (let ((epg-config (or (epg-tests-find-usable-gpg-configuration
- ,require-passphrase ,require-public-key)
- (ert-skip "No usable gpg config")))
- (context (epg-make-context 'OpenPGP)))
- (setf (epg-context-program context)
- (alist-get 'program epg-config))
- (setf (epg-context-home-directory context)
- epg-tests-home-directory)
- ,(if require-passphrase
- '(with-temp-file (expand-file-name
- "gpg-agent.conf" epg-tests-home-directory)
- (insert "pinentry-program "
- (ert-resource-file "dummy-pinentry")
- "\n")
- (epg-context-set-passphrase-callback
- context
- #'epg-tests-passphrase-callback)))
- ,(if require-public-key
- '(epg-import-keys-from-file
- context
- (ert-resource-file "pubkey.asc")))
- ,(if require-secret-key
- '(epg-import-keys-from-file
- context
- (ert-resource-file "seckey.asc")))
- (with-temp-buffer
- (setq-local epg-tests-context context)
- ,@body))
- (when (file-directory-p epg-tests-home-directory)
- (delete-directory epg-tests-home-directory t)))))
+ `(ert-with-temp-directory epg-tests-home-directory
+ (let* ((process-environment
+ (append
+ (list "GPG_AGENT_INFO"
+ (format "GNUPGHOME=%s" epg-tests-home-directory))
+ process-environment)))
+ ;; GNUPGHOME is needed to find a usable gpg, so we can't
+ ;; check whether to skip any earlier (Bug#23561).
+ (let ((epg-config (or (epg-tests-find-usable-gpg-configuration
+ ,require-passphrase ,require-public-key)
+ (ert-skip "No usable gpg config")))
+ (context (epg-make-context 'OpenPGP)))
+ (setf (epg-context-program context)
+ (alist-get 'program epg-config))
+ (setf (epg-context-home-directory context)
+ epg-tests-home-directory)
+ ,(if require-passphrase
+ '(with-temp-file (expand-file-name
+ "gpg-agent.conf" epg-tests-home-directory)
+ (insert "pinentry-program "
+ (ert-resource-file "dummy-pinentry")
+ "\n")
+ (epg-context-set-passphrase-callback
+ context
+ #'epg-tests-passphrase-callback)))
+ ,(if require-public-key
+ '(epg-import-keys-from-file
+ context
+ (ert-resource-file "pubkey.asc")))
+ ,(if require-secret-key
+ '(epg-import-keys-from-file
+ context
+ (ert-resource-file "seckey.asc")))
+ (with-temp-buffer
+ (setq-local epg-tests-context context)
+ ,@body)))))
(ert-deftest epg-decrypt-1 ()
:expected-result (if (getenv "EMACS_HYDRA_CI") :failed :passed) ; fixme
diff --git a/test/lisp/erc/erc-dcc-tests.el b/test/lisp/erc/erc-dcc-tests.el
new file mode 100644
index 00000000000..a1dfbab9dc5
--- /dev/null
+++ b/test/lisp/erc/erc-dcc-tests.el
@@ -0,0 +1,167 @@
+;;; erc-dcc-tests.el --- Tests for erc-dcc -*- lexical-binding:t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+;;
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published
+;; by the Free Software Foundation, either version 3 of the License,
+;; or (at your option) any later version.
+;;
+;; GNU Emacs is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;; Code:
+(require 'ert)
+(require 'erc-dcc)
+
+(ert-deftest erc-dcc-ctcp-query-send-regexp ()
+ (let ((s "DCC SEND \"file name\" 2130706433 9899 1405135128"))
+ (should (string-match erc-dcc-ctcp-query-send-regexp s))
+ (should-not (match-string 2 s))
+ (should (string= "file name" (match-string 1 s)))
+ (should (string= "SEND" (match-string 6 s))))
+ (let ((s "DCC SEND \"file \\\" name\" 2130706433 9899 1405135128"))
+ (should (string-match erc-dcc-ctcp-query-send-regexp s))
+ (should-not (match-string 2 s))
+ (should (string= "SEND" (match-string 6 s)))
+ (should (string= "file \" name"
+ (erc-dcc-unquote-filename (match-string 1 s)))))
+ (let ((s "DCC SEND filename 2130706433 9899 1405135128"))
+ (should (string-match erc-dcc-ctcp-query-send-regexp s))
+ (should (string= "filename" (match-string 2 s)))
+ (should (string= "2130706433" (match-string 3 s)))
+ (should (string= "9899" (match-string 4 s)))
+ (should (string= "1405135128" (match-string 5 s))))
+ (let ((s "DCC TSEND filename 2130706433 9899 1405135128"))
+ (should (string-match erc-dcc-ctcp-query-send-regexp s))
+ (should (string= "TSEND" (match-string 6 s)))))
+
+;; This also indirectly tests base functionality for
+;; `erc-dcc-do-LIST-command'
+
+(defun erc-dcc-tests--dcc-handle-ctcp-send (turbo)
+ (let (erc-send-completed-hook
+ erc-insert-modify-hook
+ erc-kill-channel-hook erc-kill-server-hook erc-kill-buffer-hook)
+ (with-current-buffer (get-buffer-create "fake-server")
+ (erc-mode)
+ (setq erc-server-process
+ (start-process "fake" (current-buffer) "sleep" "10")
+ erc-input-marker (make-marker)
+ erc-insert-marker (make-marker)
+ erc-server-current-nick "dummy")
+ (set-process-query-on-exit-flag erc-server-process nil)
+ (should-not erc-dcc-list)
+ (erc-ctcp-query-DCC erc-server-process
+ "tester"
+ "~tester"
+ "fake.irc"
+ "dummy"
+ (concat "DCC " (if turbo "TSEND" "SEND")
+ " foo 2130706433 9899 1405135128"))
+ (should-not (cdr erc-dcc-list))
+ (should (equal (plist-put (car erc-dcc-list) :parent 'fake)
+ `(:nick "tester!~tester@fake.irc"
+ :type GET
+ :peer nil
+ :parent fake
+ :ip "127.0.0.1"
+ :port "9899"
+ :file "foo"
+ :size 1405135128
+ :turbo ,(and turbo t)
+ :secure nil)))
+ (goto-char (point-min))
+ (should (search-forward "file foo offered by tester" nil t))
+ (erc-dcc-do-LIST-command erc-server-process)
+ (should (search-forward-regexp (concat
+ "GET +no +1405135128 +foo"
+ (and turbo " +(T)") "$")
+ nil t))
+ (when noninteractive
+ (kill-buffer))))
+ ;; `erc-dcc-list' is global; must leave it empty
+ (should erc-dcc-list)
+ (setq erc-dcc-list nil))
+
+(ert-deftest erc-dcc-handle-ctcp-send--base ()
+ (erc-dcc-tests--dcc-handle-ctcp-send nil))
+
+(ert-deftest erc-dcc-handle-ctcp-send--turbo ()
+ (erc-dcc-tests--dcc-handle-ctcp-send t))
+
+(ert-deftest erc-dcc-do-GET-command ()
+ (with-temp-buffer
+ (let* ((proc (start-process "fake" (current-buffer) "sleep" "10"))
+ (elt (list :nick "tester!~tester@fake.irc"
+ :type 'GET
+ :peer nil
+ :parent proc
+ :ip "127.0.0.1"
+ :port "9899"
+ :file "foo.bin"
+ :size 1405135128))
+ (erc-dcc-list (list elt))
+ ;;
+ erc-accidental-paste-threshold-seconds
+ erc-insert-modify-hook erc-send-completed-hook
+ erc-kill-channel-hook erc-kill-server-hook erc-kill-buffer-hook
+ calls)
+ (erc-mode)
+ (setq erc-server-process proc
+ erc-input-marker (make-marker)
+ erc-insert-marker (make-marker)
+ erc-server-current-nick "dummy")
+ (set-process-query-on-exit-flag proc nil)
+ (cl-letf (((symbol-function 'read-file-name)
+ (lambda (&rest _) "foo.bin"))
+ ((symbol-function 'erc-dcc-get-file)
+ (lambda (&rest r) (push r calls))))
+ (goto-char (point-max))
+ (set-marker erc-insert-marker (point-max))
+ (erc-display-prompt)
+
+ (ert-info ("No turbo")
+ (should-not (plist-member elt :turbo))
+ (goto-char erc-input-marker)
+ (insert "/dcc GET tester foo.bin")
+ (erc-send-current-line)
+ (should-not (plist-member (car erc-dcc-list) :turbo))
+ (should (equal (pop calls) (list elt "foo.bin" proc))))
+
+ (ert-info ("Arg turbo in pos 2")
+ (should-not (plist-member elt :turbo))
+ (goto-char erc-input-marker)
+ (insert "/dcc GET -t tester foo.bin")
+ (erc-send-current-line)
+ (should (eq t (plist-get (car erc-dcc-list) :turbo)))
+ (should (equal (pop calls) (list elt "foo.bin" proc))))
+
+ (ert-info ("Arg turbo in pos 4")
+ (setq elt (plist-put elt :turbo nil)
+ erc-dcc-list (list elt))
+ (goto-char erc-input-marker)
+ (insert "/dcc GET tester -t foo.bin")
+ (erc-send-current-line)
+ (should (eq t (plist-get (car erc-dcc-list) :turbo)))
+ (should (equal (pop calls) (list elt "foo.bin" proc))))
+
+ (ert-info ("Arg turbo in pos 6")
+ (setq elt (plist-put elt :turbo nil)
+ erc-dcc-list (list elt))
+ (goto-char erc-input-marker)
+ (insert "/dcc GET tester foo.bin -t")
+ (erc-send-current-line)
+ (should (eq t (plist-get (car erc-dcc-list) :turbo)))
+ (should (equal (pop calls) (list elt "foo.bin" proc))))))))
+
+;;; erc-dcc-tests.el ends here
diff --git a/test/lisp/erc/erc-join-tests.el b/test/lisp/erc/erc-join-tests.el
new file mode 100644
index 00000000000..8210defbfbd
--- /dev/null
+++ b/test/lisp/erc/erc-join-tests.el
@@ -0,0 +1,361 @@
+;;; erc-join-tests.el --- Tests for erc-join. -*- lexical-binding:t -*-
+
+;; Copyright (C) 2020-2022 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+;;
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published
+;; by the Free Software Foundation, either version 3 of the License,
+;; or (at your option) any later version.
+;;
+;; GNU Emacs is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'ert-x)
+(require 'erc-join)
+(require 'erc-networks)
+
+(ert-deftest erc-autojoin-channels--connect ()
+ (should (eq erc-autojoin-timing 'connect))
+ (should (= erc-autojoin-delay 30))
+ (should-not erc--autojoin-timer)
+
+ (let (calls
+ common
+ erc-kill-channel-hook erc-kill-server-hook erc-kill-buffer-hook)
+
+ (cl-letf (((symbol-function 'erc-server-send)
+ (lambda (line) (push line calls))))
+
+ (setq common
+ (lambda ()
+ (ert-with-test-buffer (:name "foonet")
+ (erc-mode)
+ (setq erc-server-process
+ (start-process "true" (current-buffer) "true")
+ erc-network 'FooNet
+ erc-session-server "irc.gnu.chat"
+ erc-server-current-nick "tester"
+ erc-networks--id (erc-networks--id-create nil)
+ erc-server-announced-name "foo.gnu.chat")
+ (set-process-query-on-exit-flag erc-server-process nil)
+ (erc-autojoin-channels erc-server-announced-name
+ "tester")
+ (should-not erc--autojoin-timer))))
+
+ (ert-info ("Join immediately on connect; server")
+ (let ((erc-autojoin-channels-alist '(("\\.gnu\\.chat\\'" "#chan"))))
+ (funcall common))
+ (should (equal (pop calls) "JOIN #chan")))
+
+ (ert-info ("Join immediately on connect; network")
+ (let ((erc-autojoin-channels-alist '((FooNet "#chan"))))
+ (funcall common))
+ (should (equal (pop calls) "JOIN #chan")))
+
+ (ert-info ("Do nothing; server")
+ (let ((erc-autojoin-channels-alist '(("bar\\.gnu\\.chat" "#chan"))))
+ (funcall common))
+ (should-not calls))
+
+ (ert-info ("Do nothing; network")
+ (let ((erc-autojoin-channels-alist '((BarNet "#chan"))))
+ (funcall common))
+ (should-not calls)))))
+
+(ert-deftest erc-autojoin-channels--delay ()
+ (should (eq erc-autojoin-timing 'connect))
+ (should (= erc-autojoin-delay 30))
+ (should-not erc--autojoin-timer)
+
+ (let (calls
+ common
+ erc-kill-channel-hook erc-kill-server-hook erc-kill-buffer-hook
+ (erc-autojoin-timing 'ident)
+ (erc-autojoin-delay 0.05))
+
+ (cl-letf (((symbol-function 'erc-server-send)
+ (lambda (line) (push line calls)))
+ ((symbol-function 'erc-autojoin-after-ident)
+ (lambda (&rest _r) (error "I ran but shouldn't have"))))
+
+ (setq common
+ (lambda ()
+ (ert-with-test-buffer (:name "foonet")
+ (erc-mode)
+ (setq erc-server-process
+ (start-process "true" (current-buffer) "true")
+ erc-network 'FooNet
+ erc-session-server "irc.gnu.chat"
+ erc-server-current-nick "tester"
+ erc-networks--id (erc-networks--id-create nil)
+ erc-server-announced-name "foo.gnu.chat")
+ (set-process-query-on-exit-flag erc-server-process nil)
+ (should-not erc--autojoin-timer)
+ (erc-autojoin-channels erc-server-announced-name "tester")
+ (should erc--autojoin-timer)
+ (should-not calls)
+ (sleep-for 0.1))))
+
+ (ert-info ("Deferred on connect; server")
+ (let ((erc-autojoin-channels-alist '(("\\.gnu\\.chat\\'" "#chan"))))
+ (funcall common))
+ (should (equal (pop calls) "JOIN #chan")))
+
+ (ert-info ("Deferred on connect; network")
+ (let ((erc-autojoin-channels-alist '((FooNet "#chan"))))
+ (funcall common))
+ (should (equal (pop calls) "JOIN #chan")))
+
+ (ert-info ("Do nothing; server")
+ (let ((erc-autojoin-channels-alist '(("bar\\.gnu\\.chat" "#chan"))))
+ (funcall common))
+ (should-not calls)))))
+
+(ert-deftest erc-autojoin-channels--ident ()
+ (should (eq erc-autojoin-timing 'connect))
+ (should (= erc-autojoin-delay 30))
+ (should-not erc--autojoin-timer)
+
+ (let (calls
+ common
+ erc-kill-channel-hook erc-kill-server-hook erc-kill-buffer-hook
+ (erc-autojoin-timing 'ident))
+
+ (cl-letf (((symbol-function 'erc-server-send)
+ (lambda (line) (push line calls))))
+
+ (setq common
+ (lambda ()
+ (ert-with-test-buffer (:name "foonet")
+ (erc-mode)
+ (setq erc-server-process
+ (start-process "true" (current-buffer) "true")
+ erc-network 'FooNet
+ erc-server-current-nick "tester"
+ erc-networks--id (erc-networks--id-create nil)
+ erc-server-announced-name "foo.gnu.chat")
+ (set-process-query-on-exit-flag erc-server-process nil)
+ (erc-autojoin-after-ident 'FooNet "tester")
+ (should-not erc--autojoin-timer))))
+
+ (ert-info ("Join on NickServ hook; server")
+ (let ((erc-autojoin-channels-alist '(("\\.gnu\\.chat\\'" "#chan"))))
+ (funcall common))
+ (should (equal (pop calls) "JOIN #chan")))
+
+ (ert-info ("Join on NickServ hook; network")
+ (let ((erc-autojoin-channels-alist '((FooNet "#chan"))))
+ (funcall common))
+ (should (equal (pop calls) "JOIN #chan"))))))
+
+(defun erc-join-tests--autojoin-add--common (setup &optional fwd)
+ (let (calls
+ erc-autojoin-channels-alist
+ erc-kill-channel-hook erc-kill-server-hook erc-kill-buffer-hook)
+
+ (cl-letf (((symbol-function 'erc-handle-parsed-server-response)
+ (lambda (_p m) (push m calls))))
+
+ (ert-with-test-buffer (:name "foonet")
+ (erc-mode)
+ (setq erc-server-process
+ (start-process "true" (current-buffer) "true")
+ erc-server-current-nick "tester"
+ erc--isupport-params (make-hash-table)
+ erc-server-announced-name "foo.gnu.chat")
+ (puthash 'CHANTYPES '("&#") erc--isupport-params)
+ (funcall setup)
+ (set-process-query-on-exit-flag erc-server-process nil)
+ (should-not calls)
+
+ (ert-info ("Add #chan")
+ (erc-parse-server-response erc-server-process
+ (concat ":tester!~i@c.u JOIN #chan"
+ (and fwd " * :Tes Ter")))
+ (should calls)
+ (erc-autojoin-add erc-server-process (pop calls))
+ (should (equal erc-autojoin-channels-alist '((FooNet "#chan")))))
+
+ (ert-info ("More recently joined chans are prepended")
+ (erc-parse-server-response
+ erc-server-process ; with account username
+ (concat ":tester!~i@c.u JOIN #spam" (and fwd " tester :Tes Ter")))
+ (should calls)
+ (erc-autojoin-add erc-server-process (pop calls))
+ (should (equal erc-autojoin-channels-alist
+ '((FooNet "#spam" "#chan")))))
+
+ (ert-info ("Duplicates skipped")
+ (erc-parse-server-response erc-server-process
+ (concat ":tester!~i@c.u JOIN #chan"
+ (and fwd " * :Tes Ter")))
+ (should calls)
+ (erc-autojoin-add erc-server-process (pop calls))
+ (should (equal erc-autojoin-channels-alist
+ '((FooNet "#spam" "#chan")))))
+
+ (ert-info ("Server used for local channel")
+ (erc-parse-server-response erc-server-process
+ (concat ":tester!~i@c.u JOIN &local"
+ (and fwd " * :Tes Ter")))
+ (should calls)
+ (erc-autojoin-add erc-server-process (pop calls))
+ (should (equal erc-autojoin-channels-alist
+ '(("foo\\.gnu\\.chat" "&local")
+ (FooNet "#spam" "#chan")))))))))
+
+(ert-deftest erc-autojoin-add--network ()
+ (erc-join-tests--autojoin-add--common
+ (lambda () (setq erc-network 'FooNet
+ erc-networks--id (erc-networks--id-create nil)))))
+
+(ert-deftest erc-autojoin-add--network-extended-syntax ()
+ (erc-join-tests--autojoin-add--common
+ (lambda () (setq erc-network 'FooNet
+ erc-networks--id (erc-networks--id-create nil)))
+ 'forward-compatible))
+
+(ert-deftest erc-autojoin-add--network-id ()
+ (erc-join-tests--autojoin-add--common
+ (lambda () (setq erc-network 'invalid
+ erc-networks--id (erc-networks--id-create 'FooNet)))))
+
+(ert-deftest erc-autojoin-add--server ()
+ (let (calls
+ erc-autojoin-channels-alist
+ erc-kill-channel-hook erc-kill-server-hook erc-kill-buffer-hook)
+
+ (cl-letf (((symbol-function 'erc-handle-parsed-server-response)
+ (lambda (_p m) (push m calls))))
+
+ (ert-info ("Network unavailable, announced name used")
+ (setq erc-autojoin-channels-alist nil)
+ (ert-with-test-buffer (:name "foonet")
+ (erc-mode)
+ (setq erc-server-process
+ (start-process "true" (current-buffer) "true")
+ erc-server-current-nick "tester"
+ erc-server-announced-name "foo.gnu.chat"
+ erc-networks--id (make-erc-networks--id)) ; assume too early
+ (set-process-query-on-exit-flag erc-server-process nil)
+ (should-not calls)
+ (erc-parse-server-response erc-server-process
+ ":tester!~u@q6ddatxcq6txy.irc JOIN #chan")
+ (should calls)
+ (erc-autojoin-add erc-server-process (pop calls))
+ (should (equal erc-autojoin-channels-alist
+ '(("gnu.chat" "#chan")))))))))
+
+(defun erc-join-tests--autojoin-remove--common (setup)
+ (let (calls
+ erc-autojoin-channels-alist
+ erc-kill-channel-hook erc-kill-server-hook erc-kill-buffer-hook)
+
+ (cl-letf (((symbol-function 'erc-handle-parsed-server-response)
+ (lambda (_p m) (push m calls))))
+
+ (setq erc-autojoin-channels-alist ; mutated, so can't quote whole thing
+ (list '(FooNet "#spam" "##chan")
+ '(BarNet "#bar" "##bar")
+ '("foo\\.gnu\\.chat" "&local")))
+
+ (ert-with-test-buffer (:name "foonet")
+ (erc-mode)
+ (setq erc-server-process
+ (start-process "true" (current-buffer) "true")
+ erc-server-current-nick "tester"
+ erc--isupport-params (make-hash-table)
+ erc-server-announced-name "foo.gnu.chat")
+ (puthash 'CHANTYPES '("&#") erc--isupport-params)
+ (funcall setup)
+ (set-process-query-on-exit-flag erc-server-process nil)
+ (should-not calls)
+
+ (ert-info ("Remove #chan")
+ (erc-parse-server-response erc-server-process
+ ":tester!~i@c.u PART ##chan")
+ (should calls)
+ (erc-autojoin-remove erc-server-process (pop calls))
+ (should (equal erc-autojoin-channels-alist
+ '((FooNet "#spam")
+ (BarNet "#bar" "##bar")
+ ("foo\\.gnu\\.chat" "&local")))))
+
+ (ert-info ("Wrong network, nothing done")
+ (erc-parse-server-response erc-server-process
+ ":tester!~i@c.u PART #bar")
+ (should calls)
+ (erc-autojoin-remove erc-server-process (pop calls))
+ (should (equal erc-autojoin-channels-alist
+ '((FooNet "#spam")
+ (BarNet "#bar" "##bar")
+ ("foo\\.gnu\\.chat" "&local")))))
+
+ (ert-info ("Local channel keyed by server found")
+ (erc-parse-server-response erc-server-process
+ ":tester!~i@c.u PART &local")
+ (should calls)
+ (erc-autojoin-remove erc-server-process (pop calls))
+ (should (equal erc-autojoin-channels-alist
+ '((FooNet "#spam") (BarNet "#bar" "##bar")))))))))
+
+(ert-deftest erc-autojoin-remove--network ()
+ (erc-join-tests--autojoin-remove--common
+ (lambda () (setq erc-network 'FooNet
+ erc-networks--id (erc-networks--id-create nil)))))
+
+(ert-deftest erc-autojoin-remove--network-id ()
+ (erc-join-tests--autojoin-remove--common
+ (lambda () (setq erc-network 'fake-a-roo
+ erc-networks--id (erc-networks--id-create 'FooNet)))))
+
+(ert-deftest erc-autojoin-remove--server ()
+ (let (calls
+ erc-autojoin-channels-alist
+ erc-kill-channel-hook erc-kill-server-hook erc-kill-buffer-hook)
+
+ (cl-letf (((symbol-function 'erc-handle-parsed-server-response)
+ (lambda (_p m) (push m calls))))
+
+ (setq erc-autojoin-channels-alist (list '("gnu.chat" "#spam" "##chan")
+ '("fsf.chat" "#bar" "##bar")))
+
+ (ert-with-test-buffer (:name "foonet")
+ (erc-mode)
+ (setq erc-server-process
+ (start-process "true" (current-buffer) "true")
+ erc-server-current-nick "tester"
+ erc-server-announced-name "foo.gnu.chat"
+ ;; Assume special case w/o known network
+ erc-networks--id (make-erc-networks--id))
+ (set-process-query-on-exit-flag erc-server-process nil)
+ (should-not calls)
+
+ (ert-info ("Announced name matched, #chan removed")
+ (erc-parse-server-response erc-server-process
+ ":tester!~i@c.u PART ##chan")
+ (should calls)
+ (erc-autojoin-remove erc-server-process (pop calls))
+ (should (equal erc-autojoin-channels-alist
+ '(("gnu.chat" "#spam")
+ ("fsf.chat" "#bar" "##bar")))))
+
+ (ert-info ("Wrong announced name, nothing done")
+ (erc-parse-server-response erc-server-process
+ ":tester!~i@c.u PART #bar")
+ (should calls)
+ (erc-autojoin-remove erc-server-process (pop calls))
+ (should (equal erc-autojoin-channels-alist
+ '(("gnu.chat" "#spam")
+ ("fsf.chat" "#bar" "##bar")))))))))
+
+;;; erc-join-tests.el ends here
diff --git a/test/lisp/erc/erc-networks-tests.el b/test/lisp/erc/erc-networks-tests.el
new file mode 100644
index 00000000000..66a334b7091
--- /dev/null
+++ b/test/lisp/erc/erc-networks-tests.el
@@ -0,0 +1,1707 @@
+;;; erc-networks-tests.el --- Tests for erc-networks. -*- lexical-binding:t -*-
+
+;; Copyright (C) 2020-2022 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+;;
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published
+;; by the Free Software Foundation, either version 3 of the License,
+;; or (at your option) any later version.
+;;
+;; GNU Emacs is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'ert-x) ; cl-lib
+(require 'erc-networks)
+
+(defun erc-networks-tests--create-dead-proc (&optional buf)
+ (let ((p (start-process "true" (or buf (current-buffer)) "true")))
+ (while (process-live-p p) (sit-for 0.1))
+ p))
+
+(defun erc-networks-tests--create-live-proc (&optional buf)
+ (let ((proc (start-process "sleep" (or buf (current-buffer)) "sleep" "1")))
+ (set-process-query-on-exit-flag proc nil)
+ proc))
+
+;; When we drop 27, call `get-buffer-create with INHIBIT-BUFFER-HOOKS.
+(defun erc-networks-tests--clean-bufs ()
+ (let (erc-kill-channel-hook
+ erc-kill-server-hook
+ erc-kill-buffer-hook)
+ (dolist (buf (erc-buffer-list))
+ (kill-buffer buf))))
+
+(defun erc-networks-tests--bufnames (prefix)
+ (let* ((case-fold-search)
+ (pred (lambda (b) (string-prefix-p prefix (buffer-name b))))
+ (prefixed (seq-filter pred (buffer-list))))
+ (sort (mapcar #'buffer-name prefixed) #'string<)))
+
+(ert-deftest erc-networks--id ()
+ (cl-letf (((symbol-function 'float-time)
+ (lambda (&optional _) 0.0)))
+
+ ;; Fixed
+ (should (equal (erc-networks--id-fixed-create 'foo)
+ (make-erc-networks--id-fixed :ts (float-time)
+ :symbol 'foo)))
+
+ ;; Eliding
+ (let* ((erc-network 'FooNet)
+ (erc-server-current-nick "Joe")
+ (identity (erc-networks--id-create nil)))
+
+ (should (equal identity #s(erc-networks--id-qualifying
+ 0.0 FooNet [FooNet "joe"] 1)))
+ (should (equal (erc-networks--id-qualifying-grow-id identity)
+ 'FooNet/joe))
+ (should (equal identity #s(erc-networks--id-qualifying
+ 0.0 FooNet/joe [FooNet "joe"] 2)))
+ (should-not (erc-networks--id-qualifying-grow-id identity))
+ (should (equal identity #s(erc-networks--id-qualifying
+ 0.0 FooNet/joe [FooNet "joe"] 2))))
+
+ ;; Compat
+ (with-current-buffer (get-buffer-create "fake.chat")
+ (with-suppressed-warnings ((obsolete erc-rename-buffers))
+ (let (erc-rename-buffers)
+ (should (equal (erc-networks--id-create nil)
+ (make-erc-networks--id-fixed :ts (float-time)
+ :symbol 'fake.chat)))))
+ (kill-buffer))))
+
+(ert-deftest erc-networks--id-create ()
+ (cl-letf (((symbol-function 'float-time)
+ (lambda (&optional _) 0.0)))
+
+ (should (equal (erc-networks--id-create 'foo)
+ (make-erc-networks--id-fixed :ts (float-time)
+ :symbol 'foo)))
+ (should (equal (erc-networks--id-create "foo")
+ (make-erc-networks--id-fixed :ts (float-time)
+ :symbol 'foo)))
+ (should (equal (erc-networks--id-create [h i])
+ (make-erc-networks--id-fixed :ts (float-time)
+ :symbol (quote \[h\ \i\]))))
+
+ (with-current-buffer (get-buffer-create "foo")
+ (let ((expected (make-erc-networks--id-fixed :ts (float-time)
+ :symbol 'foo)))
+ (with-suppressed-warnings ((obsolete erc-rename-buffers))
+ (let (erc-rename-buffers)
+ (should (equal (erc-networks--id-create nil) expected))))
+ (with-suppressed-warnings ((obsolete erc-reuse-buffers))
+ (let (erc-reuse-buffers)
+ (should (equal (erc-networks--id-create nil) expected))
+ (should (equal (erc-networks--id-create 'bar) expected)))))
+ (kill-buffer))))
+
+(ert-deftest erc-networks--id-qualifying-prefix-length ()
+ (should-not (erc-networks--id-qualifying-prefix-length
+ (make-erc-networks--id-qualifying)
+ (make-erc-networks--id-qualifying)))
+
+ (should-not (erc-networks--id-qualifying-prefix-length
+ (make-erc-networks--id-qualifying :parts [1 2])
+ (make-erc-networks--id-qualifying :parts [2 3])))
+
+ (should (= 1 (erc-networks--id-qualifying-prefix-length
+ (make-erc-networks--id-qualifying :parts [1])
+ (make-erc-networks--id-qualifying :parts [1 2]))))
+
+ (should (= 1 (erc-networks--id-qualifying-prefix-length
+ (make-erc-networks--id-qualifying :parts [1 2])
+ (make-erc-networks--id-qualifying :parts [1 3]))))
+
+ (should (= 2 (erc-networks--id-qualifying-prefix-length
+ (make-erc-networks--id-qualifying :parts [1 2])
+ (make-erc-networks--id-qualifying :parts [1 2]))))
+
+ (should (= 1 (erc-networks--id-qualifying-prefix-length
+ (make-erc-networks--id-qualifying :parts ["1"])
+ (make-erc-networks--id-qualifying :parts ["1"])))))
+
+(ert-deftest erc-networks--id-sort-buffers ()
+ (let (oldest middle newest)
+
+ (with-temp-buffer
+ (setq erc-networks--id (erc-networks--id-fixed-create 'oldest)
+ oldest (current-buffer))
+
+ (with-temp-buffer
+ (setq erc-networks--id (erc-networks--id-fixed-create 'middle)
+ middle (current-buffer))
+
+ (with-temp-buffer
+ (setq erc-networks--id (erc-networks--id-fixed-create 'newest)
+ newest (current-buffer))
+
+ (should (equal (erc-networks--id-sort-buffers
+ (list oldest newest middle))
+ (list newest middle oldest))))))))
+
+(ert-deftest erc-networks-rename-surviving-target-buffer--channel ()
+ (should (memq #'erc-networks-rename-surviving-target-buffer
+ erc-kill-channel-hook))
+
+ (let ((chan-foonet-buffer (get-buffer-create "#chan@foonet")))
+
+ (with-current-buffer chan-foonet-buffer
+ (erc-mode)
+ (setq erc-networks--id (make-erc-networks--id-qualifying
+ :parts [foonet "bob"] :len 1)
+ erc--target (erc--target-from-string "#chan")))
+
+ (with-current-buffer (get-buffer-create "#chan@barnet")
+ (erc-mode)
+ (setq erc-networks--id (make-erc-networks--id-qualifying
+ :parts [barnet "bob"] :len 1)
+ erc--target (erc--target-from-string "#chan")))
+
+ (kill-buffer "#chan@barnet")
+ (should (equal (erc-networks-tests--bufnames "#chan") '("#chan")))
+ (should (eq chan-foonet-buffer (get-buffer "#chan"))))
+
+ (erc-networks-tests--clean-bufs))
+
+(ert-deftest erc-networks-rename-surviving-target-buffer--query ()
+ (should (memq #'erc-networks-rename-surviving-target-buffer
+ erc-kill-buffer-hook))
+
+ (let ((bob-foonet (get-buffer-create "bob@foonet")))
+
+ (with-current-buffer bob-foonet
+ (erc-mode)
+ (setq erc-networks--id (make-erc-networks--id-qualifying
+ :parts [foonet "bob"] :len 1)
+ erc--target (erc--target-from-string "bob")))
+
+ (with-current-buffer (get-buffer-create "bob@barnet")
+ (erc-mode)
+ (setq erc-networks--id (make-erc-networks--id-qualifying
+ :parts [barnet "bob"] :len 1)
+ erc--target (erc--target-from-string "bob")))
+
+ (kill-buffer "bob@barnet")
+ (should (equal (erc-networks-tests--bufnames "bob") '("bob")))
+ (should (eq bob-foonet (get-buffer "bob"))))
+
+ (erc-networks-tests--clean-bufs))
+
+(ert-deftest erc-networks-rename-surviving-target-buffer--multi ()
+
+ (ert-info ("Multiple leftover channels untouched")
+ (with-current-buffer (get-buffer-create "#chan@foonet")
+ (erc-mode)
+ (setq erc--target (erc--target-from-string "#chan")))
+ (with-current-buffer (get-buffer-create "#chan@barnet")
+ (erc-mode)
+ (setq erc--target (erc--target-from-string "#chan")))
+ (with-current-buffer (get-buffer-create "#chan@baznet")
+ (erc-mode)
+ (setq erc--target (erc--target-from-string "#chan")))
+ (kill-buffer "#chan@baznet")
+ (should (equal (erc-networks-tests--bufnames "#chan")
+ '("#chan@barnet" "#chan@foonet")))
+ (erc-networks-tests--clean-bufs))
+
+ (ert-info ("Multiple leftover queries untouched")
+ (with-current-buffer (get-buffer-create "bob@foonet")
+ (erc-mode)
+ (setq erc--target (erc--target-from-string "bob")))
+ (with-current-buffer (get-buffer-create "bob@barnet")
+ (erc-mode)
+ (setq erc--target (erc--target-from-string "bob")))
+ (with-current-buffer (get-buffer-create "bob@baznet")
+ (erc-mode)
+ (setq erc--target (erc--target-from-string "bob")))
+ (kill-buffer "bob@baznet")
+ (should (equal (erc-networks-tests--bufnames "bob")
+ '("bob@barnet" "bob@foonet")))
+ (erc-networks-tests--clean-bufs)))
+
+;; As of May 2022, this "shrink" stuff runs whenever an ERC buffer is
+;; killed because `erc-networks-shrink-ids-and-buffer-names' is a
+;; default member of all three erc-kill-* functions.
+
+;; Note: this overlaps a fair bit with the "hook" variants, i.e.,
+;; `erc-networks--shrink-ids-and-buffer-names--hook-outstanding-*' If
+;; this ever fails, just delete this and fix those. But please copy
+;; over and adapt the comments first.
+
+(ert-deftest erc-networks--shrink-ids-and-buffer-names--perform-outstanding ()
+ ;; While some buffer #a@barnet/dummy is being killed, its display ID
+ ;; is not collapsed because collisions still exist.
+ ;;
+ ;; Note that we don't have to set `erc-server-connected' because
+ ;; this function is intentionally connectivity agnostic.
+ (with-current-buffer (get-buffer-create "foonet/tester")
+ (erc-mode)
+ (setq erc-server-current-nick "tester" ; Always set (`erc-open')
+ ;; Set when transport connected
+ erc-server-process (erc-networks-tests--create-live-proc)
+ ;; Both set just before IRC (logically) connected (post MOTD)
+ erc-network 'foonet
+ erc-networks--id (make-erc-networks--id-qualifying
+ :symbol 'foonet/tester
+ :parts [foonet "tester"]
+ :len 2))) ; is/was a plain foonet collision
+
+ ;; Presumably, some server buffer named foonet/dummy was just
+ ;; killed, hence the length 2 display ID.
+
+ ;; A target buffer for chan #a exists for foonet/tester. The
+ ;; precise form of its name should not affect shrinking.
+ (with-current-buffer (get-buffer-create
+ (elt ["#a" "#a@foonet" "#a@foonet/tester"] (random 3)))
+ (erc-mode)
+ (setq erc-server-process (buffer-local-value 'erc-server-process
+ (get-buffer "foonet/tester"))
+ erc-network 'foonet
+ erc-server-current-nick "tester"
+ erc-networks--id (buffer-local-value 'erc-networks--id
+ (get-buffer "foonet/tester"))
+ erc--target (erc--target-from-string "#a")))
+
+ ;; Another network context exists (so we have buffers to iterate
+ ;; over), and it's also part of a collision group.
+ (with-current-buffer (get-buffer-create "barnet/tester")
+ (erc-mode)
+ (setq erc-network 'barnet
+ erc-server-current-nick "tester"
+ erc-networks--id (make-erc-networks--id-qualifying
+ :symbol 'barnet/tester
+ :parts [barnet "tester"]
+ :len 2)
+ erc-server-process (erc-networks-tests--create-live-proc)))
+
+ (with-current-buffer (get-buffer-create "barnet/dummy")
+ (erc-mode)
+ (setq erc-network 'barnet
+ erc-server-current-nick "dummy"
+ erc-networks--id (make-erc-networks--id-qualifying
+ :symbol 'barnet/dummy
+ :parts [barnet "dummy"]
+ :len 2)
+ erc-server-process (erc-networks-tests--create-live-proc)))
+
+ ;; The buffer being killed is not part of the foonet collision
+ ;; group, which contains one display ID eligible for shrinkage.
+ (with-current-buffer (get-buffer-create
+ (elt ["#a@barnet" "#a@barnet/tester"] (random 2)))
+ (erc-mode)
+ (setq erc-network 'barnet
+ erc-server-current-nick "tester"
+ erc-server-process (buffer-local-value 'erc-server-process
+ (get-buffer "barnet/tester"))
+ erc-networks--id (buffer-local-value 'erc-networks--id
+ (get-buffer "barnet/tester"))
+ erc--target (erc--target-from-string "#a")))
+
+ (with-temp-buffer ; doesn't matter what the current buffer is
+ (setq erc-networks--id (make-erc-networks--id-qualifying)) ; mock
+ (erc-networks--shrink-ids-and-buffer-names))
+
+ (should (equal (mapcar #'buffer-name (erc-buffer-list))
+ '("foonet" ; shrunk
+ "#a@foonet" ; shrunk
+ "barnet/tester"
+ "barnet/dummy"
+ "#a@barnet/tester")))
+
+ (erc-networks-tests--clean-bufs))
+
+;; This likewise overlaps with the "hook" variants below. If this
+;; should ever fail, just delete it and optionally fix those.
+
+(ert-deftest erc-networks--shrink-ids-and-buffer-names--perform-collapse ()
+ ;; This is similar to the "outstanding" variant above, but both
+ ;; groups are eligible for renaming, which is abnormal but possible
+ ;; when recovering from some mishap.
+ (with-current-buffer (get-buffer-create "foonet/tester")
+ (erc-mode)
+ (setq erc-network 'foonet
+ erc-server-current-nick "tester"
+ erc-networks--id (make-erc-networks--id-qualifying
+ :symbol 'foonet/tester
+ :parts [foonet "tester"]
+ :len 2)
+ erc-server-process (erc-networks-tests--create-live-proc)))
+
+ (with-current-buffer
+ (get-buffer-create (elt ["#a" "#a@foonet/tester"] (random 2)))
+ (erc-mode)
+ (setq erc-server-process (buffer-local-value 'erc-server-process
+ (get-buffer "foonet/tester"))
+ erc-network 'foonet
+ erc-server-current-nick "tester"
+ erc-networks--id (buffer-local-value 'erc-networks--id
+ (get-buffer "foonet/tester"))
+ erc--target (erc--target-from-string "#a")))
+
+ (with-current-buffer (get-buffer-create "barnet/tester")
+ (erc-mode)
+ (setq erc-network 'barnet
+ erc-server-current-nick "tester"
+ erc-networks--id (make-erc-networks--id-qualifying
+ :symbol 'barnet/tester
+ :parts [barnet "tester"]
+ :len 2)
+ erc-server-process (erc-networks-tests--create-live-proc)))
+
+ (with-current-buffer
+ (get-buffer-create (elt ["#b" "#b@foonet/tester"] (random 2)))
+ (erc-mode)
+ (setq erc-network 'barnet
+ erc-server-current-nick "tester"
+ erc-server-process (buffer-local-value 'erc-server-process
+ (get-buffer "barnet/tester"))
+ erc-networks--id (buffer-local-value 'erc-networks--id
+ (get-buffer "barnet/tester"))
+ erc--target (erc--target-from-string "#b")))
+
+ (with-temp-buffer
+ (setq erc-networks--id (make-erc-networks--id-qualifying))
+ (erc-networks--shrink-ids-and-buffer-names))
+
+ (should (equal (mapcar #'buffer-name (erc-buffer-list))
+ '("foonet" "#a" "barnet" "#b")))
+
+ (erc-networks-tests--clean-bufs))
+
+(defun erc-networks--shrink-ids-and-buffer-names--hook-outstanding-common ()
+
+ (with-current-buffer (get-buffer-create "foonet/tester")
+ (erc-mode)
+ (setq erc-network 'foonet
+ erc-server-current-nick "tester"
+ erc-networks--id (make-erc-networks--id-qualifying
+ :symbol 'foonet/tester
+ :parts [foonet "tester"]
+ :len 2)
+ erc-server-process (erc-networks-tests--create-live-proc)))
+
+ (with-current-buffer (get-buffer-create "#a@foonet/tester")
+ (erc-mode)
+ (setq erc-server-process (buffer-local-value 'erc-server-process
+ (get-buffer "foonet/tester"))
+ erc-network 'foonet
+ erc-server-current-nick "tester"
+ erc-networks--id (buffer-local-value 'erc-networks--id
+ (get-buffer "foonet/tester"))
+ erc--target (erc--target-from-string "#a")))
+
+ (with-current-buffer (get-buffer-create "barnet/tester")
+ (erc-mode)
+ (setq erc-network 'barnet
+ erc-server-current-nick "tester"
+ erc-networks--id (make-erc-networks--id-qualifying
+ :symbol 'barnet/tester
+ :parts [barnet "tester"]
+ :len 2)
+ erc-server-process (erc-networks-tests--create-live-proc)))
+
+ (with-current-buffer (get-buffer-create "barnet/dummy")
+ (erc-mode)
+ (setq erc-network 'barnet
+ erc-server-current-nick "dummy"
+ erc-networks--id (make-erc-networks--id-qualifying
+ :symbol 'barnet/dummy
+ :parts [barnet "dummy"]
+ :len 2)
+ erc-server-process (erc-networks-tests--create-live-proc)))
+
+ (with-current-buffer (get-buffer-create "#a@barnet/tester")
+ (erc-mode)
+ (setq erc-network 'barnet
+ erc-server-current-nick "tester"
+ erc-server-process (buffer-local-value 'erc-server-process
+ (get-buffer "barnet/tester"))
+ erc-networks--id (buffer-local-value 'erc-networks--id
+ (get-buffer "barnet/tester"))
+ erc--target (erc--target-from-string "#a"))))
+
+(ert-deftest erc-networks--shrink-ids-and-buffer-names--hook-outstanding-srv ()
+ (erc-networks--shrink-ids-and-buffer-names--hook-outstanding-common)
+ (with-current-buffer (get-buffer-create "foonet/dummy")
+ (erc-mode)
+ (setq erc-network 'foonet
+ erc-server-current-nick "dummy"
+ erc-networks--id (make-erc-networks--id-qualifying
+ :symbol 'foonet/dummy
+ :parts [foonet "dummy"]
+ :len 2)
+ erc-server-process (erc-networks-tests--create-live-proc))
+ (kill-buffer))
+
+ (should (equal (mapcar #'buffer-name (erc-buffer-list))
+ '("foonet"
+ "#a@foonet"
+ "barnet/tester"
+ "barnet/dummy"
+ "#a@barnet/tester")))
+ (erc-networks-tests--clean-bufs))
+
+(ert-deftest erc-networks--shrink-ids-and-buffer-names--hook-outstanding-tgt ()
+ (erc-networks--shrink-ids-and-buffer-names--hook-outstanding-common)
+ (with-current-buffer (get-buffer-create "#a@foonet/dummy")
+ (erc-mode)
+ (setq erc-network 'foonet
+ erc-server-current-nick "dummy"
+ erc-networks--id (make-erc-networks--id-qualifying
+ :symbol 'foonet/dummy
+ :parts [foonet "dummy"]
+ :len 2)
+ erc--target (erc--target-from-string "#a")
+ erc-server-process (with-temp-buffer
+ (erc-networks-tests--create-dead-proc))))
+
+ (with-current-buffer "#a@foonet/dummy" (kill-buffer))
+
+ ;; Identical to *-server variant above
+ (should (equal (mapcar #'buffer-name (erc-buffer-list))
+ '("foonet"
+ "#a@foonet"
+ "barnet/tester"
+ "barnet/dummy"
+ "#a@barnet/tester")))
+ (erc-networks-tests--clean-bufs))
+
+(ert-deftest erc-networks-rename-surviving-target-buffer--shrink ()
+ (erc-networks--shrink-ids-and-buffer-names--hook-outstanding-common)
+
+ ;; This buffer isn't "#a@foonet" (yet) because the shrink-ids hook
+ ;; hasn't run. However, when it's the rename hook runs, its network
+ ;; id *is* "foonet", not "foonet/tester".
+ (with-current-buffer "#a@foonet/tester" (kill-buffer))
+
+ (should (equal (mapcar #'buffer-name (erc-buffer-list))
+ '("foonet"
+ "barnet/tester"
+ "barnet/dummy"
+ "#a")))
+
+ (erc-networks-tests--clean-bufs))
+
+(ert-deftest erc-networks--shrink-ids-and-buffer-names--server ()
+
+ (with-current-buffer (get-buffer-create "foonet/tester")
+ (erc-mode)
+ (setq erc-network 'foonet
+ erc-server-current-nick "tester"
+ erc-networks--id (make-erc-networks--id-qualifying
+ :symbol 'foonet/tester
+ :parts [foonet "tester"]
+ :len 2)
+ erc-server-process (erc-networks-tests--create-live-proc)))
+
+ (with-current-buffer (get-buffer-create "foonet/dummy")
+ (erc-mode)
+ (setq erc-network 'foonet
+ erc-server-current-nick "dummy"
+ erc-networks--id (make-erc-networks--id-qualifying
+ :symbol 'foonet/dummy
+ :parts [foonet "dummy"]
+ :len 2)
+ erc-server-process (erc-networks-tests--create-dead-proc))
+ (kill-buffer))
+
+ (should (equal (mapcar #'buffer-name (erc-buffer-list)) '("foonet")))
+
+ (erc-networks-tests--clean-bufs))
+
+(defun erc-networks--shrink-ids-and-buffer-names--hook-collapse (check)
+
+ (with-current-buffer (get-buffer-create "foonet/tester")
+ (erc-mode)
+ (setq erc-network 'foonet
+ erc-server-current-nick "tester"
+ erc-networks--id (make-erc-networks--id-qualifying
+ :symbol 'foonet/tester
+ :parts [foonet "tester"]
+ :len 2)
+ erc-server-process (erc-networks-tests--create-live-proc)))
+
+ (with-current-buffer (get-buffer-create "#a@foonet/tester")
+ (erc-mode)
+ (setq erc-server-process (buffer-local-value 'erc-server-process
+ (get-buffer "foonet/tester"))
+ erc-network 'foonet
+ erc-server-current-nick "tester"
+ erc-networks--id (buffer-local-value 'erc-networks--id
+ (get-buffer "foonet/tester"))
+ erc--target (erc--target-from-string "#a")))
+
+ (with-current-buffer (get-buffer-create "barnet/tester")
+ (erc-mode)
+ (setq erc-network 'barnet
+ erc-server-current-nick "tester"
+ erc-networks--id (make-erc-networks--id-qualifying
+ :symbol 'barnet/tester
+ :parts [barnet "tester"]
+ :len 2)
+ erc-server-process (erc-networks-tests--create-live-proc)))
+
+ (with-current-buffer (get-buffer-create "#b@foonet/tester")
+ (erc-mode)
+ (setq erc-network 'barnet
+ erc-server-current-nick "tester"
+ erc-server-process (buffer-local-value 'erc-server-process
+ (get-buffer "barnet/tester"))
+ erc-networks--id (buffer-local-value 'erc-networks--id
+ (get-buffer "barnet/tester"))
+ erc--target (erc--target-from-string "#b")))
+
+ (funcall check)
+
+ (should (equal (mapcar #'buffer-name (erc-buffer-list))
+ '("foonet" "#a" "barnet" "#b")))
+
+ (erc-networks-tests--clean-bufs))
+
+(ert-deftest erc-networks--shrink-ids-and-buffer-names--hook-collapse-server ()
+ (erc-networks--shrink-ids-and-buffer-names--hook-collapse
+ (lambda ()
+ (with-current-buffer (get-buffer-create "foonet/dummy")
+ (erc-mode)
+ (setq erc-network 'foonet
+ erc-server-current-nick "dummy"
+ erc-networks--id (make-erc-networks--id-qualifying
+ :symbol 'foonet/dummy
+ :parts [foonet "dummy"]
+ :len 2)
+ erc-server-process (erc-networks-tests--create-live-proc))
+ (kill-buffer)))))
+
+(ert-deftest erc-networks--shrink-ids-and-buffer-names--hook-collapse-target ()
+ (erc-networks--shrink-ids-and-buffer-names--hook-collapse
+ (lambda ()
+ (with-current-buffer (get-buffer-create "#a@foonet/dummy")
+ (erc-mode)
+ (setq erc-network 'foonet
+ erc-server-current-nick "dummy"
+ erc-networks--id (make-erc-networks--id-qualifying
+ :symbol 'foonet/dummy
+ :parts [foonet "dummy"]
+ :len 2)
+ ;; `erc-kill-buffer-function' uses legacy target detection
+ ;; but falls back on buffer name, so no need for:
+ ;;
+ ;; erc-default-recipients '("#a")
+ ;;
+ erc--target (erc--target-from-string "#a")
+ erc-server-process (with-temp-buffer
+ (erc-networks-tests--create-dead-proc)))
+ (kill-buffer)))))
+
+;; FIXME this test is old and may describe impossible states:
+;; leftover identities being qual-equal but not eq (implies
+;; `erc-networks--reclaim-orphaned-target-buffers' is somehow broken).
+;;
+;; Otherwise, the point of this test is to show that server process
+;; identity does not impact the hunt for duplicates.
+
+(defun erc-tests--prep-erc-networks--reconcile-buffer-names--duplicates (start)
+
+ (with-current-buffer (get-buffer-create "foonet")
+ (erc-mode)
+ (setq erc-network 'foonet
+ erc-server-current-nick "tester"
+ erc-networks--id (erc-networks--id-create nil)
+ erc-server-process (funcall start)))
+
+ (with-current-buffer (get-buffer-create "#chan") ; prior session
+ (erc-mode)
+ (setq erc-server-process (buffer-local-value 'erc-server-process
+ (get-buffer "foonet"))
+ erc--target (erc--target-from-string "#chan")
+ erc-networks--id (erc-networks--id-create nil)))
+
+ (ert-info ("Conflicts not recognized as ERC buffers and not renamed")
+ (get-buffer-create "#chan@foonet")
+ (should (equal (erc-networks-tests--bufnames "#chan")
+ '("#chan" "#chan@foonet"))))
+
+ ;; These are dupes (not "collisions")
+
+ (with-current-buffer "#chan@foonet" ; same proc
+ (erc-mode)
+ (setq erc--target (erc--target-from-string "#chan")
+ erc-network 'foonet
+ erc-server-current-nick "tester"
+ erc-server-process (buffer-local-value 'erc-server-process
+ (get-buffer "foonet"))
+ erc-networks--id (erc-networks--id-create nil)))
+
+ (with-current-buffer (get-buffer-create "#chan@foonet<dead>")
+ (erc-mode)
+ (setq erc--target (erc--target-from-string "#chan")
+ erc-server-process (erc-networks-tests--create-dead-proc)
+ erc-network 'foonet
+ erc-server-current-nick "tester"
+ erc-networks--id (erc-networks--id-create nil)))
+
+ (with-current-buffer (get-buffer-create "#chan@foonet<live>")
+ (erc-mode)
+ (setq erc--target (erc--target-from-string "#chan")
+ erc-server-process (erc-networks-tests--create-live-proc)
+ erc-network 'foonet
+ erc-server-current-nick "tester"
+ erc-networks--id (erc-networks--id-create nil)))
+
+ (let ((created (list (get-buffer "#chan@foonet<live>")
+ (get-buffer "#chan@foonet<dead>")
+ (get-buffer "#chan@foonet"))))
+
+ (with-current-buffer "foonet"
+ (should (string= (erc-networks--reconcile-buffer-names
+ (erc--target-from-string "#chan") erc-networks--id)
+ "#chan")))
+
+ (ert-info ("All buffers considered dupes renamed")
+ (should (equal (erc-networks-tests--bufnames "#chan")
+ '("#chan" "#chan<2>" "#chan<3>" "#chan<4>"))))
+
+ (ert-info ("All buffers renamed from newest to oldest")
+ (should (equal created (list (get-buffer "#chan<2>")
+ (get-buffer "#chan<3>")
+ (get-buffer "#chan<4>"))))))
+
+ (erc-networks-tests--clean-bufs))
+
+(defun erc-tests--prep-erc-networks--reconcile-buffer-names--dupes-given (go)
+
+ ;; The connection's network is discovered before target buffers are
+ ;; created. This shows that the network doesn't matter when only
+ ;; "given" IDs are present.
+ (with-current-buffer (get-buffer-create "oofnet")
+ (erc-mode)
+ (setq erc-networks--id (erc-networks--id-create 'oofnet)
+ erc-network 'foonet
+ erc-server-current-nick "tester"
+ erc-server-process (funcall go)))
+
+ (with-current-buffer (get-buffer-create "#chan") ; prior session
+ (erc-mode)
+ (setq erc-networks--id (erc-networks--id-create 'oofnet)
+ erc-server-process (buffer-local-value 'erc-server-process
+ (get-buffer "oofnet"))
+ erc--target (erc--target-from-string "#chan")))
+
+ (with-current-buffer (get-buffer-create "#chan@oofnet") ;dupe/not collision
+ (erc-mode)
+ (setq erc-networks--id (erc-networks--id-create 'oofnet)
+ erc-server-process (buffer-local-value 'erc-server-process
+ (get-buffer "oofnet"))
+ erc--target (erc--target-from-string "#chan")))
+
+ (with-current-buffer "oofnet"
+ (should (string= (erc-networks--reconcile-buffer-names
+ (erc--target-from-string "#chan") erc-networks--id)
+ "#chan")))
+
+ (ert-info ("All buffers matching target and network renamed")
+ (should (equal (erc-networks-tests--bufnames "#chan")
+ '("#chan" "#chan<2>"))))
+
+ (erc-networks-tests--clean-bufs))
+
+(ert-deftest erc-networks--reconcile-buffer-names--duplicates ()
+ (ert-info ("Process live, no error")
+ (erc-tests--prep-erc-networks--reconcile-buffer-names--duplicates
+ #'erc-networks-tests--create-live-proc))
+
+ (ert-info ("Process live, no error, given ID")
+ (erc-tests--prep-erc-networks--reconcile-buffer-names--dupes-given
+ #'erc-networks-tests--create-live-proc))
+
+ (ert-info ("Process dead")
+ (erc-tests--prep-erc-networks--reconcile-buffer-names--duplicates
+ #'erc-networks-tests--create-dead-proc))
+
+ (ert-info ("Process dead, given ID")
+ (erc-tests--prep-erc-networks--reconcile-buffer-names--dupes-given
+ #'erc-networks-tests--create-dead-proc)))
+
+(defun erc-tests--prep-erc-networks--reconcile-buffer-names--no-srv-buf (check)
+ (let ((foonet-proc (with-temp-buffer
+ (erc-networks-tests--create-dead-proc))))
+ (with-current-buffer (get-buffer-create "barnet")
+ (erc-mode)
+ (setq erc-network 'barnet
+ erc-server-current-nick "tester"
+ erc-networks--id (erc-networks--id-create nil)
+ erc-server-process (erc-networks-tests--create-dead-proc)))
+
+ ;; Different proc and not "qual-equal" (different elts)
+ (with-current-buffer (get-buffer-create "#chan")
+ (erc-mode)
+ (setq erc-network 'foonet
+ erc-server-current-nick "tester"
+ erc-networks--id (erc-networks--id-create nil)
+ erc--target (erc--target-from-string "#chan")
+ erc-server-process foonet-proc))
+ (funcall check)
+ (erc-networks-tests--clean-bufs)))
+
+(ert-deftest erc-networks--reconcile-buffer-names--no-server-buf ()
+ (ert-info ("Existing #chan buffer respected")
+ (erc-tests--prep-erc-networks--reconcile-buffer-names--no-srv-buf
+ (lambda ()
+ (with-current-buffer "barnet"
+ (should (string= (erc-networks--reconcile-buffer-names
+ (erc--target-from-string "#chan") erc-networks--id)
+ "#chan@barnet")))
+ (ert-info ("Existing #chan buffer found and renamed")
+ (should (equal (erc-networks-tests--bufnames "#chan")
+ '("#chan@foonet")))))))
+
+ (ert-info ("Existing #chan buffer")
+ (erc-tests--prep-erc-networks--reconcile-buffer-names--no-srv-buf
+ (lambda ()
+ (with-current-buffer (get-buffer-create "foonet")
+ (erc-mode)
+ (setq erc-network 'foonet
+ erc-server-current-nick "tester"
+ erc-networks--id (erc-networks--id-create nil)
+ erc-server-process (erc-networks-tests--create-dead-proc))
+ (should (string= (erc-networks--reconcile-buffer-names
+ (erc--target-from-string "#chan") erc-networks--id)
+ "#chan")))
+ (ert-info ("Nothing renamed")
+ (should (equal (erc-networks-tests--bufnames "#chan") '("#chan")))))))
+
+ (ert-info ("Existing #chan@foonet and #chan@barnet buffers")
+ (erc-tests--prep-erc-networks--reconcile-buffer-names--no-srv-buf
+ (lambda ()
+ (with-current-buffer "#chan"
+ (rename-buffer "#chan@foonet"))
+ (should-not (get-buffer "#chan@barnet"))
+ (with-current-buffer (get-buffer-create "#chan@barnet")
+ (erc-mode)
+ (setq erc--target (erc--target-from-string "#chan")
+ erc-server-process (buffer-local-value 'erc-server-process
+ (get-buffer "barnet"))
+ erc-networks--id (erc-networks--id-create nil)))
+ (with-current-buffer (get-buffer-create "foonet")
+ (erc-mode)
+ (setq erc-network 'foonet
+ erc-server-current-nick "tester"
+ erc-server-process (erc-networks-tests--create-live-proc)
+ erc-networks--id (erc-networks--id-create nil))
+ (set-process-query-on-exit-flag erc-server-process nil)
+ (should (string= (erc-networks--reconcile-buffer-names
+ (erc--target-from-string "#chan") erc-networks--id)
+ "#chan@foonet")))
+ (ert-info ("Nothing renamed")
+ (should (equal (erc-networks-tests--bufnames "#chan")
+ '("#chan@barnet" "#chan@foonet"))))))))
+
+(defun erc-tests--prep-erc-networks--reconcile-buffer-names--no-srv-buf-given
+ (check)
+ (let ((oofnet-proc (with-temp-buffer
+ (erc-networks-tests--create-dead-proc))))
+
+ (with-current-buffer (get-buffer-create "rabnet")
+ (erc-mode)
+ ;; Again, given name preempts network lookup (unrealistic but
+ ;; highlights priorities)
+ (setq erc-networks--id (erc-networks--id-create 'rabnet)
+ erc-network 'barnet
+ erc-server-current-nick "tester"
+ erc-server-process (erc-networks-tests--create-dead-proc)))
+
+ ;; Identity is not "qual-equal" to above
+ (with-current-buffer (get-buffer-create "#chan")
+ (erc-mode)
+ (setq erc-networks--id (erc-networks--id-create 'oofnet)
+ erc-network 'foonet
+ erc--target (erc--target-from-string "#chan")
+ erc-server-process oofnet-proc))
+ (funcall check)
+ (erc-networks-tests--clean-bufs)))
+
+(ert-deftest erc-networks--reconcile-buffer-names--no-server-buf-given ()
+
+ (ert-info ("Existing #chan buffer respected")
+ (erc-tests--prep-erc-networks--reconcile-buffer-names--no-srv-buf-given
+ (lambda ()
+ (with-current-buffer "rabnet"
+ (should (string= (erc-networks--reconcile-buffer-names
+ (erc--target-from-string "#chan") erc-networks--id)
+ "#chan@rabnet")))
+
+ (ert-info ("Existing #chan buffer found and renamed")
+ (should (equal (erc-networks-tests--bufnames "#chan")
+ '("#chan@oofnet")))))))
+
+ (ert-info ("Existing #chan@oofnet and #chan@rabnet buffers")
+ (erc-tests--prep-erc-networks--reconcile-buffer-names--no-srv-buf-given
+ (lambda ()
+ ;; #chan has already been uniquified (but not grown)
+ (with-current-buffer "#chan" (rename-buffer "#chan@oofnet"))
+ (should-not (get-buffer "#chan@rabnet"))
+
+ (with-current-buffer (get-buffer-create "#chan@rabnet")
+ (erc-mode)
+ (setq erc--target (erc--target-from-string "#chan")
+ erc-server-process (buffer-local-value 'erc-server-process
+ (get-buffer "rabnet"))
+ erc-networks--id (buffer-local-value 'erc-networks--id
+ (get-buffer "rabnet"))))
+
+ (with-current-buffer (get-buffer-create "oofnet")
+ (erc-mode)
+ (setq erc-network 'oofnet
+ erc-server-current-nick "tester"
+ erc-server-process (erc-networks-tests--create-live-proc)
+ erc-networks--id (erc-networks--id-create 'oofnet)) ; given
+ (set-process-query-on-exit-flag erc-server-process nil)
+ (should (string= (erc-networks--reconcile-buffer-names
+ (erc--target-from-string "#chan") erc-networks--id)
+ "#chan@oofnet")))
+
+ (ert-info ("Nothing renamed")
+ (should (equal (erc-networks-tests--bufnames "#chan")
+ '("#chan@oofnet" "#chan@rabnet"))))))))
+
+;; This shows a corner case where a user explicitly assigns a "given"
+;; ID via `erc-tls' but later connects again without one. It would
+;; actually probably be better if the given identity were to win and
+;; the derived one got an <n>-suffix.
+;;
+;; If we just compared net identities, the two would match, but they
+;; don't here because one has a given name and the other a
+;; discovered/assembled one; so they are *not* qual-equal.
+(ert-deftest erc-networks--reconcile-buffer-names--no-srv-buf-given-mismatch ()
+ ;; Existing #chan buffer *not* respected
+ (erc-tests--prep-erc-networks--reconcile-buffer-names--no-srv-buf-given
+ (lambda ()
+ (with-current-buffer (get-buffer-create "oofnet")
+ (erc-mode)
+ (setq erc-network 'oofnet
+ erc-server-current-nick "tester"
+ erc-server-process (erc-networks-tests--create-dead-proc)
+ erc-networks--id (erc-networks--id-create nil)) ; derived
+ (should (string= (erc-networks--reconcile-buffer-names
+ (erc--target-from-string "#chan") erc-networks--id)
+ "#chan@oofnet")))
+
+ (ert-info ("Collision renamed but not grown (because it's a given)")
+ ;; Original chan uniquified and moved out of the way
+ (should (equal (erc-networks-tests--bufnames "#chan")
+ '("#chan@oofnet<2>")))))))
+
+(defun erc-tests--prep-erc-networks--reconcile-buffer-names--multi-net (check)
+
+ (with-current-buffer (get-buffer-create "foonet")
+ (erc-mode)
+ (setq erc-network 'foonet
+ erc-server-current-nick "tester"
+ erc-server-process (erc-networks-tests--create-dead-proc)
+ erc-networks--id (erc-networks--id-create nil))) ; derived
+
+ (with-current-buffer (get-buffer-create "barnet")
+ (erc-mode)
+ (setq erc-network 'barnet
+ erc-server-current-nick "tester"
+ erc-server-process (erc-networks-tests--create-dead-proc)
+ erc-networks--id (erc-networks--id-create nil))) ; derived
+
+ (with-current-buffer
+ (get-buffer-create (elt ["#chan" "#chan@foonet"] (random 2)))
+ (erc-mode)
+ (setq erc--target (erc--target-from-string "#chan"))
+ (cl-multiple-value-setq (erc-server-process erc-networks--id)
+ (with-current-buffer "foonet"
+ (list erc-server-process erc-networks--id))))
+
+ (with-current-buffer (get-buffer-create "#chan@barnet")
+ (erc-mode)
+ (setq erc--target (erc--target-from-string "#chan"))
+ (cl-multiple-value-setq (erc-server-process erc-networks--id)
+ (with-current-buffer "barnet"
+ (list erc-server-process erc-networks--id))))
+
+ (funcall check)
+ (erc-networks-tests--clean-bufs))
+
+(ert-deftest erc-networks--reconcile-buffer-names--multi-net ()
+ (ert-info ("Same network rename")
+ (erc-tests--prep-erc-networks--reconcile-buffer-names--multi-net
+ (lambda ()
+ (with-current-buffer "foonet"
+ (let ((result (erc-networks--reconcile-buffer-names
+ (erc--target-from-string "#chan") erc-networks--id)))
+ (should (string= result "#chan@foonet"))))
+
+ (should (equal (erc-networks-tests--bufnames "#chan")
+ '("#chan@barnet" "#chan@foonet"))))))
+
+ (ert-info ("Same network keep name")
+ (erc-tests--prep-erc-networks--reconcile-buffer-names--multi-net
+ (lambda ()
+ (with-current-buffer "barnet"
+ (let ((result (erc-networks--reconcile-buffer-names
+ (erc--target-from-string "#chan") erc-networks--id)))
+ (should (string= result "#chan@barnet"))))
+
+ (should (equal (erc-networks-tests--bufnames "#chan")
+ '("#chan@barnet" "#chan@foonet")))))))
+
+(defun erc-tests--prep-erc-networks--reconcile-buffer-names--multi-net-given
+ (check)
+
+ (with-current-buffer (get-buffer-create "oofnet")
+ (erc-mode)
+ (setq erc-network 'foonet
+ erc-server-current-nick "tester"
+ erc-networks--id (erc-networks--id-create 'oofnet) ; one given
+ erc-server-process (erc-networks-tests--create-dead-proc)))
+
+ (with-current-buffer (get-buffer-create "rabnet")
+ (erc-mode)
+ (setq erc-network 'barnet
+ erc-server-current-nick "tester"
+ erc-networks--id (erc-networks--id-create 'rabnet) ; another given
+ erc-server-process (erc-networks-tests--create-dead-proc)))
+
+ (with-current-buffer (get-buffer-create (elt ["chan" "#chan@oofnet"]
+ (random 2)))
+ (erc-mode)
+ (setq erc--target (erc--target-from-string "#chan"))
+ (cl-multiple-value-setq (erc-server-process erc-networks--id)
+ (with-current-buffer "oofnet"
+ (list erc-server-process erc-networks--id))))
+
+ (with-current-buffer (get-buffer-create "#chan@barnet")
+ (erc-mode)
+ (setq erc--target (erc--target-from-string "#chan"))
+ (cl-multiple-value-setq (erc-server-process erc-networks--id)
+ (with-current-buffer "rabnet"
+ (list erc-server-process erc-networks--id))))
+
+ (funcall check)
+ (erc-networks-tests--clean-bufs))
+
+(ert-deftest erc-networks--reconcile-buffer-names--multi-net-given ()
+ (ert-info ("Same network rename")
+ (erc-tests--prep-erc-networks--reconcile-buffer-names--multi-net-given
+ (lambda ()
+ (with-current-buffer "oofnet"
+ (let ((result (erc-networks--reconcile-buffer-names
+ (erc--target-from-string "#chan") erc-networks--id)))
+ (should (string= result "#chan@oofnet"))))
+
+ (should (equal (erc-networks-tests--bufnames "#chan")
+ '("#chan@oofnet" "#chan@rabnet"))))))
+
+ (ert-info ("Same network keep name")
+ (erc-tests--prep-erc-networks--reconcile-buffer-names--multi-net-given
+ (lambda ()
+ (with-current-buffer "rabnet"
+ (let ((result (erc-networks--reconcile-buffer-names
+ (erc--target-from-string "#chan") erc-networks--id)))
+ (should (string= result "#chan@rabnet"))))
+
+ (should (equal (erc-networks-tests--bufnames "#chan")
+ '("#chan@oofnet" "#chan@rabnet")))))))
+
+(defun erc-tests--prep-erc-networks--reconcile-buffer-names--multi-net-mixed
+ (check)
+
+ (with-current-buffer (get-buffer-create "foonet")
+ (erc-mode)
+ (setq erc-network 'foonet
+ erc-server-current-nick "tester"
+ erc-networks--id (erc-networks--id-create nil) ; one derived
+ erc-server-process (erc-networks-tests--create-dead-proc)))
+
+ (with-current-buffer (get-buffer-create "my-conn")
+ (erc-mode)
+ (setq erc-network 'barnet
+ erc-server-current-nick "tester"
+ erc-networks--id (erc-networks--id-create 'my-conn) ; one given
+ erc-server-process (erc-networks-tests--create-dead-proc)))
+
+ (with-current-buffer (get-buffer-create (elt ["#chan" "#chan@foonet"]
+ (random 2)))
+ (erc-mode)
+ (setq erc--target (erc--target-from-string "#chan"))
+ (cl-multiple-value-setq (erc-server-process erc-networks--id)
+ (with-current-buffer "foonet"
+ (list erc-server-process erc-networks--id))))
+
+ (with-current-buffer (get-buffer-create "#chan@my-conn")
+ (erc-mode)
+ (setq erc--target (erc--target-from-string "#chan"))
+ (cl-multiple-value-setq (erc-server-process erc-networks--id)
+ (with-current-buffer "my-conn"
+ (list erc-server-process erc-networks--id))))
+
+ (funcall check)
+ (erc-networks-tests--clean-bufs))
+
+(ert-deftest erc-networks--reconcile-buffer-names--multi-net-existing ()
+
+ (ert-info ("Buf name derived from network")
+ (erc-tests--prep-erc-networks--reconcile-buffer-names--multi-net-mixed
+ (lambda ()
+ (with-current-buffer "foonet"
+ (let ((result (erc-networks--reconcile-buffer-names
+ (erc--target-from-string "#chan") erc-networks--id)))
+ (should (string= result "#chan@foonet"))))
+
+ (should (equal (erc-networks-tests--bufnames "#chan")
+ '("#chan@foonet" "#chan@my-conn"))))))
+
+ (ert-info ("Buf name given")
+ (erc-tests--prep-erc-networks--reconcile-buffer-names--multi-net-mixed
+ (lambda ()
+ (with-current-buffer "my-conn"
+ (let ((result (erc-networks--reconcile-buffer-names
+ (erc--target-from-string "#chan") erc-networks--id)))
+ (should (string= result "#chan@my-conn"))))
+
+ (should (equal (erc-networks-tests--bufnames "#chan")
+ '("#chan@foonet" "#chan@my-conn")))))))
+
+(ert-deftest erc-networks--reconcile-buffer-names--multi-net-suffixed ()
+ ;; Two networks, same channel. One network has two connections.
+ ;; When the same channel is joined on the latter under a different
+ ;; nick, all buffer names involving that network are suffixed with
+ ;; the network identity.
+
+ (with-current-buffer (get-buffer-create "foonet/bob")
+ (erc-mode)
+ (setq erc-network 'foonet
+ erc-server-current-nick "bob"
+ erc-networks--id (make-erc-networks--id-qualifying
+ :symbol 'foonet/bob
+ :parts [foonet "bob"]
+ :len 2)
+ erc-server-process (erc-networks-tests--create-live-proc)))
+
+ (with-current-buffer (get-buffer-create
+ (elt ["#chan@foonet" "#chan@foonet/bob"] (random 2)))
+ (erc-mode)
+ (setq erc--target (erc--target-from-string "#chan")
+ erc-server-process (buffer-local-value 'erc-server-process
+ (get-buffer "foonet/bob"))
+ erc-networks--id (buffer-local-value 'erc-networks--id
+ (get-buffer "foonet/bob"))))
+
+ (with-current-buffer (get-buffer-create "barnet")
+ (erc-mode)
+ (setq erc-network 'barnet
+ erc-server-current-nick (elt ["alice" "bob"] (random 2))
+ erc-networks--id (erc-networks--id-create 'barnet)
+ erc-server-process (erc-networks-tests--create-live-proc)))
+
+ (with-current-buffer (get-buffer-create "#chan@barnet")
+ (erc-mode)
+ (setq erc--target (erc--target-from-string "#chan")
+ erc-server-process (buffer-local-value 'erc-server-process
+ (get-buffer "barnet"))
+ erc-networks--id (buffer-local-value 'erc-networks--id
+ (get-buffer "barnet"))))
+
+ (with-current-buffer (get-buffer-create "foonet/alice")
+ (erc-mode)
+ (setq erc-network 'foonet
+ erc-server-current-nick "alice"
+ erc-networks--id (make-erc-networks--id-qualifying
+ :symbol 'foonet/alice
+ :parts [foonet "alice"]
+ :len 2)
+ erc-server-process (erc-networks-tests--create-live-proc)))
+
+ (with-current-buffer "foonet/alice"
+ (let ((result (erc-networks--reconcile-buffer-names
+ (erc--target-from-string "#chan") erc-networks--id)))
+ (should (string= result "#chan@foonet/alice"))))
+
+ (should (equal (erc-networks-tests--bufnames "#chan")
+ '("#chan@barnet" "#chan@foonet/bob")))
+
+ (erc-networks-tests--clean-bufs))
+
+(ert-deftest erc-networks--reconcile-buffer-names--local ()
+ (with-current-buffer (get-buffer-create "DALnet")
+ (erc-mode)
+ (setq erc-network 'DALnet
+ erc-server-announced-name "elysium.ga.us.dal.net"
+ erc-server-process (erc-networks-tests--create-dead-proc)
+ erc--isupport-params (make-hash-table)
+ erc-networks--id (erc-networks--id-create nil))
+ (puthash 'CHANTYPES '("&#") erc--isupport-params))
+
+ (ert-info ("Local chan buffer from older, disconnected identity")
+ (with-current-buffer (get-buffer-create "&chan")
+ (erc-mode)
+ ;; Cheat here because localp is determined on identity init
+ (setq erc--target (with-current-buffer "DALnet"
+ (erc--target-from-string "&chan"))
+ erc-network 'DALnet
+ erc-server-announced-name "twisted.ma.us.dal.net"
+ erc-server-process (erc-networks-tests--create-dead-proc)
+ erc-networks--id (erc-networks--id-create nil))))
+
+ (ert-info ("Local channels renamed using network server names")
+ (with-current-buffer "DALnet"
+ (let ((result (erc-networks--reconcile-buffer-names
+ (erc--target-from-string "&chan") erc-networks--id)))
+ (should (string= result "&chan@elysium.ga.us.dal.net")))))
+
+ (should (get-buffer "&chan@twisted.ma.us.dal.net"))
+ (should-not (get-buffer "&chan"))
+ (erc-networks-tests--clean-bufs))
+
+(ert-deftest erc-networks--set-name ()
+ (with-current-buffer (get-buffer-create "localhost:6667")
+ (let (erc-server-announced-name
+ (erc--isupport-params (make-hash-table))
+ erc-network
+ calls)
+ (erc-mode)
+
+ (cl-letf (((symbol-function 'erc-display-line)
+ (lambda (&rest r) (push r calls))))
+
+ (ert-info ("Signals when `erc-server-announced-name' unset")
+ (should-error (erc-networks--set-name nil (make-erc-response)))
+ (should-not calls))
+
+ (ert-info ("Signals when table empty and NETWORK param unset")
+ (setq erc-server-announced-name "irc.fake.gnu.org")
+ (let ((err (should-error (erc-networks--set-name
+ nil (make-erc-response)))))
+ (should (string-match-p "failed" (cadr err)))
+ (should (eq (car err) 'error)))
+ (should (string-match-p (rx "*** Failed") (car (pop calls)))))))
+
+ (erc-networks-tests--clean-bufs)))
+
+(ert-deftest erc-networks--ensure-announced ()
+ (with-current-buffer (get-buffer-create "localhost:6667")
+ (should (local-variable-if-set-p 'erc-server-announced-name))
+ (let (erc-insert-modify-hook
+ (erc-server-process (erc-networks-tests--create-live-proc))
+ (parsed (make-erc-response
+ :unparsed ":irc.barnet.org 422 tester :MOTD File is missing"
+ :sender "irc.barnet.org"
+ :command "422"
+ :command-args '("tester" "MOTD File is missing")
+ :contents "MOTD File is missing")))
+
+ (erc-mode) ; boilerplate displayable start (needs `erc-server-process')
+ (insert "\n\n")
+ (setq erc-input-marker (make-marker) erc-insert-marker (make-marker))
+ (set-marker erc-insert-marker (point-max))
+ (erc-display-prompt) ; boilerplate displayable end
+
+ (erc-networks--ensure-announced erc-server-process parsed)
+ (goto-char (point-min))
+ (search-forward "Failed")
+ (should (string= erc-server-announced-name "irc.barnet.org")))
+ (when noninteractive (kill-buffer))))
+
+(ert-deftest erc-networks--rename-server-buffer--no-existing--orphan ()
+ (with-current-buffer (get-buffer-create "#chan")
+ (erc-mode)
+ (setq erc-network 'FooNet
+ erc-server-current-nick "tester"
+ erc--target (erc--target-from-string "#chan")
+ erc-networks--id (erc-networks--id-create nil)))
+
+ (with-current-buffer (get-buffer-create "irc.foonet.org")
+ (erc-mode)
+ (setq erc-network 'FooNet
+ erc-server-current-nick "tester"
+ erc-server-process (erc-networks-tests--create-live-proc)
+ erc-networks--id (erc-networks--id-create nil))
+ (should-not (erc-networks--rename-server-buffer erc-server-process))
+ (should (string= (buffer-name) "FooNet")))
+
+ (ert-info ("Channel buffer reassociated")
+ (erc-server-process-alive "#chan")
+ (with-current-buffer "#chan"
+ (should erc-server-connected)
+ (erc-with-server-buffer
+ (should (string= (buffer-name) "FooNet")))))
+
+ (erc-networks-tests--clean-bufs))
+
+(ert-deftest erc-networks--rename-server-buffer--existing--reuse ()
+ (let* ((old-buf (get-buffer-create "FooNet"))
+ (old-proc (erc-networks-tests--create-dead-proc old-buf)))
+
+ (with-current-buffer old-buf
+ (erc-mode)
+ (insert "*** Old buf")
+ (setq erc-network 'FooNet
+ erc-server-current-nick "tester"
+ erc-insert-marker (set-marker (make-marker) (point-max))
+ erc-server-process old-proc
+ erc-networks--id (erc-networks--id-create nil)))
+
+ (with-current-buffer (get-buffer-create "#chan")
+ (erc-mode)
+ (setq erc-network 'FooNet
+ erc-server-process old-proc
+ erc-networks--id (erc-networks--id-create nil)
+ erc--target (erc--target-from-string "#chan")))
+
+ (ert-info ("New buffer steals name, content")
+ (with-current-buffer (get-buffer-create "irc.foonet.org")
+ (erc-mode)
+ (setq erc-network 'FooNet
+ erc-server-current-nick "tester"
+ erc-server-process (erc-networks-tests--create-live-proc)
+ erc-networks--id (erc-networks--id-create nil))
+ (should-not (erc-networks--rename-server-buffer erc-server-process))
+ (should (string= (buffer-name) "FooNet"))
+ (goto-char (point-min))
+ (should (search-forward "Old buf"))))
+
+ (ert-info ("Channel buffer reassociated")
+ (erc-server-process-alive "#chan")
+ (with-current-buffer "#chan"
+ (should erc-server-connected)
+ (should-not (eq erc-server-process old-proc))
+ (erc-with-server-buffer
+ (should (string= (buffer-name) "FooNet")))))
+
+ (ert-info ("Original buffer killed off")
+ (should-not (buffer-live-p old-buf))))
+
+ (erc-networks-tests--clean-bufs))
+
+;; This is for compatibility with pre-28.1 behavior. Basically, we're
+;; trying to match the behavior bug for bug. All buffers were always
+;; suffixed and never reassociated. 28.1 introduced a regression that
+;; reversed the latter, but we've reverted that.
+
+(ert-deftest erc-networks--rename-server-buffer--existing--noreuse ()
+ (with-suppressed-warnings ((obsolete erc-reuse-buffers))
+ (should erc-reuse-buffers) ; default
+ (let* ((old-buf (get-buffer-create "irc.foonet.org:6697/irc.foonet.org"))
+ (old-proc (erc-networks-tests--create-dead-proc old-buf))
+ erc-reuse-buffers)
+ (with-current-buffer old-buf
+ (erc-mode)
+ (insert "*** Old buf")
+ (setq erc-network 'FooNet
+ erc-server-current-nick "tester"
+ erc-insert-marker (set-marker (make-marker) (point-max))
+ erc-server-process old-proc
+ erc-networks--id (erc-networks--id-create nil)))
+ (with-current-buffer (get-buffer-create "#chan")
+ (erc-mode)
+ (setq erc-network 'FooNet
+ erc-server-process old-proc
+ erc-networks--id (buffer-local-value 'erc-networks--id old-buf)
+ erc--target (erc--target-from-string "#chan"))
+ (rename-buffer (erc-networks--construct-target-buffer-name erc--target)))
+
+ (ert-info ("Server buffer uniquely renamed")
+ (with-current-buffer
+ (get-buffer-create "irc.foonet.org:6697/irc.foonet.org<2>")
+ (erc-mode)
+ (setq erc-network 'FooNet
+ erc-server-current-nick "tester"
+ erc-server-process (erc-networks-tests--create-live-proc)
+ erc-networks--id (erc-networks--id-create nil))
+ (should-not (erc-networks--rename-server-buffer erc-server-process))
+ (should (string= (buffer-name)
+ "irc.foonet.org:6697/irc.foonet.org<2>"))
+ (goto-char (point-min))
+ (should-not (search-forward "Old buf" nil t))))
+
+ (ert-info ("Channel buffer not reassociated")
+ (should-not
+ (erc-server-process-alive
+ (should (get-buffer "#chan/irc.foonet.org"))))
+ (with-current-buffer (get-buffer "#chan/irc.foonet.org")
+ (should-not erc-server-connected)
+ (should (eq erc-server-process old-proc))
+ (erc-with-server-buffer
+ (should (string= (buffer-name)
+ "irc.foonet.org:6697/irc.foonet.org")))))
+
+ (ert-info ("Old buffer still around")
+ (should (buffer-live-p old-buf)))))
+ (erc-networks-tests--clean-bufs))
+
+(ert-deftest erc-networks--rename-server-buffer--reconnecting ()
+ (let* ((old-buf (get-buffer-create "FooNet"))
+ (old-proc (erc-networks-tests--create-dead-proc old-buf)))
+
+ (with-current-buffer old-buf
+ (erc-mode)
+ (insert "*** Old buf")
+ (setq erc-network 'FooNet
+ erc-server-current-nick "tester"
+ erc-insert-marker (set-marker (make-marker) (point-max))
+ erc-server-process old-proc
+ erc-networks--id (erc-networks--id-create nil)))
+
+ (with-current-buffer (get-buffer-create "#chan")
+ (erc-mode)
+ (setq erc-network 'FooNet
+ erc-server-process old-proc
+ erc--target (erc--target-from-string "#chan")
+ erc-networks--id (erc-networks--id-create nil)))
+
+ (ert-info ("No new buffer")
+ (with-current-buffer old-buf
+ (setq erc-server-process (erc-networks-tests--create-live-proc))
+ (should-not (erc-networks--rename-server-buffer erc-server-process))
+ (should (string= (buffer-name) "FooNet"))
+ (goto-char (point-min))
+ (should (search-forward "Old buf"))))
+
+ (ert-info ("Channel buffer updated with live proc")
+ (erc-server-process-alive "#chan")
+ (with-current-buffer "#chan"
+ (should erc-server-connected)
+ (should-not (eq erc-server-process old-proc))
+ (erc-with-server-buffer
+ (should (string= (buffer-name) "FooNet"))))))
+
+ (erc-networks-tests--clean-bufs))
+
+(ert-deftest erc-networks--rename-server-buffer--id ()
+ (let* ((old-buf (get-buffer-create "MySession"))
+ (old-proc (erc-networks-tests--create-dead-proc old-buf)))
+
+ (with-current-buffer old-buf
+ (erc-mode)
+ (insert "*** Old buf")
+ (setq erc-network 'FooNet
+ erc-networks--id (erc-networks--id-create 'MySession)
+ erc-insert-marker (set-marker (make-marker) (point-max))
+ erc-server-process old-proc))
+
+ (with-current-buffer (get-buffer-create "#chan")
+ (erc-mode)
+ (setq erc-network 'FooNet
+ erc-networks--id (erc-networks--id-create 'MySession)
+ erc-server-process old-proc
+ erc--target (erc--target-from-string "#chan")))
+
+ (ert-info ("No new buffer")
+ (with-current-buffer old-buf
+ (setq erc-server-process (erc-networks-tests--create-live-proc))
+ (should-not (erc-networks--rename-server-buffer erc-server-process))
+ (should (string= (buffer-name) "MySession"))
+ (goto-char (point-min))
+ (should (search-forward "Old buf"))))
+
+ (ert-info ("Channel buffer updated with live proc")
+ (erc-server-process-alive "#chan")
+ (with-current-buffer "#chan"
+ (should erc-server-connected)
+ (should-not (eq erc-server-process old-proc))
+ (erc-with-server-buffer
+ (should (string= (buffer-name) "MySession"))))))
+
+ (erc-networks-tests--clean-bufs))
+
+(ert-deftest erc-networks--rename-server-buffer--existing--live ()
+ (let* (erc-kill-server-hook
+ erc-insert-modify-hook
+ (old-buf (get-buffer-create "FooNet"))
+ (old-proc (erc-networks-tests--create-live-proc old-buf))) ; live
+
+ (with-current-buffer old-buf
+ (erc-mode)
+ (insert "*** Old buf")
+ (setq erc-network 'FooNet
+ erc-server-current-nick "tester"
+ erc-insert-marker (set-marker (make-marker) (point-max))
+ erc-server-process old-proc
+ erc-networks--id (erc-networks--id-create nil))
+ (should (erc-server-process-alive)))
+
+ (with-current-buffer (get-buffer-create "#chan")
+ (erc-mode)
+ (setq erc-network 'FooNet
+ erc-server-process old-proc
+ erc-networks--id (erc-networks--id-create nil)
+ erc-server-connected t
+ erc--target (erc--target-from-string "#chan")))
+
+ (ert-info ("New buffer rejected, abandoned, not killed")
+ (with-current-buffer (get-buffer-create "irc.foonet.org")
+ (erc-mode)
+ (setq erc-network 'FooNet
+ erc-server-current-nick "tester"
+ erc-insert-marker (set-marker (make-marker) (point-max))
+ erc-server-process (erc-networks-tests--create-live-proc)
+ erc-networks--id (erc-networks--id-create nil))
+ (should-not (erc-networks--rename-server-buffer erc-server-process))
+ (should (eq erc-active-buffer old-buf))
+ (should-not (erc-server-process-alive))
+ (should (string= (buffer-name) "irc.foonet.org"))
+ (goto-char (point-min))
+ (search-forward "still connected")))
+
+ (ert-info ("Channel buffer updated with live proc")
+ (should (erc-server-process-alive "#chan"))
+ (with-current-buffer "#chan"
+ (should erc-server-connected)
+ (should (erc-server-buffer-live-p))
+ (should (eq erc-server-process old-proc))
+ (should (buffer-live-p (process-buffer erc-server-process)))
+ (with-current-buffer (process-buffer erc-server-process)
+ (should (eq (current-buffer) (get-buffer "FooNet")))
+ (should (eq (current-buffer) old-buf))))))
+
+ (should (get-buffer "FooNet"))
+ (should (get-buffer "irc.foonet.org"))
+
+ (erc-networks-tests--clean-bufs))
+
+(ert-deftest erc-networks--rename-server-buffer--local-match ()
+ (let* ((old-buf (get-buffer-create "FooNet"))
+ (old-proc (erc-networks-tests--create-dead-proc old-buf)))
+
+ (with-current-buffer old-buf
+ (erc-mode)
+ (insert "*** Old buf")
+ (setq erc-network 'FooNet
+ erc-server-current-nick "tester"
+ erc-server-announced-name "us-east.foonet.org"
+ erc-insert-marker (set-marker (make-marker) (point-max))
+ erc-server-process old-proc
+ erc--isupport-params (make-hash-table)
+ erc-networks--id (erc-networks--id-create nil))
+ (puthash 'CHANTYPES '("&#") erc--isupport-params))
+
+ (with-current-buffer (get-buffer-create "&chan")
+ (erc-mode)
+ (setq erc-network 'FooNet
+ erc-server-process old-proc
+ erc-server-announced-name "us-east.foonet.org"
+ erc--target (erc--target-from-string "&chan")
+ erc-networks--id (erc-networks--id-create nil)))
+
+ (ert-info ("New server buffer steals name, content")
+ (with-current-buffer (get-buffer-create "irc.foonet.org")
+ (erc-mode)
+ (setq erc-network 'FooNet
+ erc-server-current-nick "tester"
+ erc-server-announced-name "us-east.foonet.org"
+ erc-server-process (erc-networks-tests--create-live-proc)
+ erc--isupport-params (make-hash-table)
+ erc-networks--id (erc-networks--id-create nil))
+ (puthash 'CHANTYPES '("&#") erc--isupport-params)
+ (should-not (erc-networks--rename-server-buffer erc-server-process))
+ (should (string= (buffer-name) "FooNet"))
+ (goto-char (point-min))
+ (should (search-forward "Old buf"))))
+
+ (ert-info ("Channel buffer reassociated when &local server matches")
+ (should (erc-server-process-alive "&chan"))
+ (with-current-buffer "&chan"
+ (should erc-server-connected)
+ (should-not (eq erc-server-process old-proc))
+ (erc-with-server-buffer
+ (should (string= (buffer-name) "FooNet")))))
+
+ (ert-info ("Original buffer killed off")
+ (should-not (buffer-live-p old-buf)))
+
+ (erc-networks-tests--clean-bufs)))
+
+(ert-deftest erc-networks--rename-server-buffer--local-nomatch ()
+ (let* ((old-buf (get-buffer-create "FooNet"))
+ (old-proc (erc-networks-tests--create-dead-proc old-buf)))
+
+ (with-current-buffer old-buf
+ (erc-mode)
+ (insert "*** Old buf")
+ (setq erc-network 'FooNet
+ erc-server-current-nick "tester"
+ erc-server-announced-name "us-west.foonet.org"
+ erc-insert-marker (set-marker (make-marker) (point-max))
+ erc-server-process old-proc
+ erc--isupport-params (make-hash-table)
+ erc-networks--id (erc-networks--id-create nil))
+ (puthash 'CHANTYPES '("&#") erc--isupport-params))
+
+ (with-current-buffer (get-buffer-create "&chan")
+ (erc-mode)
+ (setq erc-network 'FooNet
+ erc-server-process old-proc
+ erc-server-announced-name "us-west.foonet.org" ; west
+ erc--target (erc--target-from-string "&chan")
+ erc-networks--id (erc-networks--id-create nil)))
+
+ (ert-info ("New server buffer steals name, content")
+ (with-current-buffer (get-buffer-create "irc.foonet.org")
+ (erc-mode)
+ (setq erc-network 'FooNet
+ erc-server-current-nick "tester"
+ erc-server-announced-name "us-east.foonet.org" ; east
+ erc-server-process (erc-networks-tests--create-live-proc)
+ erc--isupport-params (make-hash-table)
+ erc-networks--id (erc-networks--id-create nil))
+
+ (puthash 'CHANTYPES '("&#") erc--isupport-params)
+ (should-not (erc-networks--rename-server-buffer erc-server-process))
+ (should (string= (buffer-name) "FooNet"))
+ (goto-char (point-min))
+ (should (search-forward "Old buf"))))
+
+ (ert-info ("Channel buffer now orphaned even though network matches")
+ (should-not (erc-server-process-alive "&chan"))
+ (with-current-buffer "&chan"
+ (should-not erc-server-connected)
+ (should (eq erc-server-process old-proc))
+ (erc-with-server-buffer
+ (should (string= (buffer-name) "FooNet")))))
+
+ (ert-info ("Original buffer killed off")
+ (should-not (buffer-live-p old-buf)))
+
+ (erc-networks-tests--clean-bufs)))
+
+(ert-deftest erc-networks--update-server-identity--double-existing ()
+ (with-temp-buffer
+ (erc-mode)
+ (setq erc-networks--id (make-erc-networks--id-qualifying
+ :parts [foonet "bob"] :len 1))
+
+ (with-current-buffer (get-buffer-create "#chan@foonet/bob")
+ (erc-mode)
+ (setq erc-networks--id (make-erc-networks--id-qualifying
+ :parts [foonet "bob"] :len 2)))
+ (with-current-buffer (get-buffer-create "foonet/alice")
+ (erc-mode)
+ (setq erc-networks--id
+ (make-erc-networks--id-qualifying :parts [foonet "alice"] :len 2)))
+
+ (ert-info ("Adopt equivalent identity")
+ (should (eq (erc-networks--update-server-identity)
+ (buffer-local-value 'erc-networks--id
+ (get-buffer "#chan@foonet/bob")))))
+
+ (ert-info ("Ignore non-matches")
+ (should-not (erc-networks--update-server-identity))
+ (should (eq erc-networks--id
+ (buffer-local-value 'erc-networks--id
+ (get-buffer "#chan@foonet/bob"))))))
+
+ (erc-networks-tests--clean-bufs))
+
+(ert-deftest erc-networks--update-server-identity--double-new ()
+ (with-temp-buffer
+ (erc-mode)
+ (setq erc-networks--id (make-erc-networks--id-qualifying
+ :parts [foonet "bob"] :len 1))
+
+ (with-current-buffer (get-buffer-create "foonet/alice")
+ (erc-mode)
+ (setq erc-networks--id
+ (make-erc-networks--id-qualifying :parts [foonet "alice"] :len 2)))
+ (with-current-buffer (get-buffer-create "#chan@foonet/alice")
+ (erc-mode)
+ (setq erc-networks--id (buffer-local-value 'erc-networks--id
+ (get-buffer "foonet/alice"))))
+
+ (ert-info ("Evolve identity to prevent ambiguity")
+ (should-not (erc-networks--update-server-identity))
+ (should (= (erc-networks--id-qualifying-len erc-networks--id) 2))
+ (should (eq (erc-networks--id-symbol erc-networks--id) 'foonet/bob))))
+
+ (erc-networks-tests--clean-bufs))
+
+(ert-deftest erc-networks--update-server-identity--double-bounded ()
+ (with-temp-buffer
+ (erc-mode)
+ (setq erc-networks--id (make-erc-networks--id-qualifying
+ :parts [foonet "bob"] :len 1))
+
+ (with-current-buffer (get-buffer-create "foonet/alice/home")
+ (erc-mode)
+ (setq erc-networks--id (make-erc-networks--id-qualifying
+ :parts [foonet "alice" home] :len 3)))
+ (with-current-buffer (get-buffer-create "#chan@foonet/alice/home")
+ (erc-mode)
+ (setq erc-networks--id
+ (buffer-local-value 'erc-networks--id
+ (get-buffer "foonet/alice/home"))))
+
+ (ert-info ("Evolve identity to prevent ambiguity")
+ (should-not (erc-networks--update-server-identity))
+ (should (= (erc-networks--id-qualifying-len erc-networks--id) 2))
+ (should (eq (erc-networks--id-symbol erc-networks--id) 'foonet/bob))))
+
+ (erc-networks-tests--clean-bufs))
+
+(ert-deftest erc-networks--update-server-identity--double-even ()
+ (with-temp-buffer
+ (erc-mode)
+ (setq erc-networks--id
+ (make-erc-networks--id-qualifying :parts [foonet "bob"] :len 1))
+
+ (with-current-buffer (get-buffer-create "foonet")
+ (erc-mode)
+ (setq erc-networks--id
+ (make-erc-networks--id-qualifying :parts [foonet "alice"] :len 1)))
+ (with-current-buffer (get-buffer-create "#chan")
+ (erc-mode)
+ (setq erc--target (erc--target-from-string "#chan")
+ erc-networks--id (buffer-local-value 'erc-networks--id
+ (get-buffer "foonet"))))
+
+ (ert-info ("Evolve identity to prevent ambiguity")
+ (should-not (erc-networks--update-server-identity))
+ (should (= (erc-networks--id-qualifying-len erc-networks--id) 2))
+ (should (eq (erc-networks--id-symbol erc-networks--id) 'foonet/bob)))
+
+ (ert-info ("Collision renamed")
+ (with-current-buffer "foonet/alice"
+ (should (eq (erc-networks--id-symbol erc-networks--id) 'foonet/alice)))
+
+ (with-current-buffer "#chan@foonet/alice"
+ (should (eq (erc-networks--id-symbol erc-networks--id)
+ 'foonet/alice)))))
+
+ (erc-networks-tests--clean-bufs))
+
+(ert-deftest erc-networks--update-server-identity--triple-new ()
+ (with-temp-buffer
+ (erc-mode)
+ (setq erc-networks--id
+ (make-erc-networks--id-qualifying :parts [foonet "bob" home] :len 1))
+
+ (with-current-buffer (get-buffer-create "foonet/bob/office")
+ (erc-mode)
+ (setq erc-networks--id
+ (make-erc-networks--id-qualifying :parts [foonet "bob" office]
+ :len 3)))
+ (with-current-buffer (get-buffer-create "#chan@foonet/bob/office")
+ (erc-mode)
+ (setq erc-networks--id
+ (buffer-local-value 'erc-networks--id
+ (get-buffer "foonet/bob/office"))))
+
+ (ert-info ("Extend our identity's canonical ID so that it's unique")
+ (should-not (erc-networks--update-server-identity))
+ (should (= (erc-networks--id-qualifying-len erc-networks--id) 3))))
+
+ (erc-networks-tests--clean-bufs))
+
+;;; erc-networks-tests.el ends here
diff --git a/test/lisp/erc/erc-scenarios-auth-source.el b/test/lisp/erc/erc-scenarios-auth-source.el
new file mode 100644
index 00000000000..3d399a18154
--- /dev/null
+++ b/test/lisp/erc/erc-scenarios-auth-source.el
@@ -0,0 +1,178 @@
+;;; erc-scenarios-auth-source.el --- auth-source scenarios -*- lexical-binding: t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+;;
+;; This file is part of GNU Emacs.
+;;
+;; This program is free software: you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation, either version 3 of the
+;; License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see
+;; <https://www.gnu.org/licenses/>.
+
+;; Commentary:
+;;
+;; For practical reasons (mainly lack of imagination), this file
+;; contains tests for both server-password and NickServ contexts.
+
+(require 'ert-x)
+(eval-and-compile
+ (let ((load-path (cons (ert-resource-directory) load-path)))
+ (require 'erc-scenarios-common)))
+
+(eval-when-compile (require 'erc-join)
+ (require 'erc-services))
+
+(defun erc-scenarios-common--auth-source (id dialog &rest rest)
+ (push "machine GNU.chat port %d user \"#chan\" password spam" rest)
+ (erc-scenarios-common-with-cleanup
+ ((erc-scenarios-common-dialog "base/auth-source")
+ (dumb-server (erc-d-run "localhost" t dialog))
+ (port (process-contact dumb-server :service))
+ (ents `(,@(mapcar (lambda (fmt) (format fmt port)) rest)
+ "machine MyHost port irc password 123"))
+ (netrc-file (make-temp-file "auth-source-test" nil nil
+ (string-join ents "\n")))
+ (auth-sources (list netrc-file))
+ (auth-source-do-cache nil)
+ (erc-scenarios-common-extra-teardown (lambda ()
+ (delete-file netrc-file))))
+
+ (ert-info ("Connect")
+ (with-current-buffer (erc :server "127.0.0.1"
+ :port port
+ :nick "tester"
+ :full-name "tester"
+ :id id)
+ (should (string= (buffer-name) (if id
+ (symbol-name id)
+ (format "127.0.0.1:%d" port))))
+ (erc-d-t-wait-for 5 (eq erc-network 'FooNet))))))
+
+(ert-deftest erc-scenarios-base-auth-source-server--dialed ()
+ :tags '(:expensive-test)
+ (erc-scenarios-common--auth-source
+ nil 'foonet
+ "machine GNU.chat port %d user tester password fake"
+ "machine FooNet port %d user tester password fake"
+ "machine 127.0.0.1 port %d user tester password changeme"
+ "machine 127.0.0.1 port %d user imposter password fake"))
+
+(ert-deftest erc-scenarios-base-auth-source-server--netid ()
+ :tags '(:expensive-test)
+ (erc-scenarios-common--auth-source
+ 'MySession 'foonet
+ "machine MySession port %d user tester password changeme"
+ "machine 127.0.0.1 port %d user tester password fake"
+ "machine FooNet port %d user tester password fake"))
+
+(ert-deftest erc-scenarios-base-auth-source-server--netid-custom ()
+ :tags '(:expensive-test)
+ (let ((erc-auth-source-server-function
+ (lambda (&rest _) (erc-auth-source-search :host "MyHost"))))
+ (erc-scenarios-common--auth-source
+ 'MySession 'foonet
+ "machine 127.0.0.1 port %d user tester password fake"
+ "machine MyHost port %d user tester password changeme"
+ "machine MySession port %d user tester password fake")))
+
+(ert-deftest erc-scenarios-base-auth-source-server--nopass ()
+ :tags '(:expensive-test)
+ (let (erc-auth-source-server-function)
+ (erc-scenarios-common--auth-source nil 'nopass)))
+
+(ert-deftest erc-scenarios-base-auth-source-server--nopass-netid ()
+ :tags '(:expensive-test)
+ (let (erc-auth-source-server-function)
+ (erc-scenarios-common--auth-source 'MySession 'nopass)))
+
+;; Identify via auth source with no initial password
+
+(defun erc-scenarios-common--services-auth-source (&rest rest)
+ (erc-scenarios-common-with-cleanup
+ ((erc-scenarios-common-dialog "services/auth-source")
+ (erc-server-flood-penalty 0.1)
+ (dumb-server (erc-d-run "localhost" t 'libera))
+ (port (process-contact dumb-server :service))
+ (ents `(,@(mapcar (lambda (fmt) (format fmt port)) rest)
+ "machine MyHost port irc password 123"))
+ (netrc-file (make-temp-file "auth-source-test" nil nil
+ (string-join ents "\n")))
+ (auth-sources (list netrc-file))
+ (auth-source-do-cache nil)
+ (erc-modules (cons 'services erc-modules))
+ (erc-use-auth-source-for-nickserv-password t) ; do consult for NickServ
+ (expect (erc-d-t-make-expecter))
+ (erc-scenarios-common-extra-teardown (lambda ()
+ (delete-file netrc-file))))
+
+ (cl-letf (((symbol-function 'read-passwd)
+ (lambda (&rest _) (error "Unexpected read-passwd call"))))
+ (ert-info ("Connect without password")
+ (with-current-buffer (erc :server "127.0.0.1"
+ :port port
+ :nick "tester"
+ :full-name "tester")
+ (should (string= (buffer-name) (format "127.0.0.1:%d" port)))
+ (erc-d-t-wait-for 8 (eq erc-network 'Libera.Chat))
+ (funcall expect 3 "This nickname is registered.")
+ (funcall expect 3 "You are now identified")
+ (funcall expect 3 "Last login from")
+ (erc-cmd-QUIT ""))))
+
+ (erc-services-mode -1)
+
+ (should-not (memq 'services erc-modules))))
+
+;; These tests are about authenticating to nick services
+
+(ert-deftest erc-scenarios-services-auth-source--network ()
+ :tags '(:expensive-test)
+ ;; Skip consulting auth-source for the server password (PASS).
+ (let (erc-auth-source-server-function)
+ (erc-scenarios-common--services-auth-source
+ "machine 127.0.0.1 port %d user tester password spam"
+ "machine zirconium.libera.chat port %d user tester password fake"
+ "machine Libera.Chat port %d user tester password changeme")))
+
+(ert-deftest erc-scenarios-services-auth-source--network-connect-lookup ()
+ :tags '(:expensive-test)
+ ;; Do consult auth-source for the server password (and find nothing)
+ (erc-scenarios-common--services-auth-source
+ "machine zirconium.libera.chat port %d user tester password fake"
+ "machine Libera.Chat port %d user tester password changeme"))
+
+(ert-deftest erc-scenarios-services-auth-source--announced ()
+ :tags '(:expensive-test)
+ (let (erc-auth-source-server-function)
+ (erc-scenarios-common--services-auth-source
+ "machine 127.0.0.1 port %d user tester password spam"
+ "machine zirconium.libera.chat port %d user tester password changeme")))
+
+(ert-deftest erc-scenarios-services-auth-source--dialed ()
+ :tags '(:expensive-test)
+ ;; Support legacy host -> domain name
+ ;; (likely most common in real configs)
+ (let (erc-auth-source-server-function)
+ (erc-scenarios-common--services-auth-source
+ "machine 127.0.0.1 port %d user tester password changeme")))
+
+(ert-deftest erc-scenarios-services-auth-source--custom ()
+ :tags '(:expensive-test)
+ (let (erc-auth-source-server-function
+ (erc-auth-source-services-function
+ (lambda (&rest _) (erc-auth-source-search :host "MyAccount"))))
+ (erc-scenarios-common--services-auth-source
+ "machine zirconium.libera.chat port %d user tester password spam"
+ "machine MyAccount port %d user tester password changeme"
+ "machine 127.0.0.1 port %d user tester password fake")))
+
+;;; erc-scenarios-auth-source.el ends here
diff --git a/test/lisp/erc/erc-scenarios-base-association-nick.el b/test/lisp/erc/erc-scenarios-base-association-nick.el
new file mode 100644
index 00000000000..3e848be4df2
--- /dev/null
+++ b/test/lisp/erc/erc-scenarios-base-association-nick.el
@@ -0,0 +1,163 @@
+;;; erc-scenarios-base-association-nick.el --- base assoc scenarios -*- lexical-binding: t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+;;
+;; This file is part of GNU Emacs.
+;;
+;; This program is free software: you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation, either version 3 of the
+;; License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see
+;; <https://www.gnu.org/licenses/>.
+
+(require 'ert-x)
+(eval-and-compile
+ (let ((load-path (cons (ert-resource-directory) load-path)))
+ (require 'erc-scenarios-common)))
+
+(eval-when-compile (require 'erc-join))
+
+;; You register a new nick, disconnect, and log back in, but your nick
+;; is not granted, so ERC obtains a backtick'd version. You open a
+;; query buffer for NickServ, and ERC names it using the net-ID (which
+;; includes the backtick'd nick) as a suffix. The original
+;; (disconnected) NickServ buffer gets renamed with *its* net-ID as
+;; well. You then identify to NickServ, and the dead session is no
+;; longer considered distinct.
+
+(ert-deftest erc-scenarios-base-association-nick-bumped ()
+ :tags '(:expensive-test)
+ (erc-scenarios-common-with-cleanup
+ ((erc-scenarios-common-dialog "base/assoc/bumped")
+ (dumb-server (erc-d-run "localhost" t 'renicked 'again))
+ (port (process-contact dumb-server :service))
+ (expect (erc-d-t-make-expecter))
+ (erc-server-flood-penalty 0.5)
+ (erc-server-flood-margin 30))
+
+ (ert-info ("Connect to foonet with nick tester")
+ (with-current-buffer (erc :server "127.0.0.1"
+ :port port
+ :nick "tester"
+ :full-name "tester")
+ (erc-scenarios-common-assert-initial-buf-name nil port)
+ (erc-d-t-wait-for 5 (eq erc-network 'foonet))))
+
+ (ert-info ("Create an account for tester and quit")
+ (with-current-buffer "foonet"
+ (funcall expect 3 "debug mode")
+
+ (erc-cmd-QUERY "NickServ")
+ (with-current-buffer "NickServ"
+ (erc-scenarios-common-say "REGISTER changeme")
+ (funcall expect 5 "Account created")
+ (funcall expect 1 "You're now logged in as tester"))
+
+ (with-current-buffer "foonet"
+ (erc-cmd-QUIT "")
+ (erc-d-t-wait-for 4 (not (erc-server-process-alive)))
+ (funcall expect 5 "ERC finished"))))
+
+ (with-current-buffer "foonet"
+ (erc-cmd-RECONNECT))
+
+ (erc-d-t-wait-for 10 "Nick request rejection prevents reassociation (good)"
+ (get-buffer "foonet/tester`"))
+
+ (ert-info ("Ask NickServ to change nick")
+ (with-current-buffer "foonet/tester`"
+ (funcall expect 3 "already in use")
+ (funcall expect 3 "debug mode")
+ (erc-cmd-QUERY "NickServ"))
+
+ (erc-d-t-wait-for 1 "Dead NickServ query buffer renamed, now qualified"
+ (get-buffer "NickServ@foonet/tester"))
+
+ (with-current-buffer "NickServ@foonet/tester`" ; new one
+ (erc-scenarios-common-say "IDENTIFY tester changeme")
+ (funcall expect 5 "You're now logged in as tester")
+ (ert-info ("Original buffer found, reused")
+ (erc-d-t-wait-for 2 (equal (buffer-name) "NickServ")))))
+
+ (ert-info ("Ours is the only NickServ buffer that remains")
+ (should-not (cdr (erc-scenarios-common-buflist "NickServ"))))
+
+ (ert-info ("Visible network ID truncated to one component")
+ (should (not (get-buffer "foonet/tester`")))
+ (should (not (get-buffer "foonet/tester")))
+ (should (get-buffer "foonet")))))
+
+;; A less common variant is when your bouncer switches to an alternate
+;; nick while you're disconnected, and upon reconnecting, you get
+;; a new nick.
+
+(ert-deftest erc-scenarios-base-association-nick-bumped-mandated-renick ()
+ :tags '(:expensive-test)
+ (erc-scenarios-common-with-cleanup
+ ((erc-scenarios-common-dialog "base/assoc/bumped")
+ (dumb-server (erc-d-run "localhost" t 'foisted 'refoisted))
+ (port (process-contact dumb-server :service))
+ (expect (erc-d-t-make-expecter))
+ (erc-server-flood-penalty 0.5)
+ (erc-server-flood-margin 30))
+
+ (ert-info ("Connect to foonet with nick tester")
+ (with-current-buffer (erc :server "127.0.0.1"
+ :port port
+ :nick "tester"
+ :full-name "tester")
+ (erc-scenarios-common-assert-initial-buf-name nil port)
+ (erc-d-t-wait-for 5 (eq erc-network 'foonet))))
+
+ (ert-info ("Greet bob and quit")
+ (with-current-buffer "foonet"
+ (funcall expect 3 "debug mode")
+
+ (erc-cmd-QUERY "bob")
+ (with-current-buffer "bob"
+ (erc-scenarios-common-say "hi")
+ (funcall expect 5 "hola")
+ (funcall expect 1 "how r u?"))
+
+ (with-current-buffer "foonet"
+ (erc-cmd-QUIT "")
+ (erc-d-t-wait-for 4 (not (erc-server-process-alive)))
+ (funcall expect 5 "ERC finished"))))
+
+ ;; Since we use reconnect, a new buffer won't be created
+ ;; TODO add variant with clean `erc' invocation
+ (with-current-buffer "foonet"
+ (erc-cmd-RECONNECT))
+
+ (ert-info ("Server-initiated renick")
+ (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "foonet/dummy"))
+ (should-not (get-buffer "foonet/tester"))
+ (funcall expect 15 "debug mode"))
+
+ (erc-d-t-wait-for 1 "Old query renamed, now qualified"
+ (get-buffer "bob@foonet/tester"))
+
+ (with-current-buffer (erc-d-t-wait-for 5 (get-buffer "bob@foonet/dummy"))
+ (erc-cmd-NICK "tester")
+ (ert-info ("Buffers combined")
+ (erc-d-t-wait-for 2 (equal (buffer-name) "bob")))))
+
+ (with-current-buffer "foonet"
+ (funcall expect 5 "You're now logged in as tester"))
+
+ (ert-info ("Ours is the only bob buffer that remains")
+ (should-not (cdr (erc-scenarios-common-buflist "bob"))))
+
+ (ert-info ("Visible network ID truncated to one component")
+ (should (not (get-buffer "foonet/dummy")))
+ (should (get-buffer "foonet")))))
+
+;;; erc-scenarios-base-association-nick.el ends here
diff --git a/test/lisp/erc/erc-scenarios-base-association-samenet.el b/test/lisp/erc/erc-scenarios-base-association-samenet.el
new file mode 100644
index 00000000000..b7c7079df34
--- /dev/null
+++ b/test/lisp/erc/erc-scenarios-base-association-samenet.el
@@ -0,0 +1,144 @@
+;;; erc-scenarios-base-association-samenet.el --- assoc samenet scenarios -*- lexical-binding: t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+;;
+;; This file is part of GNU Emacs.
+;;
+;; This program is free software: you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation, either version 3 of the
+;; License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see
+;; <https://www.gnu.org/licenses/>.
+
+(require 'ert-x)
+(eval-and-compile
+ (let ((load-path (cons (ert-resource-directory) load-path)))
+ (require 'erc-scenarios-common)))
+
+(declare-function erc-network-name "erc-networks")
+(declare-function erc-network "erc-networks")
+(defvar erc-autojoin-channels-alist)
+(defvar erc-network)
+
+;; One network, two simultaneous connections, no IDs.
+;; Reassociates on reconnect with and without server buffer.
+
+(defun erc-scenarios-common--base-association-samenet (after)
+ (erc-scenarios-common-with-cleanup
+ ((erc-scenarios-common-dialog "base/assoc/samenet")
+ (dumb-server (erc-d-run "localhost" t 'tester 'chester 'tester2))
+ (port (process-contact dumb-server :service))
+ (expect (erc-d-t-make-expecter))
+ (erc-server-flood-penalty 0.5)
+ (erc-server-flood-margin 30))
+
+ (ert-info ("Connect to foonet with nick tester")
+ (with-current-buffer (erc :server "127.0.0.1"
+ :port port
+ :nick "tester"
+ :password "changeme"
+ :full-name "tester")
+ (erc-scenarios-common-assert-initial-buf-name nil port)
+ (erc-d-t-wait-for 5 (eq erc-network 'foonet))))
+
+ (ert-info ("Connect to foonet with nick chester")
+ (with-current-buffer (erc :server "127.0.0.1"
+ :port port
+ :nick "chester"
+ :password "changeme"
+ :full-name "chester")
+ (erc-scenarios-common-assert-initial-buf-name nil port)))
+
+ (erc-d-t-wait-for 3 "Dialed Buflist is Empty"
+ (not (erc-scenarios-common-buflist "127.0.0.1")))
+
+ (with-current-buffer "foonet/tester"
+ (funcall expect 3 "debug mode")
+ (erc-cmd-JOIN "#chan"))
+
+ (erc-d-t-wait-for 10 (get-buffer "#chan@foonet/tester"))
+ (with-current-buffer "foonet/chester" (funcall expect 3 "debug mode"))
+ (erc-d-t-wait-for 10 (get-buffer "#chan@foonet/chester"))
+
+ (ert-info ("Nick tester sees other nick chester in channel")
+ (with-current-buffer "#chan@foonet/tester"
+ (funcall expect 5 "chester")
+ (funcall expect 5 "find the forester")
+ (erc-cmd-QUIT "")))
+
+ (ert-info ("Nick chester sees other nick tester in same channel")
+ (with-current-buffer "#chan@foonet/chester"
+ (funcall expect 5 "tester")
+ (funcall expect 5 "find the forester")))
+
+ (funcall after expect)))
+
+(ert-deftest erc-scenarios-base-association-samenet--reconnect-one ()
+ :tags '(:expensive-test)
+ (erc-scenarios-common--base-association-samenet
+ (lambda (expect)
+
+ (ert-info ("Connection tester reconnects")
+ (with-current-buffer "foonet/tester"
+ (erc-d-t-wait-for 10 (not (erc-server-process-alive)))
+ (funcall expect 10 "*** ERC finished")
+ (erc-cmd-RECONNECT)
+ (funcall expect 5 "debug mode")))
+
+ (ert-info ("Reassociated to same channel")
+ (with-current-buffer "#chan@foonet/tester"
+ (funcall expect 5 "chester")
+ (funcall expect 5 "welcome again")
+ (erc-cmd-QUIT "")))
+
+ (with-current-buffer "#chan@foonet/chester"
+ (funcall expect 5 "tester")
+ (funcall expect 5 "welcome again")
+ (funcall expect 5 "welcome again")
+ (erc-cmd-QUIT "")))))
+
+(ert-deftest erc-scenarios-base-association-samenet--new-buffer ()
+ :tags '(:expensive-test)
+ (erc-scenarios-common--base-association-samenet
+ (lambda (expect)
+
+ (ert-info ("Tester kills buffer and connects from scratch")
+
+ (let (port)
+ (with-current-buffer "foonet/tester"
+ (erc-d-t-wait-for 10 (not (erc-server-process-alive)))
+ (funcall expect 10 "*** ERC finished")
+ (setq port erc-session-port)
+ (kill-buffer))
+
+ (with-current-buffer (erc :server "127.0.0.1"
+ :port port
+ :nick "tester"
+ :password "changeme"
+ :full-name "tester")
+
+ (erc-d-t-wait-for 5 (eq erc-network 'foonet)))))
+
+ (with-current-buffer "foonet/tester" (funcall expect 3 "debug mode"))
+
+ (ert-info ("Reassociated to same channel")
+ (with-current-buffer "#chan@foonet/tester"
+ (funcall expect 5 "chester")
+ (funcall expect 5 "welcome again")
+ (erc-cmd-QUIT "")))
+
+ (with-current-buffer "#chan@foonet/chester"
+ (funcall expect 5 "tester")
+ (funcall expect 5 "welcome again")
+ (funcall expect 5 "welcome again")
+ (erc-cmd-QUIT "")))))
+
+;;; erc-scenarios-base-association-samenet.el ends here
diff --git a/test/lisp/erc/erc-scenarios-base-association.el b/test/lisp/erc/erc-scenarios-base-association.el
new file mode 100644
index 00000000000..83e5101e3ad
--- /dev/null
+++ b/test/lisp/erc/erc-scenarios-base-association.el
@@ -0,0 +1,192 @@
+;;; erc-scenarios-base-association.el --- base assoc scenarios -*- lexical-binding: t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+;;
+;; This file is part of GNU Emacs.
+;;
+;; This program is free software: you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation, either version 3 of the
+;; License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see
+;; <https://www.gnu.org/licenses/>.
+
+(require 'ert-x)
+(eval-and-compile
+ (let ((load-path (cons (ert-resource-directory) load-path)))
+ (require 'erc-scenarios-common)))
+
+(declare-function erc-network-name "erc-networks")
+(declare-function erc-network "erc-networks")
+(defvar erc-autojoin-channels-alist)
+(defvar erc-network)
+
+;; Two networks, same channel name, no confusion (no bouncer). Some
+;; of this draws from bug#47522 "foil-in-server-buf". It shows that
+;; disambiguation-related changes added for bug#48598 are not specific
+;; to bouncers.
+
+(defun erc-scenarios-common--base-association-multi-net (second-join)
+ (erc-scenarios-common-with-cleanup
+ ((erc-scenarios-common-dialog "base/assoc/multi-net")
+ (erc-server-flood-penalty 0.1)
+ (dumb-server-foonet-buffer (get-buffer-create "*server-foonet*"))
+ (dumb-server-barnet-buffer (get-buffer-create "*server-barnet*"))
+ (dumb-server-foonet (erc-d-run "localhost" t "server-foonet" 'foonet))
+ (dumb-server-barnet (erc-d-run "localhost" t "server-barnet" 'barnet))
+ (expect (erc-d-t-make-expecter)))
+
+ (ert-info ("Connect to foonet, join #chan")
+ (with-current-buffer
+ (erc :server "127.0.0.1"
+ :port (process-contact dumb-server-foonet :service)
+ :nick "tester"
+ :password "changeme"
+ :full-name "tester")
+ (funcall expect 3 "debug mode")
+ (erc-cmd-JOIN "#chan")))
+
+ (erc-d-t-wait-for 2 (get-buffer "#chan"))
+
+ (ert-info ("Connect to barnet, join #chan")
+ (with-current-buffer
+ (erc :server "127.0.0.1"
+ :port (process-contact dumb-server-barnet :service)
+ :nick "tester"
+ :password "changeme"
+ :full-name "tester")
+ (funcall expect 5 "debug mode")))
+
+ (funcall second-join)
+
+ (erc-d-t-wait-for 3 (get-buffer "#chan@barnet"))
+
+ (erc-d-t-wait-for 2 "Buf #chan now #chan@foonet"
+ (and (get-buffer "#chan@foonet") (not (get-buffer "#chan"))))
+
+ (ert-info ("All #chan@foonet output consumed")
+ (with-current-buffer "#chan@foonet"
+ (funcall expect 3 "bob")
+ (funcall expect 3 "was created on")
+ (funcall expect 3 "prosperous")))
+
+ (ert-info ("All #chan@barnet output consumed")
+ (with-current-buffer "#chan@barnet"
+ (funcall expect 3 "mike")
+ (funcall expect 3 "was created on")
+ (funcall expect 20 "ingenuous")))))
+
+(ert-deftest erc-scenarios-base-association-multi-net--baseline ()
+ :tags '(:expensive-test)
+ (erc-scenarios-common--base-association-multi-net
+ (lambda () (with-current-buffer "barnet" (erc-cmd-JOIN "#chan")))))
+
+;; The /join command only targets the current buffer's process. This
+;; recasts scenario bug#48598 "ambiguous-join" (which was based on
+;; bug#47522) to show that issuing superfluous /join commands
+;; (apparently fairly common) is benign.
+
+(ert-deftest erc-scenarios-base-association-multi-net--ambiguous-join ()
+ :tags '(:expensive-test)
+ (erc-scenarios-common--base-association-multi-net
+ (lambda ()
+ (ert-info ("Nonsensical JOIN attempts silently dropped.")
+ (with-current-buffer "foonet" (erc-cmd-JOIN "#chan"))
+ (sit-for 0.1)
+ (with-current-buffer "#chan" (erc-cmd-JOIN "#chan"))
+ (sit-for 0.1)
+ (erc-d-t-wait-for 2 (get-buffer "#chan"))
+ (erc-d-t-wait-for 1 "Only one #chan buffer exists"
+ (should (equal (erc-scenarios-common-buflist "#chan")
+ (list (get-buffer "#chan")))))
+ (with-current-buffer "*server-barnet*"
+ (erc-d-t-absent-for 0.1 "JOIN"))
+ (with-current-buffer "barnet" (erc-cmd-JOIN "#chan"))))))
+
+;; Playback for same channel on two networks routed correctly.
+;; Originally from Bug#48598: 28.0.50; buffer-naming collisions
+;; involving bouncers in ERC.
+
+(ert-deftest erc-scenarios-base-association-bouncer-history ()
+ :tags '(:expensive-test)
+ (erc-scenarios-common-with-cleanup
+ ((erc-scenarios-common-dialog "base/assoc/bouncer-history")
+ (erc-d-t-cleanup-sleep-secs 1)
+ (dumb-server (erc-d-run "localhost" t 'foonet 'barnet))
+ (port (process-contact dumb-server :service))
+ (erc-server-flood-penalty 0.5)
+ (expect (erc-d-t-make-expecter))
+ erc-autojoin-channels-alist
+ erc-server-buffer-foo erc-server-process-foo
+ erc-server-buffer-bar erc-server-process-bar)
+
+ (ert-info ("Connect to foonet")
+ (with-current-buffer
+ (setq erc-server-buffer-foo (erc :server "127.0.0.1"
+ :port port
+ :nick "tester"
+ :password "foonet:changeme"
+ :full-name "tester"))
+ (setq erc-server-process-foo erc-server-process)
+ (should (string= (buffer-name) (format "127.0.0.1:%d" port)))
+ (funcall expect 5 "foonet")))
+
+ (erc-d-t-wait-for 5 (get-buffer "#chan"))
+
+ (ert-info ("Connect to barnet")
+ (with-current-buffer
+ (setq erc-server-buffer-bar (erc :server "127.0.0.1"
+ :port port
+ :nick "tester"
+ :password "barnet:changeme"
+ :full-name "tester"))
+ (setq erc-server-process-bar erc-server-process)
+ (erc-d-t-wait-for 5 "Temporary name assigned"
+ (string= (buffer-name) (format "127.0.0.1:%d" port)))
+ (funcall expect 5 "barnet")))
+
+ (ert-info ("Server buffers are unique")
+ (should-not (eq erc-server-buffer-foo erc-server-buffer-bar)))
+
+ (ert-info ("Networks correctly determined and adopted as buffer names")
+ (with-current-buffer erc-server-buffer-foo
+ (erc-d-t-wait-for 3 "network name foonet becomes buffer name"
+ (and (eq (erc-network) 'foonet) (string= (buffer-name) "foonet"))))
+ (with-current-buffer erc-server-buffer-bar
+ (erc-d-t-wait-for 3 "network name barnet becomes buffer name"
+ (and (eq (erc-network) 'barnet) (string= (buffer-name) "barnet")))))
+
+ (erc-d-t-wait-for 5 (get-buffer "#chan@barnet"))
+
+ (ert-info ("Two channel buffers created, original #chan renamed")
+ (should (= 4 (length (erc-buffer-list))))
+ (should (equal (list (get-buffer "#chan@barnet")
+ (get-buffer "#chan@foonet"))
+ (erc-scenarios-common-buflist "#chan"))))
+
+ (ert-info ("#chan@foonet is exclusive, no cross-contamination")
+ (with-current-buffer "#chan@foonet"
+ (erc-d-t-search-for 1 "<bob>")
+ (erc-d-t-absent-for 0.1 "<joe>")
+ (should (eq erc-server-process erc-server-process-foo))))
+
+ (ert-info ("#chan@barnet is exclusive, no cross-contamination")
+ (with-current-buffer "#chan@barnet"
+ (erc-d-t-search-for 1 "<joe>")
+ (erc-d-t-absent-for 0.1 "<bob>")
+ (should (eq erc-server-process erc-server-process-bar))))
+
+ (ert-info ("All output sent")
+ (with-current-buffer "#chan@foonet"
+ (erc-d-t-search-for 10 "please your lordship"))
+ (with-current-buffer "#chan@barnet"
+ (erc-d-t-search-for 10 "I'll bid adieu")))))
+
+;;; erc-scenarios-base-association.el ends here
diff --git a/test/lisp/erc/erc-scenarios-base-compat-rename-bouncer.el b/test/lisp/erc/erc-scenarios-base-compat-rename-bouncer.el
new file mode 100644
index 00000000000..474739d01be
--- /dev/null
+++ b/test/lisp/erc/erc-scenarios-base-compat-rename-bouncer.el
@@ -0,0 +1,171 @@
+;;; erc-scenarios-compat-rename-bouncer.el --- compat-rename scenarios -*- lexical-binding: t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+;;
+;; This file is part of GNU Emacs.
+;;
+;; This program is free software: you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation, either version 3 of the
+;; License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see
+;; <https://www.gnu.org/licenses/>.
+
+(require 'ert-x)
+(eval-and-compile
+ (let ((load-path (cons (ert-resource-directory) load-path)))
+ (require 'erc-scenarios-common)))
+
+(eval-when-compile (require 'erc-join))
+
+;; Ensure deprecated option still respected when old default value
+;; explicitly set ("respected" in the sense of having names reflect
+;; dialed TCP endpoints with possible uniquifiers but without any of
+;; the old issues, pre-bug#48598).
+
+(defun erc-scenarios-common--base-compat-no-rename-bouncer (dialogs auto more)
+ (erc-scenarios-common-with-cleanup
+ ;; These actually *are* (assigned-)network-id related because
+ ;; our kludge assigns one after the fact.
+ ((erc-scenarios-common-dialog "base/netid/bouncer")
+ (erc-d-t-cleanup-sleep-secs 1)
+ (erc-server-flood-penalty 0.1)
+ (dumb-server (apply #'erc-d-run "localhost" t dialogs))
+ (port (process-contact dumb-server :service))
+ (chan-buf-foo (format "#chan@127.0.0.1:%d" port))
+ (chan-buf-bar (format "#chan@127.0.0.1:%d<2>" port))
+ (expect (erc-d-t-make-expecter))
+ (erc-server-auto-reconnect auto)
+ erc-server-buffer-foo erc-server-process-foo
+ erc-server-buffer-bar erc-server-process-bar)
+
+ (ert-info ("Connect to foonet")
+ (with-current-buffer
+ (setq erc-server-buffer-foo (erc :server "127.0.0.1"
+ :port port
+ :nick "tester"
+ :password "foonet:changeme"
+ :full-name "tester"
+ :id nil))
+ (setq erc-server-process-foo erc-server-process)
+ (erc-d-t-wait-for 3 (eq (erc-network) 'foonet))
+ (erc-d-t-wait-for 3 "Final buffer name determined"
+ (string= (buffer-name) (format "127.0.0.1:%d" port)))
+ (funcall expect 5 "foonet")))
+
+ (ert-info ("Join #chan@foonet")
+ (with-current-buffer erc-server-buffer-foo (erc-cmd-JOIN "#chan"))
+ (with-current-buffer (erc-d-t-wait-for 5 (get-buffer "#chan"))
+ (funcall expect 5 "<alice>")))
+
+ (ert-info ("Connect to barnet")
+ (with-current-buffer
+ (setq erc-server-buffer-bar (erc :server "127.0.0.1"
+ :port port
+ :nick "tester"
+ :password "barnet:changeme"
+ :full-name "tester"
+ :id nil))
+ (setq erc-server-process-bar erc-server-process)
+ (erc-d-t-wait-for 3 (eq (erc-network) 'barnet))
+ (erc-d-t-wait-for 3 "Final buffer name determined"
+ (string= (buffer-name) (format "127.0.0.1:%d<2>" port)))
+ (funcall expect 5 "barnet")))
+
+ (ert-info ("Server buffers are unique, no names based on IPs")
+ (should-not (eq erc-server-buffer-foo erc-server-buffer-bar))
+ (should (equal (erc-scenarios-common-buflist "127.0.0.1")
+ (list (get-buffer (format "127.0.0.1:%d<2>" port))
+ (get-buffer (format "127.0.0.1:%d" port))))))
+
+ (ert-info ("Join #chan@barnet")
+ (with-current-buffer erc-server-buffer-bar (erc-cmd-JOIN "#chan")))
+
+ (erc-d-t-wait-for 5 "Exactly 2 #chan-prefixed buffers exist"
+ (equal (list (get-buffer chan-buf-bar)
+ (get-buffer chan-buf-foo))
+ (erc-scenarios-common-buflist "#chan")))
+
+ (ert-info ("#chan@127.0.0.1:$port is exclusive to foonet")
+ (with-current-buffer chan-buf-foo
+ (erc-d-t-search-for 1 "<bob>")
+ (erc-d-t-absent-for 0.1 "<joe>")
+ (should (eq erc-server-process erc-server-process-foo))
+ (erc-d-t-search-for 10 "ape is dead")
+ (erc-d-t-wait-for 5 (not (erc-server-process-alive)))))
+
+ (ert-info ("#chan@127.0.0.1:$port<2> is exclusive to barnet")
+ (with-current-buffer chan-buf-bar
+ (erc-d-t-search-for 1 "<joe>")
+ (erc-d-t-absent-for 0.1 "<bob>")
+ (should (eq erc-server-process erc-server-process-bar))
+ (erc-d-t-search-for 10 "keeps you from dishonour")
+ (erc-d-t-wait-for 5 (not (erc-server-process-alive)))))
+
+ (when more (funcall more))))
+
+(ert-deftest erc-scenarios-base-compat-no-rename-bouncer--basic ()
+ :tags '(:expensive-test)
+ (with-suppressed-warnings ((obsolete erc-rename-buffers))
+ (let (erc-rename-buffers)
+ (erc-scenarios-common--base-compat-no-rename-bouncer
+ '(foonet barnet) nil nil))))
+
+(ert-deftest erc-scenarios-base-compat-no-rename-bouncer--reconnect ()
+ :tags '(:expensive-test)
+ (let ((erc-d-tmpl-vars '((token . (group (| "barnet" "foonet")))))
+ (erc-d-match-handlers
+ (list :pass #'erc-scenarios-common--clash-rename-pass-handler))
+ (dialogs '(foonet-drop barnet-drop stub-again stub-again
+ foonet-again barnet-again))
+ (after
+ (lambda ()
+ (pcase-let* ((`(,barnet ,foonet)
+ (erc-scenarios-common-buflist "127.0.0.1"))
+ (port (process-contact (with-current-buffer foonet
+ erc-server-process)
+ :service)))
+
+ (ert-info ("Sanity check: barnet retains uniquifying suffix")
+ (should (string-suffix-p "<2>" (buffer-name barnet))))
+
+ ;; Simulate disconnection and `erc-server-auto-reconnect'
+ (ert-info ("Reconnect to foonet and barnet back-to-back")
+ (with-current-buffer foonet
+ (erc-d-t-wait-for 5 (erc-server-process-alive)))
+ (with-current-buffer barnet
+ (erc-d-t-wait-for 5 (erc-server-process-alive))))
+
+ (ert-info ("#chan@127.0.0.1:<port> is exclusive to foonet")
+ (with-current-buffer (format "#chan@127.0.0.1:%d" port)
+ (erc-d-t-search-for 1 "<alice>")
+ (erc-d-t-absent-for 0.1 "<joe>")
+ (erc-d-t-search-for 10 "please your lordship")))
+
+ (ert-info ("#chan@barnet is exclusive to barnet")
+ (with-current-buffer (format "#chan@127.0.0.1:%d<2>" port)
+ (erc-d-t-search-for 1 "<joe>")
+ (erc-d-t-absent-for 0.1 "<bob>")
+ (erc-d-t-search-for 1 "much in private")))
+
+ ;; Ordering deterministic here even though not so for reconnect
+ (should (equal (list barnet foonet)
+ (erc-scenarios-common-buflist "127.0.0.1")))
+ (should (equal (list
+ (get-buffer (format "#chan@127.0.0.1:%d<2>" port))
+ (get-buffer (format "#chan@127.0.0.1:%d" port)))
+ (erc-scenarios-common-buflist "#chan")))))))
+
+ (with-suppressed-warnings ((obsolete erc-rename-buffers))
+ (let (erc-rename-buffers)
+ (erc-scenarios-common--base-compat-no-rename-bouncer dialogs
+ 'auto after)))))
+
+;;; erc-scenarios-compat-rename-bouncer.el ends here
diff --git a/test/lisp/erc/erc-scenarios-base-misc-regressions.el b/test/lisp/erc/erc-scenarios-base-misc-regressions.el
new file mode 100644
index 00000000000..8f5700df14b
--- /dev/null
+++ b/test/lisp/erc/erc-scenarios-base-misc-regressions.el
@@ -0,0 +1,126 @@
+;;; erc-scenarios-base-misc-regressions.el --- misc regressions scenarios -*- lexical-binding: t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+;;
+;; This file is part of GNU Emacs.
+;;
+;; This program is free software: you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation, either version 3 of the
+;; License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see
+;; <https://www.gnu.org/licenses/>.
+
+(require 'ert-x)
+(eval-and-compile
+ (let ((load-path (cons (ert-resource-directory) load-path)))
+ (require 'erc-scenarios-common)))
+
+(eval-when-compile (require 'erc-join))
+
+(defun erc-scenarios--rebuffed-gapless-pass-handler (dialog exchange)
+ (when (eq (erc-d-dialog-name dialog) 'pass-stub)
+ (let* ((match (erc-d-exchange-match exchange 1))
+ (sym (if (string= match "foonet") 'foonet 'barnet)))
+ (should (member match (list "foonet" "barnet")))
+ (erc-d-load-replacement-dialog dialog sym 1))))
+
+(ert-deftest erc-scenarios-base-gapless-connect ()
+ "Back-to-back entry-point invocations happen successfully.
+Originally from scenario rebuffed/gapless as explained in Bug#48598:
+28.0.50; buffer-naming collisions involving bouncers in ERC."
+ :tags '(:expensive-test)
+ (erc-scenarios-common-with-cleanup
+ ((erc-scenarios-common-dialog "base/gapless-connect")
+ (erc-server-flood-penalty 0.1)
+ (erc-server-flood-penalty erc-server-flood-penalty)
+ (erc-d-tmpl-vars '((token . (group (| "barnet" "foonet")))))
+ (erc-d-match-handlers
+ (list :pass #'erc-scenarios--rebuffed-gapless-pass-handler))
+ (dumb-server (erc-d-run "localhost" t
+ 'pass-stub 'pass-stub 'barnet 'foonet))
+ (port (process-contact dumb-server :service))
+ (expect (erc-d-t-make-expecter))
+ erc-autojoin-channels-alist
+ erc-server-buffer-foo
+ erc-server-buffer-bar)
+
+ (ert-info ("Connect twice to same endpoint without pausing")
+ (setq erc-server-buffer-foo (erc :server "127.0.0.1"
+ :port port
+ :nick "tester"
+ :password "foonet:changeme"
+ :full-name "tester")
+ erc-server-buffer-bar (erc :server "127.0.0.1"
+ :port port
+ :nick "tester"
+ :password "barnet:changeme"
+ :full-name "tester")))
+
+ (ert-info ("Returned server buffers are unique")
+ (should-not (eq erc-server-buffer-foo erc-server-buffer-bar)))
+
+ (ert-info ("Both connections still alive")
+ (should (get-process (format "erc-127.0.0.1-%d" port)))
+ (should (get-process (format "erc-127.0.0.1-%d<1>" port))))
+
+ (with-current-buffer erc-server-buffer-bar
+ (funcall expect 2 "marked as being away"))
+
+ (with-current-buffer (erc-d-t-wait-for 20 (get-buffer "#bar"))
+ (funcall expect 10 "was created on")
+ (funcall expect 2 "his second fit"))
+
+ (with-current-buffer (erc-d-t-wait-for 20 (get-buffer "#foo"))
+ (funcall expect 10 "was created on")
+ (funcall expect 2 "no use of him"))))
+
+;; This defends against a regression in `erc-server-PRIVMSG' caused by
+;; the removal of `erc-auto-query'. When an active channel buffer is
+;; killed off and PRIVMSGs arrive targeting it, the buffer should be
+;; recreated. See elsewhere for NOTICE logic, which is more complex.
+
+(ert-deftest erc-scenarios-base-channel-buffer-revival ()
+ :tags '(:expensive-test)
+
+ (erc-scenarios-common-with-cleanup
+ ((erc-scenarios-common-dialog "base/channel-buffer-revival")
+ (dumb-server (erc-d-run "localhost" t 'foonet))
+ (port (process-contact dumb-server :service))
+ erc-autojoin-channels-alist
+ erc-server-buffer-foo)
+
+ (ert-info ("Connect to foonet")
+ (setq erc-server-buffer-foo (erc :server "127.0.0.1"
+ :port port
+ :nick "tester"
+ :password "changeme"
+ :full-name "tester"))
+ (with-current-buffer erc-server-buffer-foo
+ (should (string= (buffer-name) (format "127.0.0.1:%d" port)))))
+
+ (ert-info ("Server buffer is unique and temp name is absent")
+ (erc-d-t-wait-for 1 (get-buffer "FooNet"))
+ (should-not (erc-scenarios-common-buflist "127.0.0.1"))
+ (with-current-buffer erc-server-buffer-foo
+ (erc-cmd-JOIN "#chan")))
+
+ (ert-info ("Channel buffer #chan alive and well")
+ (with-current-buffer (erc-d-t-wait-for 8 (get-buffer "#chan"))
+ (erc-d-t-search-for 10 "Our queen and all her elves")
+ (kill-buffer)))
+
+ (should-not (get-buffer "#chan"))
+
+ (ert-info ("Channel buffer #chan revived")
+ (with-current-buffer (erc-d-t-wait-for 5 (get-buffer "#chan"))
+ (erc-d-t-search-for 10 "and be prosperous")))))
+
+;;; erc-scenarios-base-misc-regressions.el ends here
diff --git a/test/lisp/erc/erc-scenarios-base-netid-bouncer-id.el b/test/lisp/erc/erc-scenarios-base-netid-bouncer-id.el
new file mode 100644
index 00000000000..6c6568cad68
--- /dev/null
+++ b/test/lisp/erc/erc-scenarios-base-netid-bouncer-id.el
@@ -0,0 +1,34 @@
+;;; erc-scenarios-base-netid-bouncer-id.el --- net-id bouncer ID scenarios -*- lexical-binding: t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+;;
+;; This file is part of GNU Emacs.
+;;
+;; This program is free software: you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation, either version 3 of the
+;; License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see
+;; <https://www.gnu.org/licenses/>.
+
+(require 'ert-x)
+(eval-and-compile
+ (let ((load-path (cons (ert-resource-directory) load-path)))
+ (require 'erc-scenarios-common)))
+
+(ert-deftest erc-scenarios-base-netid-bouncer--id-foo ()
+ :tags '(:expensive-test)
+ (erc-scenarios-common--base-network-id-bouncer '(:foo-id t) 'foonet 'barnet))
+
+(ert-deftest erc-scenarios-base-netid-bouncer--id-bar ()
+ :tags '(:expensive-test)
+ (erc-scenarios-common--base-network-id-bouncer '(:bar-id t) 'foonet 'barnet))
+
+;;; erc-scenarios-base-netid-bouncer-id.el ends here
diff --git a/test/lisp/erc/erc-scenarios-base-netid-bouncer-recon-base.el b/test/lisp/erc/erc-scenarios-base-netid-bouncer-recon-base.el
new file mode 100644
index 00000000000..f48e1ef3940
--- /dev/null
+++ b/test/lisp/erc/erc-scenarios-base-netid-bouncer-recon-base.el
@@ -0,0 +1,30 @@
+;;; erc-scenarios-base-netid-bouncer-recon-base.el --- net-id base scenarios -*- lexical-binding: t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+;;
+;; This file is part of GNU Emacs.
+;;
+;; This program is free software: you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation, either version 3 of the
+;; License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see
+;; <https://www.gnu.org/licenses/>.
+
+(require 'ert-x)
+(eval-and-compile
+ (let ((load-path (cons (ert-resource-directory) load-path)))
+ (require 'erc-scenarios-common)))
+
+(ert-deftest erc-scenarios-base-netid-bouncer--recon-base ()
+ :tags '(:expensive-test)
+ (erc-scenarios-common--base-network-id-bouncer--reconnect nil nil))
+
+;;; erc-scenarios-base-netid-bouncer-recon-base.el ends here
diff --git a/test/lisp/erc/erc-scenarios-base-netid-bouncer-recon-both.el b/test/lisp/erc/erc-scenarios-base-netid-bouncer-recon-both.el
new file mode 100644
index 00000000000..2f58c3269e3
--- /dev/null
+++ b/test/lisp/erc/erc-scenarios-base-netid-bouncer-recon-both.el
@@ -0,0 +1,32 @@
+;;; erc-scenarios-base-netid-bouncer-recon-both.el --- net-id both scenarios -*- lexical-binding: t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+;;
+;; This file is part of GNU Emacs.
+;;
+;; This program is free software: you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation, either version 3 of the
+;; License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see
+;; <https://www.gnu.org/licenses/>.
+
+(require 'ert-x)
+(eval-and-compile
+ (let ((load-path (cons (ert-resource-directory) load-path)))
+ (require 'erc-scenarios-common)))
+
+(require 'erc-scenarios-common)
+
+(ert-deftest erc-scenarios-base-netid-bouncer--recon-both ()
+ :tags '(:expensive-test)
+ (erc-scenarios-common--base-network-id-bouncer--reconnect 'foo-id 'bar-id))
+
+;;; erc-scenarios-base-netid-bouncer-recon-both.el ends here
diff --git a/test/lisp/erc/erc-scenarios-base-netid-bouncer-recon-id.el b/test/lisp/erc/erc-scenarios-base-netid-bouncer-recon-id.el
new file mode 100644
index 00000000000..72510809ab4
--- /dev/null
+++ b/test/lisp/erc/erc-scenarios-base-netid-bouncer-recon-id.el
@@ -0,0 +1,35 @@
+;;; erc-scenarios-base-netid-bouncer-recon-id.el --- recon ID scenarios -*- lexical-binding: t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+;;
+;; This file is part of GNU Emacs.
+;;
+;; This program is free software: you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation, either version 3 of the
+;; License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see
+;; <https://www.gnu.org/licenses/>.
+
+(require 'ert-x)
+(eval-and-compile
+ (let ((load-path (cons (ert-resource-directory) load-path)))
+ (require 'erc-scenarios-common)))
+
+(ert-deftest erc-scenarios-base-netid-bouncer--reconnect-id-foo ()
+ :tags '(:expensive-test)
+ (erc-scenarios-common--base-network-id-bouncer--reconnect 'foo-id nil))
+
+(ert-deftest erc-scenarios-base-netid-bouncer--reconnect-id-bar ()
+ :tags '(:expensive-test)
+ (erc-scenarios-common--base-network-id-bouncer--reconnect nil 'bar-id))
+
+
+;;; erc-scenarios-base-netid-bouncer-recon-id.el ends here
diff --git a/test/lisp/erc/erc-scenarios-base-netid-bouncer.el b/test/lisp/erc/erc-scenarios-base-netid-bouncer.el
new file mode 100644
index 00000000000..d171e1f9f91
--- /dev/null
+++ b/test/lisp/erc/erc-scenarios-base-netid-bouncer.el
@@ -0,0 +1,35 @@
+;;; erc-scenarios-base-netid-bouncer.el --- net-id bouncer scenarios -*- lexical-binding: t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+;;
+;; This file is part of GNU Emacs.
+;;
+;; This program is free software: you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation, either version 3 of the
+;; License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see
+;; <https://www.gnu.org/licenses/>.
+
+(require 'ert-x)
+(eval-and-compile
+ (let ((load-path (cons (ert-resource-directory) load-path)))
+ (require 'erc-scenarios-common)))
+
+(ert-deftest erc-scenarios-base-netid-bouncer--base ()
+ :tags '(:expensive-test)
+ (erc-scenarios-common--base-network-id-bouncer () 'foonet 'barnet))
+
+(ert-deftest erc-scenarios-base-netid-bouncer--both ()
+ :tags '(:expensive-test)
+ (erc-scenarios-common--base-network-id-bouncer '(:foo-id t :bar-id t)
+ 'foonet 'barnet))
+
+;;; erc-scenarios-base-netid-bouncer.el ends here
diff --git a/test/lisp/erc/erc-scenarios-base-netid-samenet.el b/test/lisp/erc/erc-scenarios-base-netid-samenet.el
new file mode 100644
index 00000000000..248144d6f9b
--- /dev/null
+++ b/test/lisp/erc/erc-scenarios-base-netid-samenet.el
@@ -0,0 +1,147 @@
+;;; erc-scenarios-base-network-id-samenet.el --- netid-id samenet scenarios -*- lexical-binding: t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+;;
+;; This file is part of GNU Emacs.
+;;
+;; This program is free software: you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation, either version 3 of the
+;; License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see
+;; <https://www.gnu.org/licenses/>.
+
+(require 'ert-x)
+(eval-and-compile
+ (let ((load-path (cons (ert-resource-directory) load-path)))
+ (require 'erc-scenarios-common)))
+
+(eval-when-compile (require 'erc-join))
+
+(cl-defun erc-scenarios-common--base-network-id-same-network
+ ((&key nick id server chan
+ &aux (nick-a nick) (id-a id) (serv-buf-a server) (chan-buf-a chan))
+ (&key nick id server chan
+ &aux (nick-b nick) (id-b id) (serv-buf-b server) (chan-buf-b chan)))
+ (erc-scenarios-common-with-cleanup
+ ((erc-scenarios-common-dialog "base/netid/samenet")
+ (dumb-server (erc-d-run "localhost" t 'tester 'chester))
+ (port (process-contact dumb-server :service))
+ (expect (erc-d-t-make-expecter))
+ (erc-server-flood-penalty 0.1)
+ (erc-server-flood-margin 30)
+ erc-serv-buf-a erc-serv-buf-b)
+
+ (ert-info ("Connect to foonet with nick tester")
+ (with-current-buffer
+ (setq erc-serv-buf-a (erc :server "127.0.0.1"
+ :port port
+ :nick nick-a
+ :password "changeme"
+ :full-name nick-a
+ :id id-a))
+ (erc-scenarios-common-assert-initial-buf-name id-a port)
+ (erc-d-t-wait-for 5 (eq erc-network 'foonet))))
+
+ (ert-info ("Connect to foonet with nick chester")
+ (with-current-buffer
+ (setq erc-serv-buf-b (erc :server "127.0.0.1"
+ :port port
+ :nick nick-b
+ :password "changeme"
+ :full-name nick-b
+ :id id-b))
+ (erc-scenarios-common-assert-initial-buf-name id-b port)))
+
+ (erc-d-t-wait-for 3 (not (erc-scenarios-common-buflist "127.0.0.1")))
+
+ (with-current-buffer erc-serv-buf-a
+ (should (string= (buffer-name) serv-buf-a))
+ (funcall expect 8 "debug mode")
+ (erc-cmd-JOIN "#chan"))
+
+ (with-current-buffer erc-serv-buf-b
+ (should (string= (buffer-name) serv-buf-b))
+ (funcall expect 8 "debug mode")
+ (erc-cmd-JOIN "#chan"))
+
+ (erc-d-t-wait-for 10 (get-buffer chan-buf-a))
+ (erc-d-t-wait-for 10 (get-buffer chan-buf-b))
+
+ (ert-info ("Greets other nick in same channel")
+ (with-current-buffer chan-buf-a
+ (funcall expect 5 "chester")
+ (funcall expect 5 "find the forester")
+ (erc-cmd-MSG "#chan chester: hi")))
+
+ (ert-info ("Sees other nick in same channel")
+ (with-current-buffer chan-buf-b
+ (funcall expect 5 "tester")
+ (funcall expect 10 "<tester> chester: hi")
+ (funcall expect 5 "This was lofty")
+ (erc-cmd-MSG "#chan hi tester")))
+
+ (with-current-buffer chan-buf-a
+ (funcall expect 5 "To employ you towards")
+ (erc-cmd-QUIT ""))
+
+ (with-current-buffer chan-buf-b
+ (funcall expect 5 "To employ you towards")
+ (erc-cmd-QUIT ""))))
+
+(ert-deftest erc-scenarios-base-network-id-same-network--two-ids ()
+ :tags '(:expensive-test)
+ (erc-scenarios-common--base-network-id-same-network
+ (list :nick "tester"
+ :id 'tester/foonet
+ :server "tester/foonet"
+ :chan "#chan@tester/foonet")
+ (list :nick "chester"
+ :id 'chester/foonet
+ :server "chester/foonet"
+ :chan "#chan@chester/foonet")))
+
+(ert-deftest erc-scenarios-base-network-id-same-network--one-id-tester ()
+ :tags '(:expensive-test)
+ (erc-scenarios-common--base-network-id-same-network
+ (list :nick "tester"
+ :id 'tester/foonet
+ :server "tester/foonet"
+ :chan "#chan@tester/foonet")
+ (list :nick "chester"
+ :id nil
+ :server "foonet"
+ :chan "#chan@foonet")))
+
+(ert-deftest erc-scenarios-base-network-id-same-network--one-id-chester ()
+ :tags '(:expensive-test)
+ (erc-scenarios-common--base-network-id-same-network
+ (list :nick "tester"
+ :id nil
+ :server "foonet"
+ :chan "#chan@foonet")
+ (list :nick "chester"
+ :id 'chester/foonet
+ :server "chester/foonet"
+ :chan "#chan@chester/foonet")))
+
+(ert-deftest erc-scenarios-base-network-id-same-network--no-ids ()
+ :tags '(:expensive-test)
+ (erc-scenarios-common--base-network-id-same-network
+ (list :nick "tester"
+ :id nil
+ :server "foonet/tester"
+ :chan "#chan@foonet/tester") ; <- note net before nick
+ (list :nick "chester"
+ :id nil
+ :server "foonet/chester"
+ :chan "#chan@foonet/chester")))
+
+;;; erc-scenarios-base-network-id-samenet.el ends here
diff --git a/test/lisp/erc/erc-scenarios-base-reconnect.el b/test/lisp/erc/erc-scenarios-base-reconnect.el
new file mode 100644
index 00000000000..30d692058d6
--- /dev/null
+++ b/test/lisp/erc/erc-scenarios-base-reconnect.el
@@ -0,0 +1,226 @@
+;;; erc-scenarios-base-reconnect.el --- Base-reconnect scenarios -*- lexical-binding: t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+;;
+;; This file is part of GNU Emacs.
+;;
+;; This program is free software: you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation, either version 3 of the
+;; License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see
+;; <https://www.gnu.org/licenses/>.
+
+(require 'ert-x)
+(eval-and-compile
+ (let ((load-path (cons (ert-resource-directory) load-path)))
+ (require 'erc-scenarios-common)))
+
+(eval-when-compile (require 'erc-join))
+
+;; This ensures we only reconnect `erc-server-reconnect-attempts'
+;; (rather than infinitely many) times, which can easily happen when
+;; tweaking code related to process sentinels in erc-backend.el.
+
+(ert-deftest erc-scenarios-base-reconnect-timer ()
+ :tags '(:expensive-test)
+ (erc-scenarios-common-with-cleanup
+ ((erc-scenarios-common-dialog "base/reconnect")
+ (dumb-server (erc-d-run "localhost" t 'timer 'timer 'timer-last))
+ (port (process-contact dumb-server :service))
+ (expect (erc-d-t-make-expecter))
+ (erc-server-auto-reconnect t)
+ erc-autojoin-channels-alist
+ erc-server-buffer)
+
+ (ert-info ("Connect to foonet")
+ (setq erc-server-buffer (erc :server "127.0.0.1"
+ :port port
+ :nick "tester"
+ :password "changeme"
+ :full-name "tester"))
+ (with-current-buffer erc-server-buffer
+ (should (string= (buffer-name) (format "127.0.0.1:%d" port)))))
+
+ (ert-info ("Server tries to connect thrice (including initial attempt)")
+ (with-current-buffer erc-server-buffer
+ (dotimes (n 3)
+ (ert-info ((format "Attempt %d" n))
+ (funcall expect 3 "Opening connection")
+ (funcall expect 2 "Password incorrect")
+ (funcall expect 2 "Connection failed!")
+ (funcall expect 2 "Re-establishing connection")))
+ (ert-info ("Prev attempt was final")
+ (erc-d-t-absent-for 1 "Opening connection" (point)))))
+
+ (ert-info ("Server buffer is unique and temp name is absent")
+ (should (equal (list (get-buffer (format "127.0.0.1:%d" port)))
+ (erc-scenarios-common-buflist "127.0.0.1"))))))
+
+(defun erc-scenarios-common--base-reconnect-options (test)
+ (erc-scenarios-common-with-cleanup
+ ((erc-scenarios-common-dialog "base/reconnect")
+ (dumb-server (erc-d-run "localhost" t 'options 'options-again))
+ (port (process-contact dumb-server :service))
+ (expect (erc-d-t-make-expecter))
+ (erc-server-flood-penalty 0.1)
+ (erc-server-auto-reconnect t)
+ erc-autojoin-channels-alist
+ erc-server-buffer)
+
+ (should (memq 'autojoin erc-modules))
+
+ (ert-info ("Connect to foonet")
+ (setq erc-server-buffer (erc :server "127.0.0.1"
+ :port port
+ :nick "tester"
+ :password "changeme"
+ :full-name "tester"))
+ (with-current-buffer erc-server-buffer
+ (should (string= (buffer-name) (format "127.0.0.1:%d" port)))
+ (funcall expect 10 "debug mode")))
+
+ (ert-info ("Wait for some output in channels")
+ (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "#chan"))
+ (funcall expect 10 "welcome")))
+
+ (ert-info ("Server buffer shows connection failed")
+ (with-current-buffer erc-server-buffer
+ (funcall expect 10 "Connection failed! Re-establishing")))
+
+ (should (equal erc-autojoin-channels-alist '((FooNet "#chan"))))
+
+ (funcall test)
+
+ (with-current-buffer "FooNet" (erc-cmd-JOIN "#spam"))
+
+ (erc-d-t-wait-for 5 "Channel #spam shown when autojoined"
+ (eq (window-buffer) (get-buffer "#spam")))
+
+ (ert-info ("Wait for auto reconnect")
+ (with-current-buffer erc-server-buffer
+ (funcall expect 10 "still in debug mode")))
+
+ (ert-info ("Wait for activity to recommence in channels")
+ (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "#chan"))
+ (funcall expect 10 "forest of Arden"))
+ (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "#spam"))
+ (funcall expect 10 "her elves come here anon")))))
+
+(ert-deftest erc-scenarios-base-reconnect-options--default ()
+ :tags '(:expensive-test)
+ (should (eq erc-join-buffer 'buffer))
+ (should-not erc-reconnect-display)
+
+ ;; FooNet (the server buffer) is not switched to because it's
+ ;; already current (but not shown) when `erc-open' is called. See
+ ;; related conditional guard towards the end of that function.
+
+ (erc-scenarios-common--base-reconnect-options
+ (lambda ()
+ (pop-to-buffer-same-window "*Messages*")
+
+ (erc-d-t-ensure-for 1 "Server buffer not shown"
+ (not (eq (window-buffer) (get-buffer "FooNet"))))
+
+ (erc-d-t-wait-for 5 "Channel #chan shown when autojoined"
+ (eq (window-buffer) (get-buffer "#chan"))))))
+
+(ert-deftest erc-scenarios-base-reconnect-options--bury ()
+ :tags '(:expensive-test)
+ (should (eq erc-join-buffer 'buffer))
+ (should-not erc-reconnect-display)
+
+ (let ((erc-reconnect-display 'bury))
+ (erc-scenarios-common--base-reconnect-options
+
+ (lambda ()
+ (pop-to-buffer-same-window "*Messages*")
+
+ (erc-d-t-ensure-for 1 "Server buffer not shown"
+ (not (eq (window-buffer) (get-buffer "FooNet"))))
+
+ (erc-d-t-ensure-for 3 "Channel #chan not shown"
+ (not (eq (window-buffer) (get-buffer "#chan"))))
+
+ (eq (window-buffer) (messages-buffer))))))
+
+;; Upon reconnecting, playback for channel and target buffers is
+;; routed correctly. Autojoin is irrelevant here, but for the
+;; skeptical, see `erc-scenarios-common--join-network-id', which
+;; overlaps with this and includes spurious JOINs ignored by the
+;; server.
+
+(ert-deftest erc-scenarios-base-association-reconnect-playback ()
+ :tags '(:expensive-test)
+ (erc-scenarios-common-with-cleanup
+ ((erc-scenarios-common-dialog "base/assoc/reconplay")
+ (erc-server-flood-penalty 0.1)
+ (erc-server-flood-margin 30)
+ (dumb-server (erc-d-run "localhost" t 'foonet 'again))
+ (port (process-contact dumb-server :service))
+ (expect (erc-d-t-make-expecter))
+ erc-autojoin-channels-alist
+ erc-server-buffer-foo)
+
+ (ert-info ("Connect to foonet")
+ (setq erc-server-buffer-foo (erc :server "127.0.0.1"
+ :port port
+ :nick "tester"
+ :password "changeme"
+ :full-name "tester"))
+ (with-current-buffer erc-server-buffer-foo
+ (should (string= (buffer-name) (format "127.0.0.1:%d" port)))))
+
+ (ert-info ("Setup")
+
+ (ert-info ("Server buffer is unique and temp name is absent")
+ (erc-d-t-wait-for 3 (get-buffer "foonet"))
+ (should-not (erc-scenarios-common-buflist "127.0.0.1")))
+
+ (ert-info ("Channel buffer #chan playback received")
+ (with-current-buffer (erc-d-t-wait-for 8 (get-buffer "#chan"))
+ (funcall expect 10 "But purgatory")))
+
+ (ert-info ("Ask for help from services or bouncer bot")
+ (with-current-buffer erc-server-buffer-foo
+ (erc-cmd-MSG "*status help")))
+
+ (ert-info ("Help received")
+ (with-current-buffer (erc-d-t-wait-for 5 (get-buffer "*status"))
+ (funcall expect 10 "Rehash")))
+
+ (ert-info ("#chan convo done")
+ (with-current-buffer "#chan"
+ (funcall expect 10 "most egregious indignity"))))
+
+ ;; KLUDGE (see note above test)
+ (should erc-autojoin-channels-alist)
+ (setq erc-autojoin-channels-alist nil)
+
+ (with-current-buffer erc-server-buffer-foo
+ (erc-cmd-QUIT "")
+ (erc-d-t-wait-for 4 (not (erc-server-process-alive)))
+ (erc-cmd-RECONNECT))
+
+ (ert-info ("Channel buffer found and associated")
+ (with-current-buffer "#chan"
+ (funcall expect 10 "Wilt thou rest damned")))
+
+ (ert-info ("Help buffer found and associated")
+ (with-current-buffer "*status"
+ (erc-scenarios-common-say "help")
+ (funcall expect 10 "Restart ZNC")))
+
+ (ert-info ("#chan convo done")
+ (with-current-buffer "#chan"
+ (funcall expect 10 "here comes the lady")))))
+
+;;; erc-scenarios-base-reconnect.el ends here
diff --git a/test/lisp/erc/erc-scenarios-base-renick.el b/test/lisp/erc/erc-scenarios-base-renick.el
new file mode 100644
index 00000000000..bf27f61b3fc
--- /dev/null
+++ b/test/lisp/erc/erc-scenarios-base-renick.el
@@ -0,0 +1,305 @@
+;;; erc-scenarios-base-renick.el --- Re-nicking scenarios -*- lexical-binding: t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+;;
+;; This file is part of GNU Emacs.
+;;
+;; This program is free software: you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation, either version 3 of the
+;; License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see
+;; <https://www.gnu.org/licenses/>.
+
+(require 'ert-x)
+(eval-and-compile
+ (let ((load-path (cons (ert-resource-directory) load-path)))
+ (require 'erc-scenarios-common)))
+
+(eval-when-compile (require 'erc-join))
+
+;; The server changes your nick just after registration.
+
+(ert-deftest erc-scenarios-base-renick-self-auto ()
+ :tags '(:expensive-test)
+ (erc-scenarios-common-with-cleanup
+ ((erc-scenarios-common-dialog "base/renick/self")
+ (erc-server-flood-penalty 0.1)
+ (dumb-server (erc-d-run "localhost" t 'auto))
+ (port (process-contact dumb-server :service))
+ erc-autojoin-channels-alist
+ erc-server-buffer-foo)
+
+ (ert-info ("Connect to foonet")
+ (setq erc-server-buffer-foo (erc :server "127.0.0.1"
+ :port port
+ :nick "tester"
+ :password "foonet:changeme"
+ :full-name "tester"))
+ (with-current-buffer erc-server-buffer-foo
+ (should (string= (buffer-name) (format "127.0.0.1:%d" port)))))
+
+ (with-current-buffer (erc-d-t-wait-for 3 (get-buffer "foonet"))
+ (erc-d-t-search-for 10 "Your new nickname is dummy"))
+
+ (ert-info ("Joined by bouncer to #foo, own nick present")
+ (with-current-buffer (erc-d-t-wait-for 1 (get-buffer "#foo"))
+ (erc-d-t-search-for 10 "dummy")
+ (erc-d-t-search-for 10 "On Thursday")))))
+
+;; You change your nickname manually in a server buffer; a message is
+;; printed in channel buffers.
+
+(ert-deftest erc-scenarios-base-renick-self-manual ()
+ :tags '(:expensive-test)
+ (erc-scenarios-common-with-cleanup
+ ((erc-scenarios-common-dialog "base/renick/self")
+ (erc-server-flood-penalty 0.1)
+ (dumb-server (erc-d-run "localhost" t 'manual))
+ (port (process-contact dumb-server :service))
+ (expect (erc-d-t-make-expecter))
+ erc-autojoin-channels-alist
+ erc-server-buffer-foo)
+
+ (ert-info ("Connect to foonet")
+ (setq erc-server-buffer-foo (erc :server "127.0.0.1"
+ :port port
+ :nick "tester"
+ :password "foonet:changeme"
+ :full-name "tester"))
+ (with-current-buffer erc-server-buffer-foo
+ (should (string= (buffer-name) (format "127.0.0.1:%d" port)))))
+
+ (erc-d-t-wait-for 3 (get-buffer "foonet"))
+
+ (ert-info ("Joined by bouncer to #foo, own nick present")
+ (with-current-buffer (erc-d-t-wait-for 1 (get-buffer "#foo"))
+ (funcall expect 5 "tester")
+ (funcall expect 5 "On Thursday")
+ (erc-with-server-buffer (erc-cmd-NICK "dummy"))
+ (funcall expect 5 "Your new nickname is dummy")
+ (funcall expect 5 "<bob> dummy: Hi")
+ ;; Regression in which changing a nick would trigger #foo@foonet
+ (erc-d-t-ensure-for 0.4 (equal (buffer-name) "#foo"))))))
+
+;; You connect to the same network with two different nicks. You
+;; manually change the first nick at some point, and buffer names are
+;; updated correctly.
+
+(ert-deftest erc-scenarios-base-renick-self-qualified ()
+ :tags '(:expensive-test)
+ (erc-scenarios-common-with-cleanup
+ ((erc-scenarios-common-dialog "base/renick/self")
+ (dumb-server (erc-d-run "localhost" t 'qual-tester 'qual-chester))
+ (port (process-contact dumb-server :service))
+ (expect (erc-d-t-make-expecter))
+ (erc-server-flood-penalty 0.1)
+ (erc-server-flood-margin 30)
+ erc-serv-buf-a erc-serv-buf-b)
+
+ (ert-info ("Connect to foonet with nick tester")
+ (with-current-buffer
+ (setq erc-serv-buf-a (erc :server "127.0.0.1"
+ :port port
+ :nick "tester"
+ :password "changeme"
+ :full-name "tester"))
+ (erc-d-t-wait-for 5 (eq erc-network 'foonet))))
+
+ (ert-info ("Connect to foonet with nick chester")
+ (with-current-buffer
+ (setq erc-serv-buf-b (erc :server "127.0.0.1"
+ :port port
+ :nick "chester"
+ :password "changeme"
+ :full-name "chester"))))
+
+ (erc-d-t-wait-for 3 "Dialed Buflist is Empty"
+ (not (erc-scenarios-common-buflist "127.0.0.1")))
+
+ (with-current-buffer "foonet/tester"
+ (funcall expect 3 "debug mode")
+ (erc-cmd-JOIN "#chan"))
+
+ (with-current-buffer "foonet/chester"
+ (funcall expect 3 "debug mode")
+ (erc-cmd-JOIN "#chan"))
+
+ (erc-d-t-wait-for 10 (get-buffer "#chan@foonet/tester"))
+ (erc-d-t-wait-for 10 (get-buffer "#chan@foonet/chester"))
+
+ (ert-info ("Greets other nick in same channel")
+ (with-current-buffer "#chan@foonet/tester"
+ (funcall expect 5 "<bob> chester, welcome!")
+ (erc-cmd-NICK "dummy")
+ (funcall expect 5 "Your new nickname is dummy")
+ (funcall expect 5 "find the forester")
+ (erc-d-t-wait-for 5 (string= (buffer-name) "#chan@foonet/dummy"))))
+
+ (ert-info ("Renick propagated throughout all buffers of process")
+ (should-not (get-buffer "#chan@foonet/tester"))
+ (should-not (get-buffer "foonet/tester"))
+ (should (get-buffer "foonet/dummy")))))
+
+;; When a channel user changes their nick, any query buffers for them
+;; are updated.
+
+(ert-deftest erc-scenarios-base-renick-queries-solo ()
+ :tags '(:expensive-test)
+
+ (erc-scenarios-common-with-cleanup
+ ((erc-scenarios-common-dialog "base/renick/queries")
+ (erc-server-flood-penalty 0.1)
+ (erc-server-flood-margin 20)
+ (dumb-server (erc-d-run "localhost" t 'solo))
+ (port (process-contact dumb-server :service))
+ erc-autojoin-channels-alist
+ erc-server-buffer-foo)
+
+ (ert-info ("Connect to foonet")
+ (setq erc-server-buffer-foo (erc :server "127.0.0.1"
+ :port port
+ :nick "tester"
+ :password "foonet:changeme"
+ :full-name "tester"))
+ (with-current-buffer erc-server-buffer-foo
+ (should (string= (buffer-name) (format "127.0.0.1:%d" port)))))
+
+ (erc-d-t-wait-for 1 (get-buffer "foonet"))
+
+ (ert-info ("Joined by bouncer to #foo, pal persent")
+ (with-current-buffer (erc-d-t-wait-for 1 (get-buffer "#foo"))
+ (erc-d-t-search-for 1 "On Thursday")
+ (erc-scenarios-common-say "hi")))
+
+ (erc-d-t-wait-for 10 "Query buffer appears with message from pal"
+ (get-buffer "Lal"))
+
+ (ert-info ("Chat with pal, who changes name")
+ (with-current-buffer "Lal"
+ (erc-d-t-search-for 3 "hello")
+ (erc-scenarios-common-say "hi")
+ (erc-d-t-search-for 10 "is now known as Linguo")
+ (should-not (search-forward "is now known as Linguo" nil t))))
+
+ (erc-d-t-wait-for 1 (get-buffer "Linguo"))
+ (should-not (get-buffer "Lal"))
+
+ (with-current-buffer "Linguo" (erc-scenarios-common-say "howdy Linguo"))
+
+ (with-current-buffer "#foo"
+ (erc-d-t-search-for 10 "is now known as Linguo")
+ (should-not (search-forward "is now known as Linguo" nil t))
+ (erc-cmd-PART ""))
+
+ (with-current-buffer "Linguo"
+ (erc-d-t-search-for 10 "get along"))))
+
+;; You share a channel and a query buffer with a user on two different
+;; networks (through a proxy). The user changes their nick on both
+;; networks at the same time. Query buffers are updated accordingly.
+
+(ert-deftest erc-scenarios-base-renick-queries-bouncer ()
+ :tags '(:expensive-test)
+
+ (erc-scenarios-common-with-cleanup
+ ((erc-scenarios-common-dialog "base/renick/queries")
+ (erc-server-flood-penalty 0.1)
+ (erc-server-flood-margin 30)
+ (dumb-server (erc-d-run "localhost" t 'bouncer-foonet 'bouncer-barnet))
+ (port (process-contact dumb-server :service))
+ (expect (erc-d-t-make-expecter))
+ erc-accidental-paste-threshold-seconds
+ erc-autojoin-channels-alist
+ erc-server-buffer-foo
+ erc-server-buffer-bar)
+
+ (ert-info ("Connect to foonet")
+ (setq erc-server-buffer-foo (erc :server "127.0.0.1"
+ :port port
+ :nick "tester"
+ :password "foonet:changeme"
+ :full-name "tester"))
+ (with-current-buffer erc-server-buffer-foo
+ (should (string= (buffer-name) (format "127.0.0.1:%d" port)))))
+
+ (erc-d-t-wait-for 5 (get-buffer "foonet"))
+
+ (ert-info ("Connect to barnet")
+ (setq erc-server-buffer-bar (erc :server "127.0.0.1"
+ :port port
+ :nick "tester"
+ :password "barnet:changeme"
+ :full-name "tester"))
+ (with-current-buffer erc-server-buffer-bar
+ (should (string= (buffer-name) (format "127.0.0.1:%d" port)))))
+
+ (erc-d-t-wait-for 5 (get-buffer "barnet"))
+ (should-not (erc-scenarios-common-buflist "127.0.0.1"))
+
+ (ert-info ("Joined by bouncer to #chan@foonet, pal persent")
+ (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "#chan@foonet"))
+ (funcall expect 1 "rando")
+ (funcall expect 1 "simply misused")))
+
+ (ert-info ("Joined by bouncer to #chan@barnet, pal persent")
+ (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "#chan@barnet"))
+ (funcall expect 1 "rando")
+ (funcall expect 2 "come, sir, I am")))
+
+ (ert-info ("Query buffer exists for rando@foonet")
+ (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "rando@foonet"))
+ (funcall expect 1 "guess not")
+ (erc-scenarios-common-say "I here")))
+
+ (ert-info ("Query buffer exists for rando@barnet")
+ (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "rando@barnet"))
+ (funcall expect 2 "rentacop")
+ (erc-scenarios-common-say "Linda said you were gonna kill me.")))
+
+ (ert-info ("Sync convo for rando@foonet")
+ (with-current-buffer "rando@foonet"
+ (funcall expect 1 "u are dumb")
+ (erc-scenarios-common-say "not so")))
+
+ (ert-info ("Sync convo for rando@barnet")
+ (with-current-buffer "rando@barnet"
+ (funcall expect 3 "I never saw her before")
+ (erc-scenarios-common-say "You aren't with Wage?")))
+
+ (erc-d-t-wait-for 3 (get-buffer "frenemy@foonet"))
+ (erc-d-t-wait-for 3 (get-buffer "frenemy@barnet"))
+ (should-not (get-buffer "rando@foonet"))
+ (should-not (get-buffer "rando@barnet"))
+
+ (with-current-buffer "frenemy@foonet"
+ (funcall expect 1 "now known as")
+ (funcall expect 1 "doubly so"))
+
+ (with-current-buffer "frenemy@barnet"
+ (funcall expect 1 "now known as")
+ (funcall expect 1 "reality picture"))
+
+ (when noninteractive
+ (with-current-buffer "frenemy@barnet" (kill-buffer))
+ (erc-d-t-wait-for 2 (get-buffer "frenemy"))
+ (should-not (get-buffer "frenemy@foonet")))
+
+ (with-current-buffer "#chan@foonet"
+ (funcall expect 10 "is now known as frenemy")
+ (should-not (search-forward "now known as frenemy" nil t)) ; regression
+ (funcall expect 10 "words are razors"))
+
+ (with-current-buffer "#chan@barnet"
+ (funcall expect 10 "is now known as frenemy")
+ (should-not (search-forward "now known as frenemy" nil t))
+ (erc-d-t-search-for 25 "I have lost"))))
+
+;;; erc-scenarios-base-renick.el ends here
diff --git a/test/lisp/erc/erc-scenarios-base-reuse-buffers.el b/test/lisp/erc/erc-scenarios-base-reuse-buffers.el
new file mode 100644
index 00000000000..f134f3ffb69
--- /dev/null
+++ b/test/lisp/erc/erc-scenarios-base-reuse-buffers.el
@@ -0,0 +1,238 @@
+;;; erc-scenarios-base-reuse-buffers.el --- base-reuse-buffers scenarios -*- lexical-binding: t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+;;
+;; This file is part of GNU Emacs.
+;;
+;; This program is free software: you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation, either version 3 of the
+;; License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see
+;; <https://www.gnu.org/licenses/>.
+
+(require 'ert-x)
+(eval-and-compile
+ (let ((load-path (cons (ert-resource-directory) load-path)))
+ (require 'erc-scenarios-common)))
+
+(eval-when-compile (require 'erc-join))
+
+(defun erc-scenarios-common--base-reuse-buffers-server-buffers (&optional more)
+ "Show that `erc-reuse-buffers' doesn't affect server buffers.
+Overlaps some with `clash-of-chans/uniquify'. Adapted from
+rebuffed/reuseless, described in Bug#48598: 28.0.50; buffer-naming
+collisions involving bouncers in ERC. Run EXTRA."
+ (erc-scenarios-common-with-cleanup
+ ((dumb-server (erc-d-run "localhost" t 'foonet 'barnet))
+ (port (process-contact dumb-server :service))
+ erc-autojoin-channels-alist)
+
+ (ert-info ("Connect to foonet")
+ (with-current-buffer (erc :server "127.0.0.1"
+ :port port
+ :nick "tester"
+ :password "foonet:changeme"
+ :full-name "tester")
+ (should (string= (buffer-name)
+ (format "127.0.0.1:%d/127.0.0.1" port)))
+ (erc-d-t-search-for 12 "marked as being away")))
+
+ (ert-info ("Connect to barnet")
+ (with-current-buffer (erc :server "127.0.0.1"
+ :port port
+ :nick "tester"
+ :password "barnet:changeme"
+ :full-name "tester")
+ (should (string= (buffer-name)
+ (format "127.0.0.1:%d/127.0.0.1<2>" port)))
+ (erc-d-t-search-for 45 "marked as being away")))
+
+ (erc-d-t-wait-for 2 (get-buffer (format "127.0.0.1:%d/127.0.0.1" port)))
+ (erc-d-t-wait-for 2 (get-buffer (format "127.0.0.1:%d/127.0.0.1<2>" port)))
+
+ (ert-info ("Server buffers are unique, no IP-based names")
+ (should (cdr (erc-scenarios-common-buflist "127.0.0.1"))))
+ (when more (funcall more port))))
+
+;; XXX maybe remove: already covered many times over by other scenarios
+(ert-deftest erc-scenarios-base-reuse-buffers-server-buffers--enabled ()
+ :tags '(:expensive-test)
+ (with-suppressed-warnings ((obsolete erc-reuse-buffers))
+ (should erc-reuse-buffers))
+ (let ((erc-scenarios-common-dialog "base/reuse-buffers/server"))
+ (erc-scenarios-common-with-cleanup
+ ((dumb-server (erc-d-run "localhost" t 'foonet 'barnet))
+ (port (process-contact dumb-server :service))
+ erc-autojoin-channels-alist)
+
+ (ert-info ("Connect to foonet")
+ (with-current-buffer (erc :server "127.0.0.1"
+ :port port
+ :nick "tester"
+ :password "foonet:changeme"
+ :full-name "tester")
+ (should (string= (buffer-name) (format "127.0.0.1:%d" port)))
+ (erc-d-t-search-for 12 "marked as being away")))
+
+ (ert-info ("Connect to barnet")
+ (with-current-buffer (erc :server "127.0.0.1"
+ :port port
+ :nick "tester"
+ :password "barnet:changeme"
+ :full-name "tester")
+ (should (string= (buffer-name) (format "127.0.0.1:%d" port)))
+ (erc-d-t-search-for 45 "marked as being away")))
+
+ (erc-d-t-wait-for 2 (get-buffer "foonet"))
+ (erc-d-t-wait-for 2 (get-buffer "barnet"))
+
+ (ert-info ("Server buffers are unique, no IP-based names")
+ (should-not (eq (get-buffer "foonet") (get-buffer "barnet")))
+ (should-not (erc-scenarios-common-buflist "127.0.0.1"))))))
+
+;; FIXME no sense in running this twice (JOIN variant includes this)
+(ert-deftest erc-scenarios-base-reuse-buffers-server-buffers--disabled ()
+ :tags '(:expensive-test)
+ (with-suppressed-warnings ((obsolete erc-reuse-buffers))
+ (should erc-reuse-buffers)
+ (let ((erc-scenarios-common-dialog "base/reuse-buffers/server")
+ erc-reuse-buffers)
+ (erc-scenarios-common--base-reuse-buffers-server-buffers nil))))
+
+;; This also asserts that `erc-cmd-JOIN' is no longer susceptible to a
+;; regression introduced in 28.1 (ERC 5.4) that caused phantom target
+;; buffers of the form target/server to be created via
+;; `switch-to-buffer' ("phantom" because they would go unused"). This
+;; would happen (in place of a JOIN being sent out) when a previously
+;; used (parted) target buffer existed and `erc-reuse-buffers' was
+;; nil.
+;;
+;; Note: All the `erc-get-channel-user' calls have to do with the fact
+;; that `erc-default-target' relies on the ambiguously defined
+;; `erc-default-recipients' (meaning it's overloaded in the sense of
+;; being used both for retrieving a target name and checking if a
+;; channel has been PARTed). While not ideal, `erc-get-channel-user'
+;; can (also) be used to detect the latter.
+
+(defun erc-scenarios-common--base-reuse-buffers-channel-buffers (port)
+ "The option `erc-reuse-buffers' is still respected when nil.
+Adapted from scenario clash-of-chans/uniquify described in Bug#48598:
+28.0.50; buffer-naming collisions involving bouncers in ERC."
+ (let* ((expect (erc-d-t-make-expecter))
+ (server-buffer-foo
+ (get-buffer (format "127.0.0.1:%d/127.0.0.1" port)))
+ (server-buffer-bar
+ (get-buffer (format "127.0.0.1:%d/127.0.0.1<2>" port)))
+ (chan-buffer-foo (get-buffer "#chan/127.0.0.1"))
+ (chan-buffer-bar (get-buffer "#chan/127.0.0.1<2>"))
+ (server-process-foo (with-current-buffer server-buffer-foo
+ erc-server-process))
+ (server-process-bar (with-current-buffer server-buffer-bar
+ erc-server-process)))
+
+ (ert-info ("Unique #chan buffers exist")
+ (let ((chan-bufs (erc-scenarios-common-buflist "#chan"))
+ (known (list chan-buffer-bar chan-buffer-foo)))
+ (should (memq (pop chan-bufs) known))
+ (should (memq (pop chan-bufs) known))
+ (should-not chan-bufs)))
+
+ (ert-info ("#chan@foonet is exclusive and not contaminated")
+ (with-current-buffer chan-buffer-foo
+ (funcall expect 1 "<bob>")
+ (erc-d-t-absent-for 0.1 "<joe>")
+ (funcall expect 1 "strength to climb")
+ (should (eq erc-server-process server-process-foo))))
+
+ (ert-info ("#chan@barnet is exclusive and not contaminated")
+ (with-current-buffer chan-buffer-bar
+ (funcall expect 1 "<joe>")
+ (erc-d-t-absent-for 0.1 "<bob>")
+ (funcall expect 1 "the loudest noise")
+ (should (eq erc-server-process server-process-bar))))
+
+ (ert-info ("Part #chan@foonet")
+ (with-current-buffer chan-buffer-foo
+ (erc-d-t-search-for 1 "shake my sword")
+ (erc-cmd-PART "#chan")
+ (funcall expect 3 "You have left channel #chan")
+ (erc-cmd-JOIN "#chan")))
+
+ (ert-info ("Part #chan@barnet")
+ (with-current-buffer chan-buffer-bar
+ (funcall expect 10 "Arm it in rags")
+ (should (erc-get-channel-user (erc-current-nick)))
+ (erc-cmd-PART "#chan")
+ (funcall expect 3 "You have left channel #chan")
+ (should-not (erc-get-channel-user (erc-current-nick)))
+ (erc-cmd-JOIN "#chan")))
+
+ (erc-d-t-wait-for 3 "New unique target buffer for #chan@foonet created"
+ (get-buffer "#chan/127.0.0.1<3>"))
+
+ (ert-info ("Activity continues in new, <n>-suffixed #chan@foonet buffer")
+ (with-current-buffer chan-buffer-foo
+ (should-not (erc-get-channel-user (erc-current-nick))))
+ (with-current-buffer "#chan/127.0.0.1<3>"
+ (should (erc-get-channel-user (erc-current-nick)))
+ (funcall expect 2 "You have joined channel #chan")
+ (funcall expect 2 "#chan was created on")
+ (funcall expect 2 "<alice>")
+ (should (eq erc-server-process server-process-foo))
+ (erc-d-t-absent-for 0.2 "<joe>")))
+
+ (sit-for 3)
+ (erc-d-t-wait-for 5 "New unique target buffer for #chan@barnet created"
+ (get-buffer "#chan/127.0.0.1<4>"))
+
+ (ert-info ("Activity continues in new, <n>-suffixed #chan@barnet buffer")
+ (with-current-buffer chan-buffer-bar
+ (should-not (erc-get-channel-user (erc-current-nick))))
+ (with-current-buffer "#chan/127.0.0.1<4>"
+ (funcall expect 2 "You have joined channel #chan")
+ (funcall expect 1 "Users on #chan: @mike joe tester")
+ (funcall expect 2 "<mike>")
+ (should (eq erc-server-process server-process-bar))
+ (erc-d-t-absent-for 0.2 "<bob>")))
+
+ (ert-info ("Two new chans created for a total of four")
+ (let* ((bufs (erc-scenarios-common-buflist "#chan"))
+ (names (sort (mapcar #'buffer-name bufs) #'string<)))
+ (should
+ (equal names (mapcar (lambda (f) (concat "#chan/127.0.0.1" f))
+ '("" "<2>" "<3>" "<4>"))))))
+
+ (ert-info ("All output sent")
+ (with-current-buffer "#chan/127.0.0.1<3>"
+ (funcall expect 10 "most lively"))
+ (with-current-buffer "#chan/127.0.0.1<4>"
+ (funcall expect 10 "soul black")))
+
+ ;; TODO ensure the exact <N>'s aren't reassigned during killing as
+ ;; they are when the option is on.
+ (ert-info ("Buffers are exempt from shortening")
+ (kill-buffer "#chan/127.0.0.1<4>")
+ (kill-buffer "#chan/127.0.0.1<3>")
+ (kill-buffer chan-buffer-bar)
+ (should-not (get-buffer "#chan"))
+ (should chan-buffer-foo))))
+
+(ert-deftest erc-scenarios-base-reuse-buffers-channel-buffers--disabled ()
+ :tags '(:expensive-test :unstable)
+ (with-suppressed-warnings ((obsolete erc-reuse-buffers))
+ (should erc-reuse-buffers)
+ (let ((erc-scenarios-common-dialog "base/reuse-buffers/channel")
+ (erc-server-flood-penalty 0.1)
+ erc-reuse-buffers)
+ (erc-scenarios-common--base-reuse-buffers-server-buffers
+ #'erc-scenarios-common--base-reuse-buffers-channel-buffers))))
+
+;;; erc-scenarios-base-reuse-buffers.el ends here
diff --git a/test/lisp/erc/erc-scenarios-base-unstable.el b/test/lisp/erc/erc-scenarios-base-unstable.el
new file mode 100644
index 00000000000..2313a15842c
--- /dev/null
+++ b/test/lisp/erc/erc-scenarios-base-unstable.el
@@ -0,0 +1,134 @@
+;;; erc-scenarios-base-unstable.el --- base unstable scenarios -*- lexical-binding: t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+;;
+;; This file is part of GNU Emacs.
+;;
+;; This program is free software: you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation, either version 3 of the
+;; License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see
+;; <https://www.gnu.org/licenses/>.
+
+(require 'ert-x)
+(eval-and-compile
+ (let ((load-path (cons (ert-resource-directory) load-path)))
+ (require 'erc-scenarios-common)))
+
+(eval-when-compile (require 'erc-join))
+
+;; Not unstable, but stashed here for now
+
+(ert-deftest erc-scenarios-aux-unix-socket ()
+ :tags '(:expensive-test)
+ (skip-unless (featurep 'make-network-process '(:family local)))
+ (erc-scenarios-common-with-cleanup
+ ((erc-scenarios-common-dialog "base/renick/self")
+ (erc-server-flood-penalty 0.1)
+ (sock (expand-file-name "erc-d.sock" temporary-file-directory))
+ (erc-scenarios-common-extra-teardown (lambda () (delete-file sock)))
+ (erc-server-connect-function
+ (lambda (n b _ p &rest r)
+ (apply #'make-network-process
+ `(:name ,n :buffer ,b :service ,p :family local ,@r))))
+ (dumb-server (erc-d-run nil sock 'auto))
+ erc-autojoin-channels-alist
+ erc-server-buffer-foo)
+
+ (ert-info ("Connect to foonet")
+ (setq erc-server-buffer-foo (erc :server "fake"
+ :port sock
+ :nick "tester"
+ :password "foonet:changeme"
+ :full-name "tester"))
+ (with-current-buffer erc-server-buffer-foo
+ (should (string= (buffer-name) (format "fake:%s" sock)))))
+
+ (with-current-buffer (erc-d-t-wait-for 3 (get-buffer "foonet"))
+ (erc-d-t-search-for 10 "Your new nickname is dummy"))
+
+ (ert-info ("Joined by bouncer to #foo, own nick present")
+ (with-current-buffer (erc-d-t-wait-for 3 (get-buffer "#foo"))
+ (erc-d-t-search-for 10 "dummy")
+ (erc-d-t-search-for 10 "On Thursday")))))
+
+;; See `erc-networks--rename-server-buffer'. A perceived loss in
+;; network connectivity turns out to be a false alarm, but the bouncer
+;; has already accepted the second connection
+
+(defun erc-scenarios--base-aborted-reconnect ()
+ (erc-scenarios-common-with-cleanup
+ ((erc-scenarios-common-dialog "base/reconnect")
+ (erc-d-t-cleanup-sleep-secs 1)
+ (dumb-server (erc-d-run "localhost" t 'aborted 'aborted-dupe))
+ (port (process-contact dumb-server :service))
+ erc-autojoin-channels-alist
+ erc-server-buffer-foo)
+
+ (ert-info ("Connect to foonet")
+ (setq erc-server-buffer-foo (erc :server "127.0.0.1"
+ :port port
+ :nick "tester"
+ :password "changeme"
+ :full-name "tester"))
+ (with-current-buffer erc-server-buffer-foo
+ (should (string= (buffer-name) (format "127.0.0.1:%d" port)))))
+
+ (ert-info ("Server buffer is unique and temp name is absent")
+ (erc-d-t-wait-for 10 (get-buffer "FooNet"))
+ (should-not (erc-scenarios-common-buflist "127.0.0.1"))
+ (with-current-buffer erc-server-buffer-foo
+ (erc-cmd-JOIN "#chan")))
+
+ (ert-info ("Channel buffer #chan alive and well")
+ (with-current-buffer (erc-d-t-wait-for 4 (get-buffer "#chan"))
+ (erc-d-t-search-for 10 "welcome")))
+
+ (ert-info ("Connect to foonet again")
+ (setq erc-server-buffer-foo (erc :server "127.0.0.1"
+ :port port
+ :nick "tester"
+ :password "changeme"
+ :full-name "tester"))
+ (let ((inhibit-message noninteractive))
+ (with-current-buffer erc-server-buffer-foo
+ (should (string= (buffer-name) (format "127.0.0.1:%d" port)))
+ (erc-d-t-wait-for 5 (not (erc-server-process-alive)))
+ (erc-d-t-search-for 10 "FooNet still connected"))))
+
+ (ert-info ("Server buffer is unique and temp name is absent")
+ (should (equal (list (get-buffer "FooNet"))
+ (erc-scenarios-common-buflist "FooNet")))
+ (should (equal (list (get-buffer (format "127.0.0.1:%d" port)))
+ (erc-scenarios-common-buflist "127.0.0.1"))))
+
+ (ert-info ("Channel buffer #chan still going")
+ (with-current-buffer "#chan"
+ (erc-d-t-search-for 10 "and be prosperous")))))
+
+(ert-deftest erc-scenarios-base-aborted-reconnect ()
+ :tags '(:unstable)
+ (let ((tries 3)
+ (timeout 1)
+ failed)
+ (while (condition-case _err
+ (progn
+ (erc-scenarios--base-aborted-reconnect)
+ nil)
+ (ert-test-failed
+ (message "Test %S failed; %s attempt(s) remaining."
+ (ert-test-name (ert-running-test))
+ tries)
+ (sleep-for (cl-incf timeout))
+ (not (setq failed (zerop (cl-decf tries)))))))
+ (should-not failed)))
+
+;;; erc-scenarios-base-unstable.el ends here
diff --git a/test/lisp/erc/erc-scenarios-base-upstream-recon-soju.el b/test/lisp/erc/erc-scenarios-base-upstream-recon-soju.el
new file mode 100644
index 00000000000..5a5b363f31d
--- /dev/null
+++ b/test/lisp/erc/erc-scenarios-base-upstream-recon-soju.el
@@ -0,0 +1,43 @@
+;;; erc-scenarios-upstream-recon-soju.el --- Upstream soju -*- lexical-binding: t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+;;
+;; This file is part of GNU Emacs.
+;;
+;; This program is free software: you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation, either version 3 of the
+;; License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see
+;; <https://www.gnu.org/licenses/>.
+
+;; Commentary:
+;;
+;; These concern the loss and recovery of a proxy's IRC-side connection.
+
+(require 'ert-x)
+(eval-and-compile
+ (let ((load-path (cons (ert-resource-directory) load-path)))
+ (require 'erc-scenarios-common)))
+
+(ert-deftest erc-scenarios-upstream-recon--soju ()
+ :tags '(:expensive-test)
+ (erc-scenarios-common--upstream-reconnect
+ (lambda ()
+ (with-current-buffer "foonet"
+ (erc-d-t-search-for 1 "disconnected from foonet")
+ (erc-d-t-search-for 1 "connected from foonet"))
+ (with-current-buffer "barnet"
+ (erc-d-t-search-for 1 "disconnected from barnet")
+ (erc-d-t-search-for 1 "connected from barnet")))
+ 'soju-foonet
+ 'soju-barnet))
+
+;;; erc-scenarios-upstream-recon-soju.el ends here
diff --git a/test/lisp/erc/erc-scenarios-base-upstream-recon-znc.el b/test/lisp/erc/erc-scenarios-base-upstream-recon-znc.el
new file mode 100644
index 00000000000..6e9a2172459
--- /dev/null
+++ b/test/lisp/erc/erc-scenarios-base-upstream-recon-znc.el
@@ -0,0 +1,43 @@
+;;; erc-scenarios-upstream-recon-znc.el --- Upstream znc -*- lexical-binding: t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+;;
+;; This file is part of GNU Emacs.
+;;
+;; This program is free software: you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation, either version 3 of the
+;; License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see
+;; <https://www.gnu.org/licenses/>.
+
+;; Commentary:
+;;
+;; These concern the loss and recovery of a proxy's IRC-side connection.
+
+(require 'ert-x)
+(eval-and-compile
+ (let ((load-path (cons (ert-resource-directory) load-path)))
+ (require 'erc-scenarios-common)))
+
+(ert-deftest erc-scenarios-upstream-recon--znc ()
+ :tags '(:expensive-test)
+ (erc-scenarios-common--upstream-reconnect
+ (lambda ()
+ (with-current-buffer "*status@foonet"
+ (erc-d-t-search-for 1 "Disconnected from IRC")
+ (erc-d-t-search-for 1 "Connected!"))
+ (with-current-buffer "*status@barnet"
+ (erc-d-t-search-for 1 "Disconnected from IRC")
+ (erc-d-t-search-for 1 "Connected!")))
+ 'znc-foonet
+ 'znc-barnet))
+
+;;; erc-scenarios-upstream-recon-znc.el ends here
diff --git a/test/lisp/erc/erc-scenarios-internal.el b/test/lisp/erc/erc-scenarios-internal.el
new file mode 100644
index 00000000000..e4e1edb97e3
--- /dev/null
+++ b/test/lisp/erc/erc-scenarios-internal.el
@@ -0,0 +1,27 @@
+;;; erc-scenarios-internal.el --- Proxy file for erc-d tests -*- lexical-binding: t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+;;
+;; This file is part of GNU Emacs.
+;;
+;; This program is free software: you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation, either version 3 of the
+;; License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see
+;; <https://www.gnu.org/licenses/>.
+
+(require 'ert-x)
+(eval-and-compile
+ (let ((load-path (cons (expand-file-name "erc-d" (ert-resource-directory))
+ load-path)))
+ (load "erc-d-tests" nil 'silent)))
+
+;;; erc-scenarios-internal.el ends here
diff --git a/test/lisp/erc/erc-scenarios-join-auth-source.el b/test/lisp/erc/erc-scenarios-join-auth-source.el
new file mode 100644
index 00000000000..94336db07c5
--- /dev/null
+++ b/test/lisp/erc/erc-scenarios-join-auth-source.el
@@ -0,0 +1,67 @@
+;;; erc-scenarios-join-auth-source.el --- join-auth-source scenarios -*- lexical-binding: t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+;;
+;; This file is part of GNU Emacs.
+;;
+;; This program is free software: you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation, either version 3 of the
+;; License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see
+;; <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; TODO add another test with autojoin and channel keys
+
+(require 'ert-x)
+(eval-and-compile
+ (let ((load-path (cons (ert-resource-directory) load-path)))
+ (require 'erc-scenarios-common)))
+
+(ert-deftest erc-scenarios-join-auth-source--network ()
+ :tags '(:expensive-test)
+ (should erc-auth-source-join-function)
+ (erc-scenarios-common-with-cleanup
+ ((entries
+ '("machine 127.0.0.1 port %d login \"#foo\" password spam"
+ "machine irc.foonet.org port %d login tester password fake"
+ "machine irc.foonet.org login \"#spam\" password secret"
+ "machine foonet port %d login dummy password fake"
+ "machine 127.0.0.1 port %d login dummy password changeme"))
+ (erc-scenarios-common-dialog "join/auth-source")
+ (erc-server-flood-penalty 0.1)
+ (dumb-server (erc-d-run "localhost" t 'foonet))
+ (port (process-contact dumb-server :service))
+ (ents (mapcar (lambda (fmt) (format fmt port)) entries))
+ (netrc-file (make-temp-file "auth-source-test" nil nil
+ (string-join ents "\n")))
+ (auth-sources (list netrc-file))
+ (auth-source-do-cache nil)
+ (expect (erc-d-t-make-expecter))
+ (erc-scenarios-common-extra-teardown (lambda ()
+ (delete-file netrc-file))))
+
+ (ert-info ("Connect without password")
+ (with-current-buffer (erc :server "127.0.0.1"
+ :port port
+ :nick "dummy"
+ :full-name "dummy")
+ (should (string= (buffer-name) (format "127.0.0.1:%d" port)))
+ (erc-d-t-wait-for 8 (eq erc-network 'foonet))
+ (funcall expect 10 "user modes")
+ (erc-scenarios-common-say "/JOIN #spam")))
+
+ (ert-info ("Join #spam")
+ (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "#spam"))
+ (funcall expect 10 "#spam was created on")))))
+
+;;; erc-scenarios-join-auth-source.el ends here
diff --git a/test/lisp/erc/erc-scenarios-join-netid-newcmd-id.el b/test/lisp/erc/erc-scenarios-join-netid-newcmd-id.el
new file mode 100644
index 00000000000..e2e437321d9
--- /dev/null
+++ b/test/lisp/erc/erc-scenarios-join-netid-newcmd-id.el
@@ -0,0 +1,50 @@
+;;; erc-scenarios-join-netid-newcmd-id.el --- join netid newcmd scenarios -*- lexical-binding: t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+;;
+;; This file is part of GNU Emacs.
+;;
+;; This program is free software: you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation, either version 3 of the
+;; License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see
+;; <https://www.gnu.org/licenses/>.
+
+(require 'ert-x)
+(eval-and-compile
+ (let ((load-path (cons (ert-resource-directory) load-path)))
+ (require 'erc-scenarios-common)))
+
+(ert-deftest erc-scenarios-join-netid--newcmd-id ()
+ :tags '(:expensive-test)
+ (let ((connect (lambda ()
+ (erc :server "127.0.0.1"
+ :port (with-current-buffer "oofnet"
+ (process-contact erc-server-process :service))
+ :nick "tester"
+ :password "foonet:changeme"
+ :full-name "tester"
+ :id 'oofnet))))
+ (erc-scenarios-common--join-network-id connect 'oofnet nil)))
+
+(ert-deftest erc-scenarios-join-netid--newcmd-ids ()
+ :tags '(:expensive-test)
+ (let ((connect (lambda ()
+ (erc :server "127.0.0.1"
+ :port (with-current-buffer "oofnet"
+ (process-contact erc-server-process :service))
+ :nick "tester"
+ :password "foonet:changeme"
+ :full-name "tester"
+ :id 'oofnet))))
+ (erc-scenarios-common--join-network-id connect 'oofnet 'rabnet)))
+
+;;; erc-scenarios-join-netid-newcmd-id.el ends here
diff --git a/test/lisp/erc/erc-scenarios-join-netid-newcmd.el b/test/lisp/erc/erc-scenarios-join-netid-newcmd.el
new file mode 100644
index 00000000000..1a541a46b3f
--- /dev/null
+++ b/test/lisp/erc/erc-scenarios-join-netid-newcmd.el
@@ -0,0 +1,37 @@
+;;; erc-scenarios-join-netid-newcmd.el --- join netid newcmd scenarios -*- lexical-binding: t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+;;
+;; This file is part of GNU Emacs.
+;;
+;; This program is free software: you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation, either version 3 of the
+;; License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see
+;; <https://www.gnu.org/licenses/>.
+
+(require 'ert-x)
+(eval-and-compile
+ (let ((load-path (cons (ert-resource-directory) load-path)))
+ (require 'erc-scenarios-common)))
+
+(ert-deftest erc-scenarios-join-netid--newcmd ()
+ :tags '(:expensive-test)
+ (let ((connect (lambda ()
+ (erc :server "127.0.0.1"
+ :port (with-current-buffer "foonet"
+ (process-contact erc-server-process :service))
+ :nick "tester"
+ :password "foonet:changeme"
+ :full-name "tester"))))
+ (erc-scenarios-common--join-network-id connect nil nil)))
+
+;;; erc-scenarios-join-netid-newcmd.el ends here
diff --git a/test/lisp/erc/erc-scenarios-join-netid-recon-id.el b/test/lisp/erc/erc-scenarios-join-netid-recon-id.el
new file mode 100644
index 00000000000..92bdd643de8
--- /dev/null
+++ b/test/lisp/erc/erc-scenarios-join-netid-recon-id.el
@@ -0,0 +1,46 @@
+;;; erc-scenarios-join-netid-recon-id.el --- join-netid-recon scenarios -*- lexical-binding: t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+;;
+;; This file is part of GNU Emacs.
+;;
+;; This program is free software: you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation, either version 3 of the
+;; License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see
+;; <https://www.gnu.org/licenses/>.
+
+(require 'ert-x)
+(eval-and-compile
+ (let ((load-path (cons (ert-resource-directory) load-path)))
+ (require 'erc-scenarios-common)))
+
+(ert-deftest erc-scenarios-join-netid--recon-id ()
+ :tags '(:expensive-test)
+ (let ((connect (lambda ()
+ (with-current-buffer "oofnet"
+ (erc-cmd-RECONNECT)
+ (should (eq (current-buffer)
+ (process-buffer erc-server-process)))
+ (current-buffer)))))
+ (erc-scenarios-common--join-network-id connect 'oofnet nil)))
+
+(ert-deftest erc-scenarios-join-netid--recon-ids ()
+ :tags '(:expensive-test)
+ (let ((connect (lambda ()
+ (with-current-buffer "oofnet"
+ (erc-cmd-RECONNECT)
+ (should (eq (current-buffer)
+ (process-buffer erc-server-process)))
+ (current-buffer)))))
+ (erc-scenarios-common--join-network-id connect 'oofnet 'rabnet)))
+
+;;; erc-scenarios-join-netid-recon-id.el ends here
diff --git a/test/lisp/erc/erc-scenarios-join-netid-recon.el b/test/lisp/erc/erc-scenarios-join-netid-recon.el
new file mode 100644
index 00000000000..cbdba07e256
--- /dev/null
+++ b/test/lisp/erc/erc-scenarios-join-netid-recon.el
@@ -0,0 +1,36 @@
+;;; erc-scenarios-join-netid-recon.el --- join-netid-recon scenarios -*- lexical-binding: t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+;;
+;; This file is part of GNU Emacs.
+;;
+;; This program is free software: you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation, either version 3 of the
+;; License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see
+;; <https://www.gnu.org/licenses/>.
+
+(require 'ert-x)
+(eval-and-compile
+ (let ((load-path (cons (ert-resource-directory) load-path)))
+ (require 'erc-scenarios-common)))
+
+(ert-deftest erc-scenarios-join-netid--recon ()
+ :tags '(:expensive-test)
+ (let ((connect (lambda ()
+ (with-current-buffer "foonet"
+ (erc-cmd-RECONNECT)
+ (should (eq (current-buffer)
+ (process-buffer erc-server-process)))
+ (current-buffer)))))
+ (erc-scenarios-common--join-network-id connect nil nil)))
+
+;;; erc-scenarios-join-netid-recon.el ends here
diff --git a/test/lisp/erc/erc-scenarios-misc.el b/test/lisp/erc/erc-scenarios-misc.el
new file mode 100644
index 00000000000..9d6d5bc1d6a
--- /dev/null
+++ b/test/lisp/erc/erc-scenarios-misc.el
@@ -0,0 +1,141 @@
+;;; erc-scenarios-misc.el --- Misc scenarios for ERC -*- lexical-binding: t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+;;
+;; This file is part of GNU Emacs.
+;;
+;; This program is free software: you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation, either version 3 of the
+;; License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see
+;; <https://www.gnu.org/licenses/>.
+
+(require 'ert-x)
+(eval-and-compile
+ (let ((load-path (cons (ert-resource-directory) load-path)))
+ (require 'erc-scenarios-common)))
+
+(eval-when-compile (require 'erc-join))
+
+(ert-deftest erc-scenarios-base-flood ()
+ :tags '(:expensive-test)
+ (erc-scenarios-common-with-cleanup
+ ((erc-scenarios-common-dialog "base/flood")
+ (dumb-server (erc-d-run "localhost" t 'soju))
+ (port (process-contact dumb-server :service))
+ (erc-server-flood-penalty 0.5) ; this ratio MUST match
+ (erc-server-flood-margin 1.5) ; the default of 3:10
+ (expect (erc-d-t-make-expecter))
+ erc-autojoin-channels-alist)
+
+ (ert-info ("Connect to bouncer")
+ (with-current-buffer
+ (erc :server "127.0.0.1"
+ :port port
+ :nick "tester"
+ :password "changeme"
+ :full-name "tester")
+ (should (string= (buffer-name) (format "127.0.0.1:%d" port)))
+ (funcall expect 5 "Soju")))
+
+ (ert-info ("#chan@foonet exists")
+ (with-current-buffer (erc-d-t-wait-for 5 (get-buffer "#chan/foonet"))
+ (erc-d-t-search-for 2 "<bob/foonet>")
+ (erc-d-t-absent-for 0.1 "<joe")
+ (funcall expect 3 "was created on")))
+
+ (ert-info ("#chan@barnet exists")
+ (with-current-buffer (erc-d-t-wait-for 5 (get-buffer "#chan/barnet"))
+ (erc-d-t-search-for 2 "<joe/barnet>")
+ (erc-d-t-absent-for 0.1 "<bob")
+ (funcall expect 3 "was created on")
+ (funcall expect 5 "To get good guard")))
+
+ (ert-info ("Message not held in queue limbo")
+ (with-current-buffer "#chan/foonet"
+ ;; Without 'no-penalty param in `erc-server-send', should fail
+ ;; after ~10 secs with:
+ ;;
+ ;; (erc-d-timeout "Timed out awaiting request: (:name ~privmsg
+ ;; :pattern \\`PRIVMSG #chan/foonet :alice: hi :timeout 2
+ ;; :dialog soju)")
+ ;;
+ ;; Try reversing commit and spying on queue interactively
+ (erc-cmd-MSG "#chan/foonet alice: hi")
+ (funcall expect 5 "tester: Good, very good")))
+
+ (ert-info ("All output sent")
+ (with-current-buffer "#chan/foonet"
+ (funcall expect 8 "Some man or other"))
+ (with-current-buffer "#chan/barnet"
+ (funcall expect 10 "That's he that was Othello")))))
+
+;; Corner case demoing fallback behavior for an absent 004 RPL but a
+;; present 422 or 375. If this is unlikely enough, remove or guard
+;; with `ert-skip' plus some condition so it only runs when explicitly
+;; named via ERT specifier
+
+(ert-deftest erc-scenarios-networks-announced-missing ()
+ :tags '(:expensive-test)
+ (erc-scenarios-common-with-cleanup
+ ((erc-scenarios-common-dialog "networks/announced-missing")
+ (expect (erc-d-t-make-expecter))
+ (dumb-server (erc-d-run "localhost" t 'foonet))
+ (port (process-contact dumb-server :service)))
+
+ (ert-info ("Connect without password")
+ (with-current-buffer (erc :server "127.0.0.1"
+ :port port
+ :nick "tester"
+ :full-name "tester")
+ (should (string= (buffer-name) (format "127.0.0.1:%d" port)))
+ (let ((err (should-error (sleep-for 1))))
+ (should (string-match-p "Failed to determine" (cadr err))))
+ (funcall expect 1 "Failed to determine")
+ (funcall expect 1 "Failed to determine")
+ (should-not erc-network)
+ (should (string= erc-server-announced-name "irc.foonet.org"))))))
+
+;; Targets that are host/server masks like $*, $$*, and #* are routed
+;; to the server buffer: https://github.com/ircdocs/wooooms/issues/5
+
+(ert-deftest erc-scenarios-base-mask-target-routing ()
+ :tags '(:expensive-test)
+ (erc-scenarios-common-with-cleanup
+ ((erc-scenarios-common-dialog "base/mask-target-routing")
+ (dumb-server (erc-d-run "localhost" t 'foonet))
+ (port (process-contact dumb-server :service))
+ (expect (erc-d-t-make-expecter)))
+
+ (ert-info ("Connect to foonet")
+ (with-current-buffer (erc :server "127.0.0.1"
+ :port port
+ :nick "tester"
+ :password "changeme"
+ :full-name "tester")
+ (should (string= (buffer-name) (format "127.0.0.1:%d" port)))))
+
+ (erc-d-t-wait-for 10 (get-buffer "foonet"))
+
+ (ert-info ("Channel buffer #foo playback received")
+ (with-current-buffer (erc-d-t-wait-for 3 (get-buffer "#foo"))
+ (funcall expect 10 "Excellent workman")))
+
+ (ert-info ("Global notices routed to server buffer")
+ (with-current-buffer "foonet"
+ (funcall expect 10 "going down soon")
+ (funcall expect 10 "this is a warning")
+ (funcall expect 10 "second warning")
+ (funcall expect 10 "final warning")))
+
+ (should-not (get-buffer "$*"))))
+
+;;; erc-scenarios-misc.el ends here
diff --git a/test/lisp/erc/erc-scenarios-services-misc.el b/test/lisp/erc/erc-scenarios-services-misc.el
new file mode 100644
index 00000000000..cb1aa6ff324
--- /dev/null
+++ b/test/lisp/erc/erc-scenarios-services-misc.el
@@ -0,0 +1,86 @@
+;;; erc-scenarios-services-misc.el --- Services-misc scenarios -*- lexical-binding: t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+;;
+;; This file is part of GNU Emacs.
+;;
+;; This program is free software: you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation, either version 3 of the
+;; License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see
+;; <https://www.gnu.org/licenses/>.
+
+(require 'ert-x)
+(eval-and-compile
+ (let ((load-path (cons (ert-resource-directory) load-path)))
+ (require 'erc-scenarios-common)))
+
+(eval-when-compile (require 'erc-join)
+ (require 'erc-services))
+
+(ert-deftest erc-scenarios-services-password ()
+ :tags '(:expensive-test)
+
+ (erc-scenarios-common-with-cleanup
+ ((erc-scenarios-common-dialog "services/password")
+ (erc-server-flood-penalty 0.1)
+ (erc-modules (cons 'services erc-modules))
+ (erc-nickserv-passwords '((Libera.Chat (("joe" . "bar")
+ ("tester" . "changeme")))))
+ (expect (erc-d-t-make-expecter))
+ (dumb-server (erc-d-run "localhost" t 'libera))
+ (port (process-contact dumb-server :service)))
+
+ (ert-info ("Connect without password")
+ (with-current-buffer (erc :server "127.0.0.1"
+ :port port
+ :nick "tester"
+ :full-name "tester")
+ (should (string= (buffer-name) (format "127.0.0.1:%d" port)))
+ (erc-d-t-wait-for 5 (eq erc-network 'Libera.Chat))
+ (funcall expect 5 "This nickname is registered.")
+ (funcall expect 2 "You are now identified")
+ (funcall expect 1 "Last login from")
+ (erc-cmd-QUIT "")))
+
+ (erc-services-mode -1)
+
+ (should-not (memq 'services erc-modules))))
+
+(ert-deftest erc-scenarios-services-prompt ()
+ :tags '(:expensive-test)
+ (erc-scenarios-common-with-cleanup
+ ((erc-scenarios-common-dialog "services/password")
+ (erc-server-flood-penalty 0.1)
+ (inhibit-interaction nil)
+ (erc-modules (cons 'services erc-modules))
+ (expect (erc-d-t-make-expecter))
+ (dumb-server (erc-d-run "localhost" t 'libera))
+ (port (process-contact dumb-server :service)))
+
+ (ert-info ("Connect without password")
+ (with-current-buffer (erc :server "127.0.0.1"
+ :port port
+ :nick "tester"
+ :full-name "tester")
+ (should (string= (buffer-name) (format "127.0.0.1:%d" port)))
+ (ert-simulate-keys "changeme\r"
+ (erc-d-t-wait-for 10 (eq erc-network 'Libera.Chat))
+ (funcall expect 3 "This nickname is registered.")
+ (funcall expect 3 "You are now identified")
+ (funcall expect 3 "Last login from"))
+ (erc-cmd-QUIT "")))
+
+ (erc-services-mode -1)
+
+ (should-not (memq 'services erc-modules))))
+
+;;; erc-scenarios-services-misc.el ends here
diff --git a/test/lisp/erc/erc-services-tests.el b/test/lisp/erc/erc-services-tests.el
new file mode 100644
index 00000000000..8e2b8d29273
--- /dev/null
+++ b/test/lisp/erc/erc-services-tests.el
@@ -0,0 +1,574 @@
+;;; erc-services-tests.el --- Tests for erc-services. -*- lexical-binding:t -*-
+
+;; Copyright (C) 2020-2022 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+;;
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published
+;; by the Free Software Foundation, either version 3 of the License,
+;; or (at your option) any later version.
+;;
+;; GNU Emacs is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; TODO: move the auth-source tests somewhere else. They've been
+;; stashed here for pragmatic reasons.
+
+;;; Code:
+
+(require 'ert-x)
+(require 'erc-services)
+(require 'erc-compat)
+(require 'secrets)
+
+;;;; Core auth-source
+
+(ert-deftest erc--auth-source-determine-params-merge ()
+ (let ((erc-session-server "irc.gnu.org")
+ (erc-server-announced-name "my.gnu.org")
+ (erc-session-port 6697)
+ (erc-network 'fake)
+ (erc-server-current-nick "tester")
+ (erc-networks--id (erc-networks--id-create 'GNU.chat)))
+
+ (should (equal (erc--auth-source-determine-params-merge)
+ '(:host ("GNU.chat" "my.gnu.org" "irc.gnu.org")
+ :port ("6697" "irc")
+ :require (:secret))))
+
+ (should (equal (erc--auth-source-determine-params-merge :host "fake")
+ '(:host ("fake" "GNU.chat" "my.gnu.org" "irc.gnu.org")
+ :port ("6697" "irc")
+ :require (:secret))))
+
+ (should (equal (erc--auth-source-determine-params-merge
+ :host '("fake") :require :host)
+ '(:host ("fake" "GNU.chat" "my.gnu.org" "irc.gnu.org")
+ :require (:host :secret)
+ :port ("6697" "irc"))))
+
+ (should (equal (erc--auth-source-determine-params-merge
+ :host '("fake" "GNU.chat") :port "1234" :x "x")
+ '(:host ("fake" "GNU.chat" "my.gnu.org" "irc.gnu.org")
+ :port ("1234" "6697" "irc")
+ :x ("x")
+ :require (:secret))))))
+
+;; Some of the following may be related to bug#23438.
+
+(defun erc-services-tests--auth-source-standard (search)
+
+ (ert-info ("Session wins")
+ (let ((erc-session-server "irc.gnu.org")
+ (erc-server-announced-name "my.gnu.org")
+ (erc-session-port 6697)
+ (erc-network 'fake)
+ (erc-server-current-nick "tester")
+ (erc-networks--id (erc-networks--id-create 'GNU.chat)))
+ (should (string= (funcall search :user "#chan") "foo"))))
+
+ (ert-info ("Network wins")
+ (let* ((erc-session-server "irc.gnu.org")
+ (erc-server-announced-name "my.gnu.org")
+ (erc-session-port 6697)
+ (erc-network 'GNU.chat)
+ (erc-server-current-nick "tester")
+ (erc-networks--id (erc-networks--id-create nil)))
+ (should (string= (funcall search :user "#chan") "foo"))))
+
+ (ert-info ("Announced wins")
+ (let ((erc-session-server "irc.gnu.org")
+ (erc-server-announced-name "my.gnu.org")
+ (erc-session-port 6697)
+ erc-network
+ (erc-networks--id (erc-networks--id-create nil)))
+ (should (string= (funcall search :user "#chan") "baz")))))
+
+(defun erc-services-tests--auth-source-announced (search)
+ (let* ((erc--isupport-params (make-hash-table))
+ (erc-server-parameters '(("CHANTYPES" . "&#")))
+ (erc--target (erc--target-from-string "&chan")))
+
+ (ert-info ("Announced prioritized")
+
+ (ert-info ("Announced wins")
+ (let* ((erc-session-server "irc.gnu.org")
+ (erc-server-announced-name "my.gnu.org")
+ (erc-session-port 6697)
+ (erc-network 'GNU.chat)
+ (erc-server-current-nick "tester")
+ (erc-networks--id (erc-networks--id-create nil)))
+ (should (string= (funcall search :user "#chan") "baz"))))
+
+ (ert-info ("Peer next")
+ (let* ((erc-server-announced-name "irc.gnu.org")
+ (erc-session-port 6697)
+ (erc-network 'GNU.chat)
+ (erc-server-current-nick "tester")
+ (erc-networks--id (erc-networks--id-create nil)))
+ (should (string= (funcall search :user "#chan") "bar"))))
+
+ (ert-info ("Network used as fallback")
+ (let* ((erc-session-port 6697)
+ (erc-network 'GNU.chat)
+ (erc-server-current-nick "tester")
+ (erc-networks--id (erc-networks--id-create nil)))
+ (should (string= (funcall search :user "#chan") "foo")))))))
+
+(defun erc-services-tests--auth-source-overrides (search)
+ (let* ((erc-session-server "irc.gnu.org")
+ (erc-server-announced-name "my.gnu.org")
+ (erc-network 'GNU.chat)
+ (erc-server-current-nick "tester")
+ (erc-networks--id (erc-networks--id-create nil))
+ (erc-session-port 6667))
+
+ (ert-info ("Specificity and overrides")
+
+ (ert-info ("More specific port")
+ (let ((erc-session-port 6697))
+ (should (string= (funcall search :user "#chan") "spam"))))
+
+ (ert-info ("More specific user (network loses)")
+ (should (string= (funcall search :user '("#fsf")) "42")))
+
+ (ert-info ("Actual override")
+ (should (string= (funcall search :port "6667") "sesame")))
+
+ (ert-info ("Overrides don't interfere with post-processing")
+ (should (string= (funcall search :host "MyHost") "123"))))))
+
+;; auth-source netrc backend
+
+(defvar erc-services-tests--auth-source-entries
+ '("machine irc.gnu.org port irc user \"#chan\" password bar"
+ "machine my.gnu.org port irc user \"#chan\" password baz"
+ "machine GNU.chat port irc user \"#chan\" password foo"))
+
+;; FIXME explain what this is for
+(defun erc-services-tests--auth-source-shuffle (&rest extra)
+ (string-join `(,@(sort (append erc-services-tests--auth-source-entries extra)
+ (lambda (&rest _) (zerop (random 2))))
+ "")
+ "\n"))
+
+(ert-deftest erc--auth-source-search--netrc-standard ()
+ (ert-with-temp-file netrc-file
+ :prefix "erc--auth-source-search--standard"
+ :text (erc-services-tests--auth-source-shuffle)
+
+ (let ((auth-sources (list netrc-file))
+ (auth-source-do-cache nil))
+ (erc-services-tests--auth-source-standard #'erc-auth-source-search))))
+
+(ert-deftest erc--auth-source-search--netrc-announced ()
+ (ert-with-temp-file netrc-file
+ :prefix "erc--auth-source-search--announced"
+ :text (erc-services-tests--auth-source-shuffle)
+
+ (let ((auth-sources (list netrc-file))
+ (auth-source-do-cache nil))
+ (erc-services-tests--auth-source-announced #'erc-auth-source-search))))
+
+(ert-deftest erc--auth-source-search--netrc-overrides ()
+ (ert-with-temp-file netrc-file
+ :prefix "erc--auth-source-search--overrides"
+ :text (erc-services-tests--auth-source-shuffle
+ "machine GNU.chat port 6697 user \"#chan\" password spam"
+ "machine my.gnu.org port irc user \"#fsf\" password 42"
+ "machine irc.gnu.org port 6667 password sesame"
+ "machine MyHost port irc password 456"
+ "machine MyHost port 6667 password 123")
+
+ (let ((auth-sources (list netrc-file))
+ (auth-source-do-cache nil))
+ (erc-services-tests--auth-source-overrides #'erc-auth-source-search))))
+
+;; auth-source plstore backend
+
+(defun erc-services-test--call-with-plstore (&rest args)
+ (advice-add 'epg-decrypt-string :override
+ (lambda (&rest r) (prin1-to-string (cadr r)))
+ '((name . erc--auth-source-plstore)))
+ (advice-add 'epg-find-configuration :override
+ (lambda (&rest _) "" '((program . "/bin/true")))
+ '((name . erc--auth-source-plstore)))
+ (unwind-protect
+ (apply #'erc-auth-source-search args)
+ (advice-remove 'epg-decrypt-string 'erc--auth-source-plstore)
+ (advice-remove 'epg-find-configuration 'erc--auth-source-plstore)))
+
+(defvar erc-services-tests--auth-source-plstore-standard-entries
+ '(("ba950d38118a76d71f9f0591bb373d6cb366a512"
+ :secret-secret t
+ :host "irc.gnu.org"
+ :user "#chan"
+ :port "irc")
+ ("7f17ca445d11158065e911a6d0f4cbf52ca250e3"
+ :secret-secret t
+ :host "my.gnu.org"
+ :user "#chan"
+ :port "irc")
+ ("fcd3c8bd6daf4509de0ad6ee98e744ce0fca9377"
+ :secret-secret t
+ :host "GNU.chat"
+ :user "#chan"
+ :port "irc")))
+
+(defvar erc-services-tests--auth-source-plstore-standard-secrets
+ '(("ba950d38118a76d71f9f0591bb373d6cb366a512" :secret "bar")
+ ("7f17ca445d11158065e911a6d0f4cbf52ca250e3" :secret "baz")
+ ("fcd3c8bd6daf4509de0ad6ee98e744ce0fca9377" :secret "foo")))
+
+(ert-deftest erc--auth-source-search--plstore-standard ()
+ (ert-with-temp-file plstore-file
+ :suffix ".plist"
+ :text (concat ";;; public entries -*- mode: plstore -*- \n"
+ (prin1-to-string
+ erc-services-tests--auth-source-plstore-standard-entries)
+ "\n;;; secret entries\n"
+ (prin1-to-string
+ erc-services-tests--auth-source-plstore-standard-secrets)
+ "\n")
+
+ (let ((auth-sources (list plstore-file))
+ (auth-source-do-cache nil))
+ (erc-services-tests--auth-source-standard
+ #'erc-services-test--call-with-plstore))))
+
+(ert-deftest erc--auth-source-search--plstore-announced ()
+ (ert-with-temp-file plstore-file
+ :suffix ".plist"
+ :text (concat ";;; public entries -*- mode: plstore -*- \n"
+ (prin1-to-string
+ erc-services-tests--auth-source-plstore-standard-entries)
+ "\n;;; secret entries\n"
+ (prin1-to-string
+ erc-services-tests--auth-source-plstore-standard-secrets)
+ "\n")
+
+ (let ((auth-sources (list plstore-file))
+ (auth-source-do-cache nil))
+ (erc-services-tests--auth-source-announced
+ #'erc-services-test--call-with-plstore))))
+
+(ert-deftest erc--auth-source-search--plstore-overrides ()
+ (ert-with-temp-file plstore-file
+ :suffix ".plist"
+ :text (concat
+ ";;; public entries -*- mode: plstore -*- \n"
+ (prin1-to-string
+ `(,@erc-services-tests--auth-source-plstore-standard-entries
+ ("1b3fab249a8dff77a4d8fe7eb4b0171b25cc711a"
+ :secret-secret t :host "GNU.chat" :user "#chan" :port "6697")
+ ("6cbcdc39476b8cfcca6f3e9a7876f41ec3f708cc"
+ :secret-secret t :host "my.gnu.org" :user "#fsf" :port "irc")
+ ("a33e2b3bd2d6f33995a4b88710a594a100c5e41d"
+ :secret-secret t :host "irc.gnu.org" :port "6667")
+ ("ab2fd349b2b7d6a9215bb35a92d054261b0b1537"
+ :secret-secret t :host "MyHost" :port "irc")
+ ("61a6bd552059494f479ff720e8de33e22574650a"
+ :secret-secret t :host "MyHost" :port "6667")))
+ "\n;;; secret entries\n"
+ (prin1-to-string
+ `(,@erc-services-tests--auth-source-plstore-standard-secrets
+ ("1b3fab249a8dff77a4d8fe7eb4b0171b25cc711a" :secret "spam")
+ ("6cbcdc39476b8cfcca6f3e9a7876f41ec3f708cc" :secret "42")
+ ("a33e2b3bd2d6f33995a4b88710a594a100c5e41d" :secret "sesame")
+ ("ab2fd349b2b7d6a9215bb35a92d054261b0b1537" :secret "456")
+ ("61a6bd552059494f479ff720e8de33e22574650a" :secret "123")))
+ "\n")
+
+ (let ((auth-sources (list plstore-file))
+ (auth-source-do-cache nil))
+ (erc-services-tests--auth-source-overrides
+ #'erc-services-test--call-with-plstore))))
+
+;; auth-source JSON backend
+
+(defvar erc-services-tests--auth-source-json-standard-entries
+ [(:host "irc.gnu.org" :port "irc" :user "#chan" :secret "bar")
+ (:host "my.gnu.org" :port "irc" :user "#chan" :secret "baz")
+ (:host "GNU.chat" :port "irc" :user "#chan" :secret "foo")])
+
+(ert-deftest erc--auth-source-search--json-standard ()
+ (ert-with-temp-file json-store
+ :suffix ".json"
+ :text (let ((json-object-type 'plist))
+ (json-encode
+ erc-services-tests--auth-source-json-standard-entries))
+ (let ((auth-sources (list json-store))
+ (auth-source-do-cache nil))
+ (erc-services-tests--auth-source-standard #'erc-auth-source-search))))
+
+(ert-deftest erc--auth-source-search--json-announced ()
+ (ert-with-temp-file plstore-file
+ :suffix ".json"
+ :text (let ((json-object-type 'plist))
+ (json-encode
+ erc-services-tests--auth-source-json-standard-entries))
+
+ (let ((auth-sources (list plstore-file))
+ (auth-source-do-cache nil))
+ (erc-services-tests--auth-source-announced #'erc-auth-source-search))))
+
+(ert-deftest erc--auth-source-search--json-overrides ()
+ (ert-with-temp-file json-file
+ :suffix ".json"
+ :text (let ((json-object-type 'plist))
+ (json-encode
+ (vconcat
+ erc-services-tests--auth-source-json-standard-entries
+ [(:secret "spam" :host "GNU.chat" :user "#chan" :port "6697")
+ (:secret "42" :host "my.gnu.org" :user "#fsf" :port "irc")
+ (:secret "sesame" :host "irc.gnu.org" :port "6667")
+ (:secret "456" :host "MyHost" :port "irc")
+ (:secret "123" :host "MyHost" :port "6667")])))
+
+ (let ((auth-sources (list json-file))
+ (auth-source-do-cache nil))
+ (erc-services-tests--auth-source-overrides #'erc-auth-source-search))))
+
+;; auth-source-secrets backend
+
+(defvar erc-services-tests--auth-source-secrets-standard-entries
+ '(("#chan@irc.gnu.org:irc" ; label
+ (:host . "irc.gnu.org")
+ (:user . "#chan")
+ (:port . "irc")
+ (:xdg:schema . "org.freedesktop.Secret.Generic"))
+ ("#chan@my.gnu.org:irc"
+ (:host . "my.gnu.org")
+ (:user . "#chan")
+ (:port . "irc")
+ (:xdg:schema . "org.freedesktop.Secret.Generic"))
+ ("#chan@GNU.chat:irc"
+ (:host . "GNU.chat")
+ (:user . "#chan")
+ (:port . "irc")
+ (:xdg:schema . "org.freedesktop.Secret.Generic"))))
+
+(defvar erc-services-tests--auth-source-secrets-standard-secrets
+ '(("#chan@irc.gnu.org:irc" . "bar")
+ ("#chan@my.gnu.org:irc" . "baz")
+ ("#chan@GNU.chat:irc" . "foo")))
+
+(ert-deftest erc--auth-source-search--secrets-standard ()
+ (skip-unless (bound-and-true-p secrets-enabled))
+ (let ((auth-sources '("secrets:Test"))
+ (auth-source-do-cache nil)
+ (entries erc-services-tests--auth-source-secrets-standard-entries)
+ (secrets erc-services-tests--auth-source-secrets-standard-secrets))
+
+ (cl-letf (((symbol-function 'secrets-search-items)
+ (lambda (col &rest r)
+ (should (equal col "Test"))
+ (should (plist-get r :user))
+ (map-keys entries)))
+ ((symbol-function 'secrets-get-secret)
+ (lambda (col label)
+ (should (equal col "Test"))
+ (assoc-default label secrets)))
+ ((symbol-function 'secrets-get-attributes)
+ (lambda (col label)
+ (should (equal col "Test"))
+ (assoc-default label entries))))
+
+ (erc-services-tests--auth-source-standard #'erc-auth-source-search))))
+
+(ert-deftest erc--auth-source-search--secrets-announced ()
+ (skip-unless (bound-and-true-p secrets-enabled))
+ (let ((auth-sources '("secrets:Test"))
+ (auth-source-do-cache nil)
+ (entries erc-services-tests--auth-source-secrets-standard-entries)
+ (secrets erc-services-tests--auth-source-secrets-standard-secrets))
+
+ (cl-letf (((symbol-function 'secrets-search-items)
+ (lambda (col &rest r)
+ (should (equal col "Test"))
+ (should (plist-get r :user))
+ (map-keys entries)))
+ ((symbol-function 'secrets-get-secret)
+ (lambda (col label)
+ (should (equal col "Test"))
+ (assoc-default label secrets)))
+ ((symbol-function 'secrets-get-attributes)
+ (lambda (col label)
+ (should (equal col "Test"))
+ (assoc-default label entries))))
+
+ (erc-services-tests--auth-source-announced #'erc-auth-source-search))))
+
+(ert-deftest erc--auth-source-search--secrets-overrides ()
+ (skip-unless (bound-and-true-p secrets-enabled))
+ (let ((auth-sources '("secrets:Test"))
+ (auth-source-do-cache nil)
+ (entries `(,@erc-services-tests--auth-source-secrets-standard-entries
+ ("#chan@GNU.chat:6697"
+ (:host . "GNU.chat") (:user . "#chan") (:port . "6697")
+ (:xdg:schema . "org.freedesktop.Secret.Generic"))
+ ("#fsf@my.gnu.org:irc"
+ (:host . "my.gnu.org") (:user . "#fsf") (:port . "irc")
+ (:xdg:schema . "org.freedesktop.Secret.Generic"))
+ ("irc.gnu.org:6667"
+ (:host . "irc.gnu.org") (:port . "6667")
+ (:xdg:schema . "org.freedesktop.Secret.Generic"))
+ ("MyHost:irc"
+ (:host . "MyHost") (:port . "irc")
+ (:xdg:schema . "org.freedesktop.Secret.Generic"))
+ ("MyHost:6667"
+ (:host . "MyHost") (:port . "6667")
+ (:xdg:schema . "org.freedesktop.Secret.Generic"))))
+ (secrets `(,@erc-services-tests--auth-source-secrets-standard-secrets
+ ("#chan@GNU.chat:6697" . "spam")
+ ("#fsf@my.gnu.org:irc" . "42" )
+ ("irc.gnu.org:6667" . "sesame")
+ ("MyHost:irc" . "456")
+ ("MyHost:6667" . "123"))))
+
+ (cl-letf (((symbol-function 'secrets-search-items)
+ (lambda (col &rest _)
+ (should (equal col "Test"))
+ (map-keys entries)))
+ ((symbol-function 'secrets-get-secret)
+ (lambda (col label)
+ (should (equal col "Test"))
+ (assoc-default label secrets)))
+ ((symbol-function 'secrets-get-attributes)
+ (lambda (col label)
+ (should (equal col "Test"))
+ (assoc-default label entries))))
+
+ (erc-services-tests--auth-source-overrides #'erc-auth-source-search))))
+
+;; auth-source-pass backend
+
+(require 'auth-source-pass)
+
+;; `auth-source-pass--find-match-unambiguous' returns something like:
+;;
+;; (list :host "irc.gnu.org"
+;; :port "6697"
+;; :user "rms"
+;; :secret
+;; #[0 "\301\302\300\"\207"
+;; [((secret . "freedom")) auth-source-pass--get-attr secret] 3])
+;;
+;; This function gives ^ (faked here to avoid gpg and file IO). See
+;; `auth-source-pass--with-store' in ../auth-source-pass-tests.el
+(defun erc-services-tests--asp-parse-entry (store entry)
+ (when-let ((found (cl-find entry store :key #'car :test #'string=)))
+ (list (assoc 'secret (cdr found)))))
+
+(defvar erc-join-tests--auth-source-pass-entries
+ '(("irc.gnu.org:irc/#chan"
+ ("port" . "irc") ("user" . "#chan") (secret . "bar"))
+ ("my.gnu.org:irc/#chan"
+ ("port" . "irc") ("user" . "#chan") (secret . "baz"))
+ ("GNU.chat:irc/#chan"
+ ("port" . "irc") ("user" . "#chan") (secret . "foo"))))
+
+(ert-deftest erc--auth-source-search--pass-standard ()
+ (ert-skip "Pass backend not yet supported")
+ (let ((store erc-join-tests--auth-source-pass-entries)
+ (auth-sources '(password-store))
+ (auth-source-do-cache nil))
+
+ (cl-letf (((symbol-function 'auth-source-pass-parse-entry)
+ (apply-partially #'erc-services-tests--asp-parse-entry store))
+ ((symbol-function 'auth-source-pass-entries)
+ (lambda () (mapcar #'car store))))
+
+ (erc-services-tests--auth-source-standard #'erc-auth-source-search))))
+
+(ert-deftest erc--auth-source-search--pass-announced ()
+ (ert-skip "Pass backend not yet supported")
+ (let ((store erc-join-tests--auth-source-pass-entries)
+ (auth-sources '(password-store))
+ (auth-source-do-cache nil))
+
+ (cl-letf (((symbol-function 'auth-source-pass-parse-entry)
+ (apply-partially #'erc-services-tests--asp-parse-entry store))
+ ((symbol-function 'auth-source-pass-entries)
+ (lambda () (mapcar #'car store))))
+
+ (erc-services-tests--auth-source-announced #'erc-auth-source-search))))
+
+(ert-deftest erc--auth-source-search--pass-overrides ()
+ (ert-skip "Pass backend not yet supported")
+ (let ((store
+ `(,@erc-join-tests--auth-source-pass-entries
+ ("GNU.chat:6697/#chan"
+ ("port" . "6697") ("user" . "#chan") (secret . "spam"))
+ ("my.gnu.org:irc/#fsf"
+ ("port" . "irc") ("user" . "#fsf") (secret . "42"))
+ ("irc.gnu.org:6667"
+ ("port" . "6667") (secret . "sesame"))
+ ("MyHost:irc"
+ ("port" . "irc") (secret . "456"))
+ ("MyHost:6667"
+ ("port" . "6667") (secret . "123"))))
+ (auth-sources '(password-store))
+ (auth-source-do-cache nil))
+
+ (cl-letf (((symbol-function 'auth-source-pass-parse-entry)
+ (apply-partially #'erc-services-tests--asp-parse-entry store))
+ ((symbol-function 'auth-source-pass-entries)
+ (lambda () (mapcar #'car store))))
+
+ (erc-services-tests--auth-source-overrides #'erc-auth-source-search))))
+
+;;;; The services module
+
+(ert-deftest erc-nickserv-get-password ()
+ (should erc-prompt-for-nickserv-password)
+ (ert-with-temp-file netrc-file
+ :prefix "erc-nickserv-get-password"
+ :text (mapconcat 'identity
+ '("machine GNU/chat port 6697 user bob password spam"
+ "machine FSF.chat port 6697 user bob password sesame"
+ "machine MyHost port irc password 123")
+ "\n")
+
+ (let* ((auth-sources (list netrc-file))
+ (auth-source-do-cache nil)
+ (erc-nickserv-passwords '((FSF.chat (("alice" . "foo")
+ ("joe" . "bar")))))
+ (erc-use-auth-source-for-nickserv-password t)
+ (erc-session-server "irc.gnu.org")
+ (erc-server-announced-name "my.gnu.org")
+ (erc-network 'FSF.chat)
+ (erc-server-current-nick "tester")
+ (erc-networks--id (erc-networks--id-create nil))
+ (erc-session-port 6697))
+
+ (ert-info ("Lookup custom option")
+ (should (string= (erc-nickserv-get-password "alice") "foo")))
+
+ (ert-info ("Auth source")
+ (ert-info ("Network")
+ (should (string= (erc-nickserv-get-password "bob") "sesame")))
+
+ (ert-info ("Network ID")
+ (let ((erc-networks--id (erc-networks--id-create 'GNU/chat)))
+ (should (string= (erc-nickserv-get-password "bob") "spam")))))
+
+ (ert-info ("Read input")
+ (should (string=
+ (ert-simulate-keys "baz\r" (erc-nickserv-get-password "mike"))
+ "baz")))
+
+ (ert-info ("Failed")
+ (should-not (ert-simulate-keys "\r"
+ (erc-nickserv-get-password "fake")))))))
+
+
+;;; erc-services-tests.el ends here
diff --git a/test/lisp/erc/erc-tests.el b/test/lisp/erc/erc-tests.el
index 60b3da2317f..4971d0e194f 100644
--- a/test/lisp/erc/erc-tests.el
+++ b/test/lisp/erc/erc-tests.el
@@ -21,7 +21,7 @@
;;; Code:
-(require 'ert)
+(require 'ert-x)
(require 'erc)
(require 'erc-ring)
(require 'erc-networks)
@@ -48,6 +48,27 @@
(cl-letf (((symbol-function 'read-string) (lambda (&rest _) "1d")))
(should (equal (erc--read-time-period "foo: ") 86400))))
+(ert-deftest erc--meta--backend-dependencies ()
+ (with-temp-buffer
+ (insert-file-contents-literally
+ (concat (file-name-sans-extension (symbol-file 'erc)) ".el"))
+ (let ((beg (search-forward ";; Defined in erc-backend"))
+ (end (search-forward "\n\n"))
+ vars)
+ (save-excursion
+ (save-restriction
+ (narrow-to-region beg end)
+ (goto-char (point-min))
+ (with-syntax-table lisp-data-mode-syntax-table
+ (condition-case _
+ (while (push (cadr (read (current-buffer))) vars))
+ (end-of-file)))))
+ (should (= (point) end))
+ (dolist (var vars)
+ (setq var (concat "\\_<" (symbol-name var) "\\_>"))
+ (ert-info (var)
+ (should (save-excursion (search-forward-regexp var nil t))))))))
+
(ert-deftest erc-with-all-buffers-of-server ()
(let (proc-exnet
proc-onet
@@ -114,6 +135,207 @@
(should (get-buffer "#spam"))
(kill-buffer "#spam")))
+(defun erc-tests--send-prep ()
+ ;; Caller should probably shadow `erc-insert-modify-hook' or
+ ;; populate user tables for erc-button.
+ (erc-mode)
+ (insert "\n\n")
+ (setq erc-input-marker (make-marker)
+ erc-insert-marker (make-marker))
+ (set-marker erc-insert-marker (point-max))
+ (erc-display-prompt)
+ (should (= (point) erc-input-marker)))
+
+(defun erc-tests--set-fake-server-process (&rest args)
+ (setq erc-server-process
+ (apply #'start-process (car args) (current-buffer) args))
+ (set-process-query-on-exit-flag erc-server-process nil))
+
+(ert-deftest erc-hide-prompt ()
+ (let (erc-kill-channel-hook erc-kill-server-hook erc-kill-buffer-hook)
+
+ (with-current-buffer (get-buffer-create "ServNet")
+ (erc-tests--send-prep)
+ (goto-char erc-insert-marker)
+ (should (looking-at-p (regexp-quote erc-prompt)))
+ (erc-tests--set-fake-server-process "sleep" "1")
+ (set-process-sentinel erc-server-process #'ignore)
+ (setq erc-network 'ServNet)
+ (set-process-query-on-exit-flag erc-server-process nil))
+
+ (with-current-buffer (get-buffer-create "#chan")
+ (erc-tests--send-prep)
+ (goto-char erc-insert-marker)
+ (should (looking-at-p (regexp-quote erc-prompt)))
+ (setq erc-server-process (buffer-local-value 'erc-server-process
+ (get-buffer "ServNet"))
+ erc-default-recipients '("#chan")))
+
+ (with-current-buffer (get-buffer-create "bob")
+ (erc-tests--send-prep)
+ (goto-char erc-insert-marker)
+ (should (looking-at-p (regexp-quote erc-prompt)))
+ (setq erc-server-process (buffer-local-value 'erc-server-process
+ (get-buffer "ServNet"))
+ erc-default-recipients '("bob")))
+
+ (ert-info ("Value: t (default)")
+ (should (eq erc-hide-prompt t))
+ (with-current-buffer "ServNet"
+ (should (= (point) erc-insert-marker))
+ (erc--hide-prompt erc-server-process)
+ (should (string= ">" (get-text-property (point) 'display))))
+
+ (with-current-buffer "#chan"
+ (goto-char erc-insert-marker)
+ (should (string= ">" (get-text-property (point) 'display)))
+ (should (memq #'erc--unhide-prompt-on-self-insert pre-command-hook))
+ (goto-char erc-input-marker)
+ (ert-simulate-command '(self-insert-command 1 ?/))
+ (goto-char erc-insert-marker)
+ (should-not (get-text-property (point) 'display))
+ (should-not (memq #'erc--unhide-prompt-on-self-insert
+ pre-command-hook)))
+
+ (with-current-buffer "bob"
+ (goto-char erc-insert-marker)
+ (should (string= ">" (get-text-property (point) 'display)))
+ (should (memq #'erc--unhide-prompt-on-self-insert pre-command-hook))
+ (goto-char erc-input-marker)
+ (ert-simulate-command '(self-insert-command 1 ?/))
+ (goto-char erc-insert-marker)
+ (should-not (get-text-property (point) 'display))
+ (should-not (memq #'erc--unhide-prompt-on-self-insert
+ pre-command-hook)))
+
+ (with-current-buffer "ServNet"
+ (should (get-text-property erc-insert-marker 'display))
+ (should (memq #'erc--unhide-prompt-on-self-insert pre-command-hook))
+ (erc--unhide-prompt)
+ (should-not (memq #'erc--unhide-prompt-on-self-insert
+ pre-command-hook))
+ (should-not (get-text-property erc-insert-marker 'display))))
+
+ (ert-info ("Value: server")
+ (setq erc-hide-prompt '(server))
+ (with-current-buffer "ServNet"
+ (erc--hide-prompt erc-server-process)
+ (should (string= ">" (get-text-property erc-insert-marker 'display))))
+
+ (with-current-buffer "#chan"
+ (should-not (get-text-property erc-insert-marker 'display)))
+
+ (with-current-buffer "bob"
+ (should-not (get-text-property erc-insert-marker 'display)))
+
+ (with-current-buffer "ServNet"
+ (erc--unhide-prompt)
+ (should-not (get-text-property erc-insert-marker 'display))))
+
+ (ert-info ("Value: channel")
+ (setq erc-hide-prompt '(channel))
+ (with-current-buffer "ServNet"
+ (erc--hide-prompt erc-server-process)
+ (should-not (get-text-property erc-insert-marker 'display)))
+
+ (with-current-buffer "bob"
+ (should-not (get-text-property erc-insert-marker 'display)))
+
+ (with-current-buffer "#chan"
+ (should (string= ">" (get-text-property erc-insert-marker 'display)))
+ (erc--unhide-prompt)
+ (should-not (get-text-property erc-insert-marker 'display))))
+
+ (ert-info ("Value: query")
+ (setq erc-hide-prompt '(query))
+ (with-current-buffer "ServNet"
+ (erc--hide-prompt erc-server-process)
+ (should-not (get-text-property erc-insert-marker 'display)))
+
+ (with-current-buffer "bob"
+ (should (string= ">" (get-text-property erc-insert-marker 'display)))
+ (erc--unhide-prompt)
+ (should-not (get-text-property erc-insert-marker 'display)))
+
+ (with-current-buffer "#chan"
+ (should-not (get-text-property erc-insert-marker 'display))))
+
+ (ert-info ("Value: nil")
+ (setq erc-hide-prompt nil)
+ (with-current-buffer "ServNet"
+ (erc--hide-prompt erc-server-process)
+ (should-not (get-text-property erc-insert-marker 'display)))
+
+ (with-current-buffer "bob"
+ (should-not (get-text-property erc-insert-marker 'display)))
+
+ (with-current-buffer "#chan"
+ (should-not (get-text-property erc-insert-marker 'display))
+ (erc--unhide-prompt) ; won't blow up when prompt already showing
+ (should-not (get-text-property erc-insert-marker 'display))))
+
+ (when noninteractive
+ (kill-buffer "#chan")
+ (kill-buffer "bob")
+ (kill-buffer "ServNet"))))
+
+(ert-deftest erc--switch-to-buffer ()
+ (defvar erc-modified-channels-alist) ; lisp/erc/erc-track.el
+
+ (let ((proc (start-process "aNet" (current-buffer) "true"))
+ (erc-modified-channels-alist `(("fake") (,(messages-buffer))))
+ (inhibit-message noninteractive)
+ (completion-fail-discreetly t) ; otherwise ^G^G printed to .log file
+ ;;
+ erc-kill-channel-hook erc-kill-server-hook erc-kill-buffer-hook)
+
+ (with-current-buffer (get-buffer-create "server")
+ (erc-mode)
+ (set-process-buffer (setq erc-server-process proc) (current-buffer))
+ (set-process-query-on-exit-flag erc-server-process nil)
+ (with-current-buffer (get-buffer-create "#chan")
+ (erc-mode)
+ (setq erc-server-process proc))
+ (with-current-buffer (get-buffer-create "#foo")
+ (erc-mode)
+ (setq erc-server-process proc))
+
+ (ert-info ("Channel #chan selectable from server buffer")
+ (ert-simulate-keys (list ?# ?c ?h ?a ?n ?\C-m)
+ (should (string= "#chan" (erc--switch-to-buffer))))))
+
+ (ert-info ("Channel #foo selectable from non-ERC buffer")
+ (ert-simulate-keys (list ?# ?f ?o ?o ?\C-m)
+ (should (string= "#foo" (erc--switch-to-buffer)))))
+
+ (ert-info ("Default selectable")
+ (ert-simulate-keys (list ?\C-m)
+ (should (string= "*Messages*" (erc--switch-to-buffer)))))
+
+ (ert-info ("Extant but non-ERC buffer not selectable")
+ (get-buffer-create "#fake") ; not ours
+ (ert-simulate-keys (kbd "#fake C-m C-a C-k C-m")
+ ;; Initial query fails ~~~~~~^; clearing input accepts default
+ (should (string= "*Messages*" (erc--switch-to-buffer)))))
+
+ (with-current-buffer (get-buffer-create "other")
+ (erc-mode)
+ (setq erc-server-process (start-process "bNet" (current-buffer) "true"))
+ (set-process-query-on-exit-flag erc-server-process nil))
+
+ (ert-info ("Foreign ERC buffer not selectable")
+ (ert-simulate-keys (kbd "other C-m C-a C-k C-m")
+ (with-current-buffer "server"
+ (should (string= "*Messages*" (erc--switch-to-buffer))))))
+
+ (ert-info ("Any ERC-buffer selectable from non-ERC buffer")
+ (should-not (eq major-mode 'erc-mode))
+ (ert-simulate-keys (list ?o ?t ?h ?e ?r ?\C-m)
+ (should (string= "other" (erc--switch-to-buffer)))))
+
+ (dolist (b '("server" "other" "#chan" "#foo" "#fake"))
+ (kill-buffer b))))
+
(ert-deftest erc-lurker-maybe-trim ()
(let (erc-lurker-trim-nicks
(erc-lurker-ignore-chars "_`"))
@@ -127,6 +349,147 @@
(setq erc-lurker-ignore-chars "_-`") ; set of chars, not character alts
(should (string= "nick" (erc-lurker-maybe-trim "nick-_`")))))
+(ert-deftest erc--parse-isupport-value ()
+ (should (equal (erc--parse-isupport-value "a,b") '("a" "b")))
+ (should (equal (erc--parse-isupport-value "a,b,c") '("a" "b" "c")))
+
+ (should (equal (erc--parse-isupport-value "abc") '("abc")))
+ (should (equal (erc--parse-isupport-value "\\x20foo") '(" foo")))
+ (should (equal (erc--parse-isupport-value "foo\\x20") '("foo ")))
+ (should (equal (erc--parse-isupport-value "a\\x20b\\x20c") '("a b c")))
+ (should (equal (erc--parse-isupport-value "a\\x20b\\x20c\\x20") '("a b c ")))
+ (should (equal (erc--parse-isupport-value "\\x20a\\x20b\\x20c") '(" a b c")))
+ (should (equal (erc--parse-isupport-value "a\\x20\\x20c") '("a c")))
+ (should (equal (erc--parse-isupport-value "\\x20\\x20\\x20") '(" ")))
+ (should (equal (erc--parse-isupport-value "\\x5Co/") '("\\o/")))
+ (should (equal (erc--parse-isupport-value "\\x7F,\\x19") '("\\x7F" "\\x19")))
+ (should (equal (erc--parse-isupport-value "a\\x2Cb,c") '("a,b" "c"))))
+
+(ert-deftest erc--get-isupport-entry ()
+ (let ((erc--isupport-params (make-hash-table))
+ (erc-server-parameters '(("FOO" . "1") ("BAR") ("BAZ" . "A,B,C")))
+ (items (lambda ()
+ (cl-loop for k being the hash-keys of erc--isupport-params
+ using (hash-values v) collect (cons k v)))))
+
+ (should-not (erc--get-isupport-entry 'FAKE))
+ (should-not (erc--get-isupport-entry 'FAKE 'single))
+ (should (zerop (hash-table-count erc--isupport-params)))
+
+ (should (equal (erc--get-isupport-entry 'BAR) '(BAR)))
+ (should-not (erc--get-isupport-entry 'BAR 'single))
+ (should (= 1 (hash-table-count erc--isupport-params)))
+
+ (should (equal (erc--get-isupport-entry 'BAZ) '(BAZ "A" "B" "C")))
+ (should (equal (erc--get-isupport-entry 'BAZ 'single) "A"))
+ (should (= 2 (hash-table-count erc--isupport-params)))
+
+ (should (equal (erc--get-isupport-entry 'FOO 'single) "1"))
+ (should (equal (erc--get-isupport-entry 'FOO) '(FOO "1")))
+
+ (should (equal (funcall items)
+ '((BAR . --empty--) (BAZ "A" "B" "C") (FOO "1"))))))
+
+(ert-deftest erc-server-005 ()
+ (let* ((hooked 0)
+ (verify #'ignore)
+ (hook (lambda (_ _) (funcall verify) (cl-incf hooked)))
+ (erc-server-005-functions (list #'erc-server-005 hook #'ignore))
+ erc-server-parameters
+ erc--isupport-params
+ erc-timer-hook
+ calls
+ args
+ parsed)
+
+ (cl-letf (((symbol-function 'erc-display-message)
+ (lambda (_ _ _ line) (push line calls))))
+
+ (ert-info ("Baseline")
+ (setq args '("tester" "BOT=B" "EXCEPTS" "PREFIX=(ov)@+" "are supp...")
+ parsed (make-erc-response :command-args args :command "005"))
+
+ (setq verify
+ (lambda ()
+ (should (equal erc-server-parameters
+ '(("PREFIX" . "(ov)@+") ("EXCEPTS")
+ ("BOT" . "B"))))
+ (should (zerop (hash-table-count erc--isupport-params)))
+ (should (equal "(ov)@+" (erc--get-isupport-entry 'PREFIX t)))
+ (should (equal '(EXCEPTS) (erc--get-isupport-entry 'EXCEPTS)))
+ (should (equal "B" (erc--get-isupport-entry 'BOT t)))
+ (should (string= (pop calls)
+ "BOT=B EXCEPTS PREFIX=(ov)@+ are supp..."))
+ (should (equal args (erc-response.command-args parsed)))))
+
+ (erc-call-hooks nil parsed))
+
+ (ert-info ("Negated, updated")
+ (setq args '("tester" "-EXCEPTS" "-FAKE" "PREFIX=(ohv)@%+" "are su...")
+ parsed (make-erc-response :command-args args :command "005"))
+
+ (setq verify
+ (lambda ()
+ (should (equal erc-server-parameters
+ '(("PREFIX" . "(ohv)@%+") ("BOT" . "B"))))
+ (should (string= (pop calls)
+ "-EXCEPTS -FAKE PREFIX=(ohv)@%+ are su..."))
+ (should (equal "(ohv)@%+" (erc--get-isupport-entry 'PREFIX t)))
+ (should (equal "B" (erc--get-isupport-entry 'BOT t)))
+ (should-not (erc--get-isupport-entry 'EXCEPTS))
+ (should (equal args (erc-response.command-args parsed)))))
+
+ (erc-call-hooks nil parsed))
+ (should (= hooked 2)))))
+
+(ert-deftest erc-downcase ()
+ (let ((erc--isupport-params (make-hash-table)))
+
+ (puthash 'PREFIX '("(ov)@+") erc--isupport-params)
+ (puthash 'BOT '("B") erc--isupport-params)
+
+ (ert-info ("ascii")
+ (puthash 'CASEMAPPING '("ascii") erc--isupport-params)
+ (should (equal (erc-downcase "Bob[m]`") "bob[m]`"))
+ (should (equal (erc-downcase "Tilde~") "tilde~" ))
+ (should (equal (erc-downcase "\\O/") "\\o/" )))
+
+ (ert-info ("rfc1459")
+ (puthash 'CASEMAPPING '("rfc1459") erc--isupport-params)
+ (should (equal (erc-downcase "Bob[m]`") "bob{m}`" ))
+ (should (equal (erc-downcase "Tilde~") "tilde^" ))
+ (should (equal (erc-downcase "\\O/") "|o/" )))
+
+ (ert-info ("rfc1459-strict")
+ (puthash 'CASEMAPPING '("rfc1459-strict") erc--isupport-params)
+ (should (equal (erc-downcase "Bob[m]`") "bob{m}`"))
+ (should (equal (erc-downcase "Tilde~") "tilde~" ))
+ (should (equal (erc-downcase "\\O/") "|o/" )))))
+
+(ert-deftest erc--valid-local-channel-p ()
+ (ert-info ("Local channels not supported")
+ (let ((erc--isupport-params (make-hash-table)))
+ (puthash 'CHANTYPES '("#") erc--isupport-params)
+ (should-not (erc--valid-local-channel-p "#chan"))
+ (should-not (erc--valid-local-channel-p "&local"))))
+ (ert-info ("Local channels supported")
+ (let ((erc--isupport-params (make-hash-table)))
+ (puthash 'CHANTYPES '("&#") erc--isupport-params)
+ (should-not (erc--valid-local-channel-p "#chan"))
+ (should (erc--valid-local-channel-p "&local")))))
+
+(ert-deftest erc--target-from-string ()
+ (should (equal (erc--target-from-string "#chan")
+ #s(erc--target-channel "#chan" \#chan)))
+
+ (should (equal (erc--target-from-string "Bob")
+ #s(erc--target "Bob" bob)))
+
+ (let ((erc--isupport-params (make-hash-table)))
+ (puthash 'CHANTYPES '("&#") erc--isupport-params)
+ (should (equal (erc--target-from-string "&Bitlbee")
+ #s(erc--target-channel-local "&Bitlbee" &bitlbee)))))
+
(ert-deftest erc-ring-previous-command-base-case ()
(ert-info ("Create ring when nonexistent and do nothing")
(let (erc-input-ring
@@ -140,14 +503,10 @@
(ert-deftest erc-ring-previous-command ()
(with-current-buffer (get-buffer-create "*#fake*")
(erc-mode)
- (insert "\n\n")
+ (erc-tests--send-prep)
+ (setq-local erc-last-input-time 0)
(should-not (local-variable-if-set-p 'erc-send-completed-hook))
(set (make-local-variable 'erc-send-completed-hook) nil) ; skip t (globals)
- (setq erc-input-marker (make-marker)
- erc-insert-marker (make-marker))
- (set-marker erc-insert-marker (point-max))
- (erc-display-prompt)
- (should (= (point) erc-input-marker))
;; Just in case erc-ring-mode is already on
(setq-local erc-pre-send-functions nil)
(add-hook 'erc-pre-send-functions #'erc-add-to-input-ring)
@@ -207,8 +566,9 @@
(erc-log-irc-protocol ":irc.gnu.org 001 tester :Welcome")
(erc-log-irc-protocol ":irc.gnu.org 002 tester :Your host is irc.gnu.org")
(setq erc-network 'FooNet)
+ (setq erc-networks--id (erc-networks--id-create nil))
(erc-log-irc-protocol ":irc.gnu.org 422 tester :MOTD missing")
- (setq erc-network 'BarNet)
+ (setq erc-networks--id (erc-networks--id-create 'BarNet))
(erc-log-irc-protocol ":irc.gnu.org 221 tester +i")
(set-process-query-on-exit-flag erc-server-process nil)))
(with-current-buffer "*erc-protocol*"
@@ -228,4 +588,309 @@
(kill-buffer "*erc-protocol*")
(should-not erc-debug-irc-protocol)))
+(ert-deftest erc--input-line-delim-regexp ()
+ (let ((p erc--input-line-delim-regexp))
+ ;; none
+ (should (equal '("a" "b") (split-string "a\r\nb" p)))
+ (should (equal '("a" "b") (split-string "a\nb" p)))
+ (should (equal '("a" "b") (split-string "a\rb" p)))
+
+ ;; one
+ (should (equal '("") (split-string "" p)))
+ (should (equal '("a" "" "b") (split-string "a\r\rb" p)))
+ (should (equal '("a" "" "b") (split-string "a\n\rb" p)))
+ (should (equal '("a" "" "b") (split-string "a\n\nb" p)))
+ (should (equal '("a" "" "b") (split-string "a\r\r\nb" p)))
+ (should (equal '("a" "" "b") (split-string "a\n\r\nb" p)))
+ (should (equal '("a" "") (split-string "a\n" p)))
+ (should (equal '("a" "") (split-string "a\r" p)))
+ (should (equal '("a" "") (split-string "a\r\n" p)))
+ (should (equal '("" "b") (split-string "\nb" p)))
+ (should (equal '("" "b") (split-string "\rb" p)))
+ (should (equal '("" "b") (split-string "\r\nb" p)))
+
+ ;; two
+ (should (equal '("" "") (split-string "\r" p)))
+ (should (equal '("" "") (split-string "\n" p)))
+ (should (equal '("" "") (split-string "\r\n" p)))
+
+ ;; three
+ (should (equal '("" "" "") (split-string "\r\r" p)))
+ (should (equal '("" "" "") (split-string "\n\n" p)))
+ (should (equal '("" "" "") (split-string "\n\r" p)))))
+
+(ert-deftest erc--blank-in-multiline-input-p ()
+ (let ((check (lambda (s)
+ (erc--blank-in-multiline-input-p
+ (split-string s erc--input-line-delim-regexp)))))
+
+ (ert-info ("With `erc-send-whitespace-lines'")
+ (let ((erc-send-whitespace-lines t))
+ (should (funcall check ""))
+ (should-not (funcall check "\na"))
+ (should-not (funcall check "/msg a\n")) ; real /cmd
+ (should-not (funcall check "a\n\nb")) ; "" allowed
+ (should-not (funcall check "/msg a\n\nb")) ; non-/cmd
+ (should-not (funcall check " "))
+ (should-not (funcall check "\t"))
+ (should-not (funcall check "a\nb"))
+ (should-not (funcall check "a\n "))
+ (should-not (funcall check "a\n \t"))
+ (should-not (funcall check "a\n \f"))
+ (should-not (funcall check "a\n \nb"))
+ (should-not (funcall check "a\n \t\nb"))
+ (should-not (funcall check "a\n \f\nb"))))
+
+ (should (funcall check ""))
+ (should (funcall check " "))
+ (should (funcall check "\t"))
+ (should (funcall check "a\n\nb"))
+ (should (funcall check "a\n\nb"))
+ (should (funcall check "a\n "))
+ (should (funcall check "a\n \t"))
+ (should (funcall check "a\n \f"))
+ (should (funcall check "a\n \nb"))
+ (should (funcall check "a\n \t\nb"))
+
+ (should-not (funcall check "a\rb"))
+ (should-not (funcall check "a\nb"))
+ (should-not (funcall check "a\r\nb"))))
+
+(defun erc-tests--with-process-input-spy (test)
+ (with-current-buffer (get-buffer-create "FakeNet")
+ (let* ((erc-pre-send-functions
+ (remove #'erc-add-to-input-ring erc-pre-send-functions)) ; for now
+ (inhibit-message noninteractive)
+ (erc-server-current-nick "tester")
+ (erc-last-input-time 0)
+ erc-accidental-paste-threshold-seconds
+ erc-send-modify-hook
+ ;;
+ calls)
+ (cl-letf (((symbol-function 'erc-process-input-line)
+ (lambda (&rest r) (push r calls)))
+ ((symbol-function 'erc-server-buffer)
+ (lambda () (current-buffer))))
+ (erc-tests--send-prep)
+ (funcall test (lambda () (pop calls)))))
+ (when noninteractive (kill-buffer))))
+
+(ert-deftest erc--check-prompt-input-functions ()
+ (erc-tests--with-process-input-spy
+ (lambda (next)
+
+ (ert-info ("Errors when point not in prompt area") ; actually just dings
+ (insert "/msg #chan hi")
+ (forward-line -1)
+ (let ((e (should-error (erc-send-current-line))))
+ (should (equal "Point is not in the input area" (cadr e))))
+ (goto-char (point-max))
+ (ert-info ("Input remains untouched")
+ (should (save-excursion (erc-bol) (looking-at "/msg #chan hi")))))
+
+ (ert-info ("Errors when no process running")
+ (let ((e (should-error (erc-send-current-line))))
+ (should (equal "ERC: No process running" (cadr e))))
+ (ert-info ("Input remains untouched")
+ (should (save-excursion (erc-bol) (looking-at "/msg #chan hi")))))
+
+ (ert-info ("Errors when line contains empty newline")
+ (erc-bol)
+ (delete-region (point) (point-max))
+ (insert "one\n")
+ (let ((e (should-error (erc-send-current-line))))
+ (should (equal "Blank line - ignoring..." (cadr e))))
+ (goto-char (point-max))
+ (ert-info ("Input remains untouched")
+ (should (save-excursion (goto-char erc-input-marker)
+ (looking-at "one\n")))))
+
+ (should (= 0 erc-last-input-time))
+ (should-not (funcall next)))))
+
+;; These also indirectly tests `erc-send-input'
+
+(ert-deftest erc-send-current-line ()
+ (erc-tests--with-process-input-spy
+ (lambda (next)
+ (erc-tests--set-fake-server-process "sleep" "1")
+ (should (= 0 erc-last-input-time))
+
+ (ert-info ("Simple command")
+ (insert "/msg #chan hi")
+ (erc-send-current-line)
+ (ert-info ("Prompt restored")
+ (forward-line 0)
+ (should (looking-at-p erc-prompt)))
+ (ert-info ("Input cleared")
+ (erc-bol)
+ (should (eq (point) (point-max))))
+ ;; Commands are forced (no flood protection)
+ (should (equal (funcall next) '("/msg #chan hi\n" t nil))))
+
+ (ert-info ("Simple non-command")
+ (insert "hi")
+ (erc-send-current-line)
+ (should (eq (point) (point-max)))
+ (should (save-excursion (forward-line -1)
+ (search-forward "<tester> hi")))
+ ;; Non-ommands are forced only when `erc-flood-protect' is nil
+ (should (equal (funcall next) '("hi\n" nil t))))
+
+ (should (consp erc-last-input-time)))))
+
+(ert-deftest erc-send-whitespace-lines ()
+ (erc-tests--with-process-input-spy
+ (lambda (next)
+ (erc-tests--set-fake-server-process "sleep" "1")
+ (setq-local erc-send-whitespace-lines t)
+
+ (ert-info ("Multiline hunk with blank line correctly split")
+ (insert "one\n\ntwo")
+ (erc-send-current-line)
+ (ert-info ("Prompt restored")
+ (forward-line 0)
+ (should (looking-at-p erc-prompt)))
+ (ert-info ("Input cleared")
+ (erc-bol)
+ (should (eq (point) (point-max))))
+ (should (equal (funcall next) '("two\n" nil t)))
+ (should (equal (funcall next) '("\n" nil t)))
+ (should (equal (funcall next) '("one\n" nil t))))
+
+ (ert-info ("Multiline hunk with trailing newline filtered")
+ (insert "hi\n")
+ (erc-send-current-line)
+ (ert-info ("Input cleared")
+ (erc-bol)
+ (should (eq (point) (point-max))))
+ (should (equal (funcall next) '("hi\n" nil t)))
+ (should-not (funcall next)))
+
+ (ert-info ("Multiline hunk with trailing carriage filtered")
+ (insert "hi\r")
+ (erc-send-current-line)
+ (ert-info ("Input cleared")
+ (erc-bol)
+ (should (eq (point) (point-max))))
+ (should (equal (funcall next) '("hi\n" nil t)))
+ (should-not (funcall next)))
+
+ (ert-info ("Multiline command with trailing blank filtered")
+ (pcase-dolist (`(,p . ,q)
+ '(("/a b\r" "/a b\n") ("/a b\n" "/a b\n")
+ ("/a b\n\n" "/a b\n") ("/a b\r\n" "/a b\n")
+ ("a b\nc\n\n" "c\n" "a b\n")
+ ("/a b\nc\n\n" "c\n" "/a b\n")
+ ("/a b\n\nc\n\n" "c\n" "\n" "/a b\n")))
+ (insert p)
+ (erc-send-current-line)
+ (erc-bol)
+ (should (eq (point) (point-max)))
+ (while q
+ (should (equal (funcall next) (list (pop q) nil t))))
+ (should-not (funcall next))))
+
+ (ert-info ("Multiline hunk with trailing whitespace not filtered")
+ (insert "there\n ")
+ (erc-send-current-line)
+ (should (equal (funcall next) '(" \n" nil t)))
+ (should (equal (funcall next) '("there\n" nil t)))
+ (should-not (funcall next))))))
+
+(ert-deftest erc--check-prompt-input-for-excess-lines ()
+ (ert-info ("Without `erc-inhibit-multiline-input'")
+ (should-not erc-inhibit-multiline-input)
+ (should-not (erc--check-prompt-input-for-excess-lines "" '("a" "b"))))
+
+ (ert-info ("With `erc-inhibit-multiline-input' as t (2)")
+ (let ((erc-inhibit-multiline-input t))
+ (should-not (erc--check-prompt-input-for-excess-lines "" '("a")))
+ (should-not (erc--check-prompt-input-for-excess-lines "" '("a" "")))
+ (should (erc--check-prompt-input-for-excess-lines "" '("a" "b")))))
+
+ (ert-info ("With `erc-inhibit-multiline-input' as 3")
+ (let ((erc-inhibit-multiline-input 3))
+ (should-not (erc--check-prompt-input-for-excess-lines "" '("a" "b")))
+ (should-not (erc--check-prompt-input-for-excess-lines "" '("a" "b" "")))
+ (should (erc--check-prompt-input-for-excess-lines "" '("a" "b" "c")))))
+
+ (ert-info ("With `erc-ask-about-multiline-input'")
+ (let ((erc-inhibit-multiline-input t)
+ (erc-ask-about-multiline-input t))
+ (ert-simulate-keys '(?n ?\r ?y ?\r)
+ (should (erc--check-prompt-input-for-excess-lines "" '("a" "b")))
+ (should-not (erc--check-prompt-input-for-excess-lines "" '("a" "b")))))
+ (should-not erc-ask-about-multiline-input)))
+
+;; The point of this test is to ensure output is handled identically
+;; regardless of whether a command handler is summoned.
+
+(ert-deftest erc-process-input-line ()
+ (let (erc-server-last-sent-time
+ erc-server-flood-queue
+ (orig-erc-cmd-MSG (symbol-function 'erc-cmd-MSG))
+ (erc-default-recipients '("#chan"))
+ calls)
+ (with-temp-buffer
+ (cl-letf (((symbol-function 'erc-cmd-MSG)
+ (lambda (line)
+ (push line calls)
+ (funcall orig-erc-cmd-MSG line)))
+ ((symbol-function 'erc-server-buffer)
+ (lambda () (current-buffer)))
+ ((symbol-function 'erc-server-process-alive)
+ (lambda () t))
+ ((symbol-function 'erc-server-send-queue)
+ #'ignore))
+
+ (ert-info ("Dispatch to user command handler")
+
+ (ert-info ("Baseline")
+ (erc-process-input-line "/msg #chan hi\n")
+ (should (equal (pop calls) " #chan hi"))
+ (should (equal (pop erc-server-flood-queue)
+ '("PRIVMSG #chan :hi\r\n" . utf-8))))
+
+ (ert-info ("Quote preserves line intact")
+ (erc-process-input-line "/QUOTE FAKE foo bar\n")
+ (should (equal (pop erc-server-flood-queue)
+ '("FAKE foo bar\r\n" . utf-8))))
+
+ (ert-info ("Unknown command respected")
+ (erc-process-input-line "/FAKE foo bar\n")
+ (should (equal (pop erc-server-flood-queue)
+ '("FAKE foo bar\r\n" . utf-8))))
+
+ (ert-info ("Spaces preserved")
+ (erc-process-input-line "/msg #chan hi you\n")
+ (should (equal (pop calls) " #chan hi you"))
+ (should (equal (pop erc-server-flood-queue)
+ '("PRIVMSG #chan :hi you\r\n" . utf-8))))
+
+ (ert-info ("Empty line honored")
+ (erc-process-input-line "/msg #chan\n")
+ (should (equal (pop calls) " #chan"))
+ (should (equal (pop erc-server-flood-queue)
+ '("PRIVMSG #chan :\r\n" . utf-8)))))
+
+ (ert-info ("Implicit cmd via `erc-send-input-line-function'")
+
+ (ert-info ("Baseline")
+ (erc-process-input-line "hi\n")
+ (should (equal (pop erc-server-flood-queue)
+ '("PRIVMSG #chan :hi\r\n" . utf-8))))
+
+ (ert-info ("Spaces preserved")
+ (erc-process-input-line "hi you\n")
+ (should (equal (pop erc-server-flood-queue)
+ '("PRIVMSG #chan :hi you\r\n" . utf-8))))
+
+ (ert-info ("Empty line transmitted with injected-space kludge")
+ (erc-process-input-line "\n")
+ (should (equal (pop erc-server-flood-queue)
+ '("PRIVMSG #chan : \r\n" . utf-8))))
+
+ (should-not calls))))))
+
;;; erc-tests.el ends here
diff --git a/test/lisp/erc/resources/base/assoc/bouncer-history/barnet.eld b/test/lisp/erc/resources/base/assoc/bouncer-history/barnet.eld
new file mode 100644
index 00000000000..4b6ccfff38a
--- /dev/null
+++ b/test/lisp/erc/resources/base/assoc/bouncer-history/barnet.eld
@@ -0,0 +1,44 @@
+;; -*- mode: lisp-data; -*-
+((pass 3 "PASS :barnet:changeme"))
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0 ":irc.barnet.org 001 tester :Welcome to the barnet IRC Network tester")
+ (0 ":irc.barnet.org 002 tester :Your host is irc.barnet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.barnet.org 003 tester :This server was created Wed, 28 Apr 2021 06:59:59 UTC")
+ (0 ":irc.barnet.org 004 tester irc.barnet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.barnet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.barnet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=barnet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.barnet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.barnet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (0 ":irc.barnet.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.barnet.org 254 tester 1 :channels formed")
+ (0 ":irc.barnet.org 255 tester :I have 3 clients and 0 servers")
+ (0 ":irc.barnet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0 ":irc.barnet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0 ":irc.barnet.org 422 tester :MOTD File is missing"))
+
+((mode-user 3.2 "MODE tester +i")
+ ;; No mode answer ^
+ (0 ":irc.znc.in 306 tester :You have been marked as being away")
+ (0 ":tester!~u@xrir8fpe4d7ak.irc JOIN #chan")
+ (0 ":irc.barnet.org 353 tester = #chan :joe @mike tester")
+ (0 ":irc.barnet.org 366 tester #chan :End of /NAMES list.")
+ (0 ":***!znc@znc.in PRIVMSG #chan :Buffer Playback...")
+ (0 ":joe!~u@xrir8fpe4d7ak.irc PRIVMSG #chan :[07:04:25] mike: Belike, for joy the emperor hath a son.")
+ (0 ":mike!~u@xrir8fpe4d7ak.irc PRIVMSG #chan :[07:04:27] joe: Protest their first of manhood.")
+ (0 ":joe!~u@xrir8fpe4d7ak.irc PRIVMSG #chan :[07:04:29] mike: As frozen water to a starved snake.")
+ (0 ":mike!~u@xrir8fpe4d7ak.irc PRIVMSG #chan :[07:04:34] joe: My mirth it much displeas'd, but pleas'd my woe.")
+ (0 ":joe!~u@xrir8fpe4d7ak.irc PRIVMSG #chan :[07:04:38] mike: Why, Marcus, no man should be mad but I.")
+ (0 ":mike!~u@xrir8fpe4d7ak.irc PRIVMSG #chan :[07:04:44] joe: Faith, I have heard too much, for your words and performances are no kin together.")
+ (0 ":***!znc@znc.in PRIVMSG #chan :Playback Complete.")
+ (0 ":irc.barnet.org NOTICE tester :[07:00:01] This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect.")
+ (0 ":irc.barnet.org 305 tester :You are no longer marked as being away"))
+
+((mode 6 "MODE #chan")
+ (0 ":irc.barnet.org 324 tester #chan +nt")
+ (0 ":irc.barnet.org 329 tester #chan 1619593200")
+ (0.25 ":joe!~u@svpn88yjcdj42.irc PRIVMSG #chan :mike: But, in defence, by mercy, 'tis most just.")
+ (0.25 ":mike!~u@xrir8fpe4d7ak.irc PRIVMSG #chan :joe: The Marshal of France, Monsieur la Far.")
+ (0.25 ":joe!~u@xrir8fpe4d7ak.irc PRIVMSG #chan :mike: And bide the penance of each three years' day.")
+ (0.25 ":mike!~u@xrir8fpe4d7ak.irc PRIVMSG #chan :joe: Madam, within; but never man so chang'd.")
+ (0.25 ":joe!~u@xrir8fpe4d7ak.irc PRIVMSG #chan :mike: As much in private, and I'll bid adieu."))
diff --git a/test/lisp/erc/resources/base/assoc/bouncer-history/foonet.eld b/test/lisp/erc/resources/base/assoc/bouncer-history/foonet.eld
new file mode 100644
index 00000000000..58df79e19fa
--- /dev/null
+++ b/test/lisp/erc/resources/base/assoc/bouncer-history/foonet.eld
@@ -0,0 +1,48 @@
+;; -*- mode: lisp-data; -*-
+((pass 1 "PASS :foonet:changeme"))
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
+ (0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.foonet.org 003 tester :This server was created Wed, 28 Apr 2021 07:00:00 UTC")
+ (0 ":irc.foonet.org 004 tester irc.foonet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.foonet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.foonet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.foonet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (0 ":irc.foonet.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.foonet.org 254 tester 1 :channels formed")
+ (0 ":irc.foonet.org 255 tester :I have 3 clients and 0 servers")
+ (0 ":irc.foonet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0 ":irc.foonet.org 422 tester :MOTD File is missing"))
+
+((mode-user 3.2 "MODE tester +i")
+ ;; No mode answer ^
+ (0 ":irc.znc.in 306 tester :You have been marked as being away")
+ (0 ":tester!~u@nvfhxvqm92rm6.irc JOIN #chan")
+ (0 ":irc.foonet.org 353 tester = #chan :alice @bob tester")
+ (0 ":irc.foonet.org 366 tester #chan :End of /NAMES list.")
+ (0 ":***!znc@znc.in PRIVMSG #chan :Buffer Playback...")
+ (0 ":bob!~u@svpn88yjcdj42.irc PRIVMSG #chan :[07:04:02] alice: Here come the lovers, full of joy and mirth.")
+ (0 ":alice!~u@svpn88yjcdj42.irc PRIVMSG #chan :[07:04:07] bob: According to the fool's bolt, sir, and such dulcet diseases.")
+ (0 ":bob!~u@svpn88yjcdj42.irc PRIVMSG #chan :[07:04:10] alice: And hang himself. I pray you, do my greeting.")
+ (0 ":alice!~u@svpn88yjcdj42.irc PRIVMSG #chan :[07:04:18] bob: And you sat smiling at his cruel prey.")
+ (0 ":bob!~u@svpn88yjcdj42.irc PRIVMSG #chan :[07:04:21] alice: Or never after look me in the face.")
+ (0 ":alice!~u@svpn88yjcdj42.irc PRIVMSG #chan :[07:04:25] bob: If that may be, than all is well. Come, sit down, every mother's son, and rehearse your parts. Pyramus, you begin: when you have spoken your speech, enter into that brake; and so every one according to his cue.")
+ (0 ":bob!~u@svpn88yjcdj42.irc PRIVMSG #chan :[07:04:30] alice: Where I espied the panther fast asleep.")
+ (0 ":alice!~u@svpn88yjcdj42.irc PRIVMSG #chan :[07:04:32] bob: Alas! he is too young: yet he looks successfully.")
+ (0 ":bob!~u@svpn88yjcdj42.irc PRIVMSG #chan :[07:04:37] alice: Here, at your lordship's service.")
+ (0 ":alice!~u@svpn88yjcdj42.irc PRIVMSG #chan :[07:04:42] bob: By my troth, and in good earnest, and so God mend me, and by all pretty oaths that are not dangerous, if you break one jot of your promise or come one minute behind your hour, I will think you the most pathetical break-promise, and the most hollow lover, and the most unworthy of her you call Rosalind, that may be chosen out of the gross band of the unfaithful. Therefore, beware my censure, and keep your promise.")
+ (0 ":***!znc@znc.in PRIVMSG #chan :Playback Complete.")
+ (0 ":irc.foonet.org NOTICE tester :[07:00:32] This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect.")
+ (0 ":irc.foonet.org 305 tester :You are no longer marked as being away"))
+
+((mode 6 "MODE #chan")
+ (0 ":irc.foonet.org 324 tester #chan +nt")
+ (0 ":irc.foonet.org 329 tester #chan 1619593200")
+ (0.9 ":alice!~u@svpn88yjcdj42.irc PRIVMSG #chan :bob: Grows, lives, and dies, in single blessedness.")
+ (0.25 ":bob!~u@svpn88yjcdj42.irc PRIVMSG #chan :alice: For these two hours, Rosalind, I will leave thee.")
+ (0.25 ":alice!~u@svpn88yjcdj42.irc PRIVMSG #chan :bob: By this hand, it will not kill a fly. But come, now I will be your Rosalind in a more coming-on disposition; and ask me what you will, I will grant it.")
+ (0.25 ":bob!~u@svpn88yjcdj42.irc PRIVMSG #chan :alice: That I must love a loathed enemy.")
+ (0.25 ":alice!~u@svpn88yjcdj42.irc PRIVMSG #chan :bob: As't please your lordship: I'll leave you."))
diff --git a/test/lisp/erc/resources/base/assoc/bumped/again.eld b/test/lisp/erc/resources/base/assoc/bumped/again.eld
new file mode 100644
index 00000000000..ab3c7b06214
--- /dev/null
+++ b/test/lisp/erc/resources/base/assoc/bumped/again.eld
@@ -0,0 +1,30 @@
+;; -*- mode: lisp-data; -*-
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0.0 ":irc.foonet.org 433 * tester :Nickname is reserved by a different account")
+ (0.0 ":irc.foonet.org FAIL NICK NICKNAME_RESERVED tester :Nickname is reserved by a different account"))
+
+((nick 3 "NICK tester`")
+ (0.1 ":irc.foonet.org 001 tester` :Welcome to the foonet IRC Network tester`")
+ (0.0 ":irc.foonet.org 002 tester` :Your host is irc.foonet.org, running version oragono-2.6.1-937b9b02368748e5")
+ (0.0 ":irc.foonet.org 003 tester` :This server was created Fri, 24 Sep 2021 01:38:36 UTC")
+ (0.0 ":irc.foonet.org 004 tester` irc.foonet.org oragono-2.6.1-937b9b02368748e5 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0.0 ":irc.foonet.org 005 tester` AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0.1 ":irc.foonet.org 005 tester` MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0.1 ":irc.foonet.org 005 tester` draft/CHATHISTORY=100 :are supported by this server")
+ (0.0 ":irc.foonet.org 251 tester` :There are 0 users and 3 invisible on 1 server(s)")
+ (0.0 ":irc.foonet.org 252 tester` 0 :IRC Operators online")
+ (0.0 ":irc.foonet.org 253 tester` 0 :unregistered connections")
+ (0.0 ":irc.foonet.org 254 tester` 1 :channels formed")
+ (0.0 ":irc.foonet.org 255 tester` :I have 3 clients and 0 servers")
+ (0.0 ":irc.foonet.org 265 tester` 3 3 :Current local users 3, max 3")
+ (0.2 ":irc.foonet.org 266 tester` 3 3 :Current global users 3, max 3")
+ (0.0 ":irc.foonet.org 422 tester` :MOTD File is missing"))
+
+((mode-user 3.2 "MODE tester` +i")
+ (0.0 ":irc.foonet.org 221 tester` +i")
+ (0.0 ":irc.foonet.org NOTICE tester` :This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect."))
+
+((privmsg 42.6 "PRIVMSG NickServ :IDENTIFY tester changeme")
+ (0.01 ":tester`!~u@rpaau95je67ci.irc NICK tester")
+ (0.0 ":NickServ!NickServ@localhost NOTICE tester :You're now logged in as tester"))
diff --git a/test/lisp/erc/resources/base/assoc/bumped/foisted.eld b/test/lisp/erc/resources/base/assoc/bumped/foisted.eld
new file mode 100644
index 00000000000..5c36e58d9d3
--- /dev/null
+++ b/test/lisp/erc/resources/base/assoc/bumped/foisted.eld
@@ -0,0 +1,30 @@
+;; -*- mode: lisp-data; -*-
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0.0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
+ (0.0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version oragono-2.6.1-937b9b02368748e5")
+ (0.0 ":irc.foonet.org 003 tester :This server was created Fri, 24 Sep 2021 01:38:36 UTC")
+ (0.0 ":irc.foonet.org 004 tester irc.foonet.org oragono-2.6.1-937b9b02368748e5 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0.0 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0.01 ":irc.foonet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0.01 ":irc.foonet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0.0 ":irc.foonet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (0.0 ":irc.foonet.org 252 tester 0 :IRC Operators online")
+ (0.0 ":irc.foonet.org 253 tester 0 :unregistered connections")
+ (0.0 ":irc.foonet.org 254 tester 1 :channels formed")
+ (0.0 ":irc.foonet.org 255 tester :I have 3 clients and 0 servers")
+ (0.0 ":irc.foonet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0.0 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0.0 ":irc.foonet.org 422 tester :MOTD File is missing"))
+
+((mode-user 1.2 "MODE tester +i")
+ (0.0 ":irc.foonet.org 221 tester +i")
+ (0.0 ":irc.foonet.org NOTICE tester :This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect."))
+
+((privmsg 17.21 "PRIVMSG bob :hi")
+ (0.02 ":bob!~u@ecnnh95wr67pv.net PRIVMSG tester :hola")
+ (0.01 ":bob!~u@ecnnh95wr67pv.net PRIVMSG tester :how r u?"))
+
+((quit 18.19 "QUIT :" quit)
+ (0.01 ":tester!~u@rpaau95je67ci.irc QUIT :Quit: " quit))
+((drop 1 DROP))
diff --git a/test/lisp/erc/resources/base/assoc/bumped/refoisted.eld b/test/lisp/erc/resources/base/assoc/bumped/refoisted.eld
new file mode 100644
index 00000000000..33e4168ac46
--- /dev/null
+++ b/test/lisp/erc/resources/base/assoc/bumped/refoisted.eld
@@ -0,0 +1,31 @@
+;; -*- mode: lisp-data; -*-
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0.1 ":irc.foonet.org 001 dummy :Welcome to the foonet IRC Network dummy")
+ (0.0 ":irc.foonet.org 002 dummy :Your host is irc.foonet.org, running version oragono-2.6.1-937b9b02368748e5")
+ (0.0 ":irc.foonet.org 003 dummy :This server was created Fri, 24 Sep 2021 01:38:36 UTC")
+ (0.0 ":irc.foonet.org 004 dummy irc.foonet.org oragono-2.6.1-937b9b02368748e5 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0.0 ":irc.foonet.org 005 dummy AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0.1 ":irc.foonet.org 005 dummy MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0.1 ":irc.foonet.org 005 dummy draft/CHATHISTORY=100 :are supported by this server")
+ (0.0 ":irc.foonet.org 251 dummy :There are 0 users and 3 invisible on 1 server(s)")
+ (0.0 ":irc.foonet.org 252 dummy 0 :IRC Operators online")
+ (0.0 ":irc.foonet.org 253 dummy 0 :unregistered connections")
+ (0.0 ":irc.foonet.org 254 dummy 1 :channels formed")
+ (0.0 ":irc.foonet.org 255 dummy :I have 3 clients and 0 servers")
+ (0.0 ":irc.foonet.org 265 dummy 3 3 :Current local users 3, max 3")
+ (0.2 ":irc.foonet.org 266 dummy 3 3 :Current global users 3, max 3")
+ ;; Could arrive anytime around this point
+ (0.0 ":tester!~u@rpaau95je67ci.irc NICK :dummy")
+ (0.0 ":irc.foonet.org 422 dummy :MOTD File is missing")
+ ;; Playback
+ (0.01 ":bob!~u@ecnnh95wr67pv.net PRIVMSG dummy :back?")
+ )
+
+((mode-user 1.2 "MODE dummy +i")
+ (0.0 ":irc.foonet.org 221 dummy +i")
+ (0.0 ":irc.foonet.org NOTICE dummy :This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect."))
+
+((renick 42.6 "NICK tester")
+ (0.01 ":dummy!~u@rpaau95je67ci.irc NICK tester")
+ (0.0 ":NickServ!NickServ@localhost NOTICE dummy :You're now logged in as tester"))
diff --git a/test/lisp/erc/resources/base/assoc/bumped/renicked.eld b/test/lisp/erc/resources/base/assoc/bumped/renicked.eld
new file mode 100644
index 00000000000..4e96fd73045
--- /dev/null
+++ b/test/lisp/erc/resources/base/assoc/bumped/renicked.eld
@@ -0,0 +1,30 @@
+;; -*- mode: lisp-data; -*-
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0.0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
+ (0.0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version oragono-2.6.1-937b9b02368748e5")
+ (0.0 ":irc.foonet.org 003 tester :This server was created Fri, 24 Sep 2021 01:38:36 UTC")
+ (0.0 ":irc.foonet.org 004 tester irc.foonet.org oragono-2.6.1-937b9b02368748e5 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0.0 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0.01 ":irc.foonet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0.01 ":irc.foonet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0.0 ":irc.foonet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (0.0 ":irc.foonet.org 252 tester 0 :IRC Operators online")
+ (0.0 ":irc.foonet.org 253 tester 0 :unregistered connections")
+ (0.0 ":irc.foonet.org 254 tester 1 :channels formed")
+ (0.0 ":irc.foonet.org 255 tester :I have 3 clients and 0 servers")
+ (0.0 ":irc.foonet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0.0 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0.0 ":irc.foonet.org 422 tester :MOTD File is missing"))
+
+((mode-user 12 "MODE tester +i")
+ (0.0 ":irc.foonet.org 221 tester +i")
+ (0.0 ":irc.foonet.org NOTICE tester :This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect."))
+
+((privmsg 17.21 "PRIVMSG NickServ :REGISTER changeme")
+ (0.02 ":NickServ!NickServ@localhost NOTICE tester :Account created")
+ (0.01 ":NickServ!NickServ@localhost NOTICE tester :You're now logged in as tester"))
+
+((quit 18.19 "QUIT :" quit)
+ (0.01 ":tester!~u@rpaau95je67ci.irc QUIT :Quit: " quit))
+((drop 1 DROP))
diff --git a/test/lisp/erc/resources/base/assoc/multi-net/barnet.eld b/test/lisp/erc/resources/base/assoc/multi-net/barnet.eld
new file mode 100644
index 00000000000..c62a22a11c7
--- /dev/null
+++ b/test/lisp/erc/resources/base/assoc/multi-net/barnet.eld
@@ -0,0 +1,42 @@
+;; -*- mode: lisp-data; -*-
+((pass 1 "PASS :changeme"))
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0 ":irc.barnet.org 001 tester :Welcome to the barnet IRC Network tester")
+ (0 ":irc.barnet.org 002 tester :Your host is irc.barnet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.barnet.org 003 tester :This server was created Tue, 04 May 2021 05:06:19 UTC")
+ (0 ":irc.barnet.org 004 tester irc.barnet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.barnet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.barnet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=barnet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.barnet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.barnet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (0 ":irc.barnet.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.barnet.org 253 tester 0 :unregistered connections")
+ (0 ":irc.barnet.org 254 tester 1 :channels formed")
+ (0 ":irc.barnet.org 255 tester :I have 3 clients and 0 servers")
+ (0 ":irc.barnet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0 ":irc.barnet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0 ":irc.barnet.org 422 tester :MOTD File is missing"))
+
+((mode-user 8 "MODE tester +i")
+ (0 ":irc.barnet.org 221 tester +i")
+ (0 ":irc.barnet.org NOTICE tester :This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect."))
+
+((join 2 "JOIN #chan")
+ (0 ":tester!~u@jnu48g2wrycbw.irc JOIN #chan")
+ (0 ":irc.barnet.org 353 tester = #chan :@mike joe tester")
+ (0 ":irc.barnet.org 366 tester #chan :End of NAMES list"))
+
+((mode 2 "MODE #chan")
+ (0 ":irc.barnet.org 324 tester #chan +nt")
+ (0 ":irc.barnet.org 329 tester #chan 1620104779")
+ (0.1 ":mike!~u@kd7gmjbnbkn8c.irc PRIVMSG #chan :tester, welcome!")
+ (0.1 ":joe!~u@kd7gmjbnbkn8c.irc PRIVMSG #chan :tester, welcome!")
+ (0.1 ":mike!~u@kd7gmjbnbkn8c.irc PRIVMSG #chan :joe: Whipp'd first, sir, and hang'd after.")
+ (0.1 ":joe!~u@kd7gmjbnbkn8c.irc PRIVMSG #chan :mike: We have yet many among us can gripe as hard as Cassibelan; I do not say I am one, but I have a hand. Why tribute ? why should we pay tribute ? If C sar can hide the sun from us with a blanket, or put the moon in his pocket, we will pay him tribute for light; else, sir, no more tribute, pray you now.")
+ (0.1 ":mike!~u@kd7gmjbnbkn8c.irc PRIVMSG #chan :joe: Double and treble admonition, and still forfeit in the same kind ? This would make mercy swear, and play the tyrant.")
+ (0.1 ":joe!~u@kd7gmjbnbkn8c.irc PRIVMSG #chan :mike: And secretly to greet the empress' friends.")
+ (0.1 ":mike!~u@kd7gmjbnbkn8c.irc PRIVMSG #chan :joe: You have not been inquired after: I have sat here all day.")
+ (0.1 ":joe!~u@kd7gmjbnbkn8c.irc PRIVMSG #chan :mike: That same Berowne I'll torture ere I go.")
+ (0.1 ":mike!~u@kd7gmjbnbkn8c.irc PRIVMSG #chan :joe: For mine own part,no offence to the general, nor any man of quality,I hope to be saved.")
+ (0.1 ":joe!~u@kd7gmjbnbkn8c.irc PRIVMSG #chan :mike: Mehercle! if their sons be ingenuous, they shall want no instruction; if their daughters be capable, I will put it to them. But, vir sapit qui pauca loquitur. A soul feminine saluteth us."))
diff --git a/test/lisp/erc/resources/base/assoc/multi-net/foonet.eld b/test/lisp/erc/resources/base/assoc/multi-net/foonet.eld
new file mode 100644
index 00000000000..f30b7deca11
--- /dev/null
+++ b/test/lisp/erc/resources/base/assoc/multi-net/foonet.eld
@@ -0,0 +1,45 @@
+;; -*- mode: lisp-data; -*-
+((pass 1 "PASS :changeme"))
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
+ (0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.foonet.org 003 tester :This server was created Tue, 04 May 2021 05:06:18 UTC")
+ (0 ":irc.foonet.org 004 tester irc.foonet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.foonet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.foonet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.foonet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (0 ":irc.foonet.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.foonet.org 253 tester 0 :unregistered connections")
+ (0 ":irc.foonet.org 254 tester 1 :channels formed")
+ (0 ":irc.foonet.org 255 tester :I have 3 clients and 0 servers")
+ (0 ":irc.foonet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0 ":irc.foonet.org 422 tester :MOTD File is missing"))
+
+((mode-user 8 "MODE tester +i")
+ (0 ":irc.foonet.org 221 tester +i")
+ (0 ":irc.foonet.org NOTICE tester :This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect."))
+
+((join 2 "JOIN #chan")
+ (0 ":tester!~u@9g6b728983yd2.irc JOIN #chan")
+ (0 ":irc.foonet.org 353 tester = #chan :alice tester @bob")
+ (0 ":irc.foonet.org 366 tester #chan :End of NAMES list"))
+
+((mode 2 "MODE #chan")
+ (0 ":irc.foonet.org 324 tester #chan +nt")
+ (0 ":irc.foonet.org 329 tester #chan 1620104779")
+ (0.1 ":bob!~u@rz2v467q4rwhy.irc PRIVMSG #chan :tester, welcome!")
+ (0.1 ":alice!~u@rz2v467q4rwhy.irc PRIVMSG #chan :tester, welcome!")
+ (0.1 ":bob!~u@rz2v467q4rwhy.irc PRIVMSG #chan :alice: But, as it seems, did violence on herself.")
+ (0.1 ":alice!~u@rz2v467q4rwhy.irc PRIVMSG #chan :bob: Well, this is the forest of Arden.")
+ (0.1 ":bob!~u@rz2v467q4rwhy.irc PRIVMSG #chan :alice: Signior Iachimo will not from it. Pray, let us follow 'em.")
+ (0.1 ":alice!~u@rz2v467q4rwhy.irc PRIVMSG #chan :bob: Our queen and all her elves come here anon.")
+ (0.1 ":bob!~u@rz2v467q4rwhy.irc PRIVMSG #chan :alice: The ground is bloody; search about the churchyard.")
+ (0.1 ":alice!~u@rz2v467q4rwhy.irc PRIVMSG #chan :bob: You have discharged this honestly: keep it to yourself. Many likelihoods informed me of this before, which hung so tottering in the balance that I could neither believe nor misdoubt. Pray you, leave me: stall this in your bosom; and I thank you for your honest care. I will speak with you further anon.")
+ (0.1 ":bob!~u@rz2v467q4rwhy.irc PRIVMSG #chan :alice: Give me that mattock, and the wrenching iron.")
+ (0.1 ":alice!~u@rz2v467q4rwhy.irc PRIVMSG #chan :bob: Stand you! You have land enough of your own; but he added to your having, gave you some ground.")
+ (0.1 ":bob!~u@rz2v467q4rwhy.irc PRIVMSG #chan :alice: Excellent workman! Thou canst not paint a man so bad as is thyself.")
+ (0.1 ":alice!~u@rz2v467q4rwhy.irc PRIVMSG #chan :bob: And will you, being a man of your breeding, be married under a bush, like a beggar ? Get you to church, and have a good priest that can tell you what marriage is: this fellow will but join you together as they join wainscot; then one of you will prove a shrunk panel, and like green timber, warp, warp.")
+ (0.1 ":bob!~u@rz2v467q4rwhy.irc PRIVMSG #chan :alice: Live, and be prosperous; and farewell, good fellow."))
diff --git a/test/lisp/erc/resources/base/assoc/reconplay/again.eld b/test/lisp/erc/resources/base/assoc/reconplay/again.eld
new file mode 100644
index 00000000000..4210c07e41a
--- /dev/null
+++ b/test/lisp/erc/resources/base/assoc/reconplay/again.eld
@@ -0,0 +1,42 @@
+;; -*- mode: lisp-data; -*-
+((pass 4.0 "PASS :changeme"))
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0.0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
+ (0.0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0.0 ":irc.foonet.org 003 tester :This server was created Wed, 16 Jun 2021 04:15:00 UTC")
+ (0.0 ":irc.foonet.org 004 tester irc.foonet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0.0 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0.0 ":irc.foonet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0.0 ":irc.foonet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0.0 ":irc.foonet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (0.0 ":irc.foonet.org 252 tester 0 :IRC Operators online")
+ (0.0 ":irc.foonet.org 254 tester 1 :channels formed")
+ (0.0 ":irc.foonet.org 255 tester :I have 3 clients and 0 servers")
+ (0.0 ":irc.foonet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0.0 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0.0 ":irc.foonet.org 422 tester :MOTD File is missing"))
+
+((mode-user 10 "MODE tester +i")
+ ;; No mode answer
+ (0.0 ":tester!~u@mw6kegwt77kwe.irc JOIN #chan")
+ (0.0 ":irc.foonet.org 353 tester = #chan :alice @bob tester")
+ (0.0 ":irc.foonet.org 366 tester #chan :End of /NAMES list.")
+ (0.0 ":***!znc@znc.in PRIVMSG #chan :Buffer Playback...")
+ (0.0 ":alice!~u@mw6kegwt77kwe.irc PRIVMSG #chan :[10:37:52] bob: Thou pout'st upon thy fortune and thy love.")
+ (0.0 ":bob!~u@mw6kegwt77kwe.irc PRIVMSG #chan :[10:37:56] alice: With these mortals on the ground.")
+ (0.0 ":***!znc@znc.in PRIVMSG #chan :Playback Complete."))
+
+((mode 10 "MODE #chan")
+ (0.0 ":irc.foonet.org 324 tester #chan +nt")
+ (0.0 ":irc.foonet.org 329 tester #chan 1623816901")
+ (0.1 ":bob!~u@mw6kegwt77kwe.irc PRIVMSG #chan :alice: My name, my good lord, is Parolles.")
+ (0.1 ":alice!~u@mw6kegwt77kwe.irc PRIVMSG #chan :bob: Wilt thou rest damned ? God help thee, shallow man! God make incision in thee! thou art raw."))
+
+((privmsg 3.0 "PRIVMSG *status :help")
+ (0.0 ":*status!znc@znc.in PRIVMSG tester :In the following list all occurrences of <#chan> support wildcards (* and ?) except ListNicks")
+ (0.0 ":*status!znc@znc.in PRIVMSG tester :\2Version\17: Print which version of ZNC this is")
+ (0.0 ":*status!znc@znc.in PRIVMSG tester :\2Shutdown [message]\17: Shut down ZNC completely")
+ (0.0 ":*status!znc@znc.in PRIVMSG tester :\2Restart [message]\17: Restart ZNC")
+ (0.1 ":bob!~u@mw6kegwt77kwe.irc PRIVMSG #chan :alice: In that word's death; no words can that woe sound.")
+ (0.1 ":alice!~u@mw6kegwt77kwe.irc PRIVMSG #chan :bob: Look, sir, here comes the lady towards my cell."))
diff --git a/test/lisp/erc/resources/base/assoc/reconplay/foonet.eld b/test/lisp/erc/resources/base/assoc/reconplay/foonet.eld
new file mode 100644
index 00000000000..6f50ecca4ef
--- /dev/null
+++ b/test/lisp/erc/resources/base/assoc/reconplay/foonet.eld
@@ -0,0 +1,52 @@
+;; -*- mode: lisp-data; -*-
+((pass 1 "PASS :changeme"))
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0.0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
+ (0.0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0.0 ":irc.foonet.org 003 tester :This server was created Wed, 16 Jun 2021 04:15:00 UTC")
+ (0.0 ":irc.foonet.org 004 tester irc.foonet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0.0 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0.0 ":irc.foonet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0.0 ":irc.foonet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0.0 ":irc.foonet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (0.0 ":irc.foonet.org 252 tester 0 :IRC Operators online")
+ (0.0 ":irc.foonet.org 254 tester 1 :channels formed")
+ (0.0 ":irc.foonet.org 255 tester :I have 3 clients and 0 servers")
+ (0.0 ":irc.foonet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0.0 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0.0 ":irc.foonet.org 422 tester :MOTD File is missing"))
+
+((mode-user 5 "MODE tester +i")
+ ;; No mode answer
+ (0.0 ":irc.znc.in 306 tester :You have been marked as being away")
+ (0.0 ":tester!~u@mw6kegwt77kwe.irc JOIN #chan")
+ (0.0 ":irc.foonet.org 353 tester = #chan :alice @bob tester")
+ (0.0 ":irc.foonet.org 366 tester #chan :End of /NAMES list.")
+ (0.0 ":***!znc@znc.in PRIVMSG #chan :Buffer Playback...")
+ (0.0 ":alice!~u@mw6kegwt77kwe.irc PRIVMSG #chan :[10:35:50] bob: To Laced mon did my land extend.")
+ (0.0 ":bob!~u@mw6kegwt77kwe.irc PRIVMSG #chan :[10:35:55] alice: This is but a custom in your tongue; you bear a graver purpose, I hope.")
+ (0.0 ":alice!~u@mw6kegwt77kwe.irc PRIVMSG #chan :[10:37:16] bob: To imitate them; faults that are rich are fair.")
+ (0.0 ":bob!~u@mw6kegwt77kwe.irc PRIVMSG #chan :[10:37:18] alice: Our Romeo hath not been in bed to-night.")
+ (0.0 ":alice!~u@mw6kegwt77kwe.irc PRIVMSG #chan :[10:37:21] bob: But, in defence, by mercy, 'tis most just.")
+ (0.0 ":bob!~u@mw6kegwt77kwe.irc PRIVMSG #chan :[10:37:25] alice: Younger than she are happy mothers made.")
+ (0.0 ":***!znc@znc.in PRIVMSG #chan :Playback Complete.")
+ (0.0 ":irc.foonet.org 305 tester :You are no longer marked as being away"))
+
+((mode 3 "MODE #chan")
+ (1.0 ":irc.foonet.org 324 tester #chan +nt")
+ (0.0 ":irc.foonet.org 329 tester #chan 1623816901")
+ (0.1 ":alice!~u@mw6kegwt77kwe.irc PRIVMSG #chan :bob: At thy good heart's oppression.")
+ (0.1 ":bob!~u@mw6kegwt77kwe.irc PRIVMSG #chan :alice: But purgatory, torture, hell itself."))
+
+((privmsg 3 "PRIVMSG *status :help")
+ (0.0 ":*status!znc@znc.in PRIVMSG tester :In the following list all occurrences of <#chan> support wildcards (* and ?) except ListNicks")
+ (0.0 ":*status!znc@znc.in PRIVMSG tester :\2AddPort <[+]port> <ipv4|ipv6|all> <web|irc|all> [bindhost [uriprefix]]\17: Add another port for ZNC to listen on")
+ (0.0 ":*status!znc@znc.in PRIVMSG tester :\2DelPort <port> <ipv4|ipv6|all> [bindhost]\17: Remove a port from ZNC")
+ (0.0 ":*status!znc@znc.in PRIVMSG tester :\2Rehash\17: Reload global settings, modules, and listeners from znc.conf")
+ (0.1 ":alice!~u@mw6kegwt77kwe.irc PRIVMSG #chan :bob: And at my suit, sweet, pardon what is past.")
+ (0.1 ":bob!~u@mw6kegwt77kwe.irc PRIVMSG #chan :alice: My lord, you give me most egregious indignity."))
+
+((quit 2 "QUIT :\2ERC\2"))
+
+((drop 0 DROP))
diff --git a/test/lisp/erc/resources/base/assoc/samenet/chester.eld b/test/lisp/erc/resources/base/assoc/samenet/chester.eld
new file mode 100644
index 00000000000..f1aed2836c7
--- /dev/null
+++ b/test/lisp/erc/resources/base/assoc/samenet/chester.eld
@@ -0,0 +1,40 @@
+;; -*- mode: lisp-data; -*-
+((pass 1 "PASS :changeme"))
+((nick 1 "NICK chester"))
+((user 1 "USER user 0 * :chester")
+ (0 ":irc.foonet.org 001 chester :Welcome to the foonet IRC Network chester")
+ (0 ":irc.foonet.org 002 chester :Your host is irc.foonet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.foonet.org 003 chester :This server was created Sun, 13 Jun 2021 05:45:20 UTC")
+ (0 ":irc.foonet.org 004 chester irc.foonet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.foonet.org 005 chester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.foonet.org 005 chester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.foonet.org 005 chester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.foonet.org 251 chester :There are 0 users and 3 invisible on 1 server(s)")
+ (0 ":irc.foonet.org 252 chester 0 :IRC Operators online")
+ (0 ":irc.foonet.org 253 chester 1 :unregistered connections")
+ (0 ":irc.foonet.org 254 chester 1 :channels formed")
+ (0 ":irc.foonet.org 255 chester :I have 3 clients and 0 servers")
+ (0 ":irc.foonet.org 265 chester 3 4 :Current local users 3, max 4")
+ (0 ":irc.foonet.org 266 chester 3 4 :Current global users 3, max 4")
+ (0 ":irc.foonet.org 422 chester :MOTD File is missing"))
+
+((mode-user 12 "MODE chester +i")
+ (0 ":irc.foonet.org 221 chester +i")
+ (0 ":chester!~u@yuvqisyu7m7qs.irc JOIN #chan")
+ (0 ":irc.foonet.org 353 chester = #chan :tester chester @alice bob")
+ (0 ":irc.foonet.org 366 chester #chan :End of NAMES list")
+ (0 ":irc.foonet.org NOTICE chester :This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect."))
+
+((mode 10 "MODE #chan")
+ (0.0 ":irc.foonet.org 324 chester #chan +nt")
+ (0.0 ":irc.foonet.org 329 chester #chan 1623563121")
+ (0.0 ":alice!~u@wyb9b355rgzi8.irc PRIVMSG #chan :chester, welcome!")
+ (0.0 ":bob!~u@wyb9b355rgzi8.irc PRIVMSG #chan :chester, welcome!")
+ (0.1 ":bob!~u@wyb9b355rgzi8.irc PRIVMSG #chan :alice: Dispatch, I say, and find the forester.")
+ (0.0 ":tester!~u@yuvqisyu7m7qs.irc QUIT :Quit: " quit)
+ (0.5 ":tester!~u@yuvqisyu7m7qs.irc JOIN #chan")
+ (0.1 ":alice!~u@wyb9b355rgzi8.irc PRIVMSG #chan :tester, welcome again!")
+ (0.1 ":bob!~u@wyb9b355rgzi8.irc PRIVMSG #chan :tester, welcome again!"))
+
+((quit 20 "QUIT :" quit)
+ (0.0 ":chester!~u@yuvqisyu7m7qs.irc QUIT :Quit: " quit))
diff --git a/test/lisp/erc/resources/base/assoc/samenet/tester.eld b/test/lisp/erc/resources/base/assoc/samenet/tester.eld
new file mode 100644
index 00000000000..cd9cacbe5dc
--- /dev/null
+++ b/test/lisp/erc/resources/base/assoc/samenet/tester.eld
@@ -0,0 +1,42 @@
+;; -*- mode: lisp-data; -*-
+((pass 1 "PASS :changeme"))
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
+ (0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.foonet.org 003 tester :This server was created Sun, 13 Jun 2021 05:45:20 UTC")
+ (0 ":irc.foonet.org 004 tester irc.foonet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.foonet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.foonet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.foonet.org 251 tester :There are 0 users and 4 invisible on 1 server(s)")
+ (0 ":irc.foonet.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.foonet.org 253 tester 0 :unregistered connections")
+ (0 ":irc.foonet.org 254 tester 1 :channels formed")
+ (0 ":irc.foonet.org 255 tester :I have 4 clients and 0 servers")
+ (0 ":irc.foonet.org 265 tester 4 4 :Current local users 4, max 4")
+ (0 ":irc.foonet.org 266 tester 4 4 :Current global users 4, max 4")
+ (0 ":irc.foonet.org 422 tester :MOTD File is missing"))
+
+((mode-user 12 "MODE tester +i")
+ (0 ":irc.foonet.org 221 tester +i")
+ (0 ":irc.foonet.org NOTICE tester :This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect."))
+
+((join 15 "JOIN #chan")
+ (0 ":tester!~u@yuvqisyu7m7qs.irc JOIN #chan")
+ (0 ":irc.foonet.org 353 tester = #chan :tester @alice bob")
+ (0 ":irc.foonet.org 366 tester #chan :End of NAMES list"))
+
+((mode 10 "MODE #chan")
+ (0.0 ":irc.foonet.org 324 tester #chan +nt")
+ (0.0 ":irc.foonet.org 329 tester #chan 1623563121")
+ (0.0 ":alice!~u@wyb9b355rgzi8.irc PRIVMSG #chan :tester, welcome!")
+ (0.0 ":bob!~u@wyb9b355rgzi8.irc PRIVMSG #chan :tester, welcome!")
+ (0.0 ":chester!~u@yuvqisyu7m7qs.irc JOIN #chan")
+ (0.1 ":alice!~u@wyb9b355rgzi8.irc PRIVMSG #chan :chester, welcome!")
+ (0.0 ":bob!~u@wyb9b355rgzi8.irc PRIVMSG #chan :chester, welcome!")
+ (0.1 ":bob!~u@wyb9b355rgzi8.irc PRIVMSG #chan :alice: Dispatch, I say, and find the forester."))
+
+((quit 4 "QUIT "))
+
+((drop 0 DROP))
diff --git a/test/lisp/erc/resources/base/assoc/samenet/tester2.eld b/test/lisp/erc/resources/base/assoc/samenet/tester2.eld
new file mode 100644
index 00000000000..67c3a94a262
--- /dev/null
+++ b/test/lisp/erc/resources/base/assoc/samenet/tester2.eld
@@ -0,0 +1,39 @@
+;; -*- mode: lisp-data; -*-
+((pass 1 "PASS :changeme"))
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
+ (0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.foonet.org 003 tester :This server was created Sun, 13 Jun 2021 05:45:20 UTC")
+ (0 ":irc.foonet.org 004 tester irc.foonet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.foonet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.foonet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.foonet.org 251 tester :There are 0 users and 4 invisible on 1 server(s)")
+ (0 ":irc.foonet.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.foonet.org 253 tester 0 :unregistered connections")
+ (0 ":irc.foonet.org 254 tester 1 :channels formed")
+ (0 ":irc.foonet.org 255 tester :I have 4 clients and 0 servers")
+ (0 ":irc.foonet.org 265 tester 4 4 :Current local users 4, max 4")
+ (0 ":irc.foonet.org 266 tester 4 4 :Current global users 4, max 4")
+ (0 ":irc.foonet.org 422 tester :MOTD File is missing"))
+
+((mode-user 4.2 "MODE tester +i")
+ (0 ":irc.foonet.org 221 tester +i")
+ (0 ":irc.foonet.org NOTICE tester :This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect.")
+ (0 ":tester!~u@yuvqisyu7m7qs.irc JOIN #chan")
+ (0 ":irc.foonet.org 353 tester = #chan :tester @alice bob chester")
+ (0 ":irc.foonet.org 366 tester #chan :End of NAMES list"))
+
+((~useless-join 10 "JOIN #chan"))
+
+((mode 10 "MODE #chan")
+ (0.0 ":irc.foonet.org 324 tester #chan +nt")
+ (0.0 ":irc.foonet.org 329 tester #chan 1623563121")
+ (0.0 ":alice!~u@wyb9b355rgzi8.irc PRIVMSG #chan :tester, welcome again!")
+ (0.0 ":bob!~u@wyb9b355rgzi8.irc PRIVMSG #chan :tester, welcome again!"))
+
+((quit 4 "QUIT :" quit)
+ (0 ":tester!~u@yuvqisyu7m7qs.irc QUIT :Quit: " quit))
+
+((linger 5 LINGER))
diff --git a/test/lisp/erc/resources/base/auth-source/foonet.eld b/test/lisp/erc/resources/base/auth-source/foonet.eld
new file mode 100644
index 00000000000..1fe772c7e23
--- /dev/null
+++ b/test/lisp/erc/resources/base/auth-source/foonet.eld
@@ -0,0 +1,23 @@
+;; -*- mode: lisp-data; -*-
+((pass 1 "PASS :changeme"))
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
+ (0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.foonet.org 003 tester :This server was created Tue, 04 May 2021 05:06:18 UTC")
+ (0 ":irc.foonet.org 004 tester irc.foonet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.foonet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=FooNet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.foonet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.foonet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (0 ":irc.foonet.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.foonet.org 253 tester 0 :unregistered connections")
+ (0 ":irc.foonet.org 254 tester 1 :channels formed")
+ (0 ":irc.foonet.org 255 tester :I have 3 clients and 0 servers")
+ (0 ":irc.foonet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0 ":irc.foonet.org 422 tester :MOTD File is missing"))
+
+((mode-user 1.2 "MODE tester +i")
+ (0 ":irc.foonet.org 221 tester +i")
+ (0 ":irc.foonet.org NOTICE tester :This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect."))
diff --git a/test/lisp/erc/resources/base/auth-source/nopass.eld b/test/lisp/erc/resources/base/auth-source/nopass.eld
new file mode 100644
index 00000000000..3fdb4ecf7bc
--- /dev/null
+++ b/test/lisp/erc/resources/base/auth-source/nopass.eld
@@ -0,0 +1,22 @@
+;; -*- mode: lisp-data; -*-
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
+ (0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.foonet.org 003 tester :This server was created Tue, 04 May 2021 05:06:18 UTC")
+ (0 ":irc.foonet.org 004 tester irc.foonet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.foonet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=FooNet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.foonet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.foonet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (0 ":irc.foonet.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.foonet.org 253 tester 0 :unregistered connections")
+ (0 ":irc.foonet.org 254 tester 1 :channels formed")
+ (0 ":irc.foonet.org 255 tester :I have 3 clients and 0 servers")
+ (0 ":irc.foonet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0 ":irc.foonet.org 422 tester :MOTD File is missing"))
+
+((mode-user 1.2 "MODE tester +i")
+ (0 ":irc.foonet.org 221 tester +i")
+ (0 ":irc.foonet.org NOTICE tester :This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect."))
diff --git a/test/lisp/erc/resources/base/channel-buffer-revival/foonet.eld b/test/lisp/erc/resources/base/channel-buffer-revival/foonet.eld
new file mode 100644
index 00000000000..b09692327c7
--- /dev/null
+++ b/test/lisp/erc/resources/base/channel-buffer-revival/foonet.eld
@@ -0,0 +1,45 @@
+;; -*- mode: lisp-data; -*-
+((pass 1 "PASS :changeme"))
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
+ (0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.foonet.org 003 tester :This server was created Tue, 04 May 2021 05:06:18 UTC")
+ (0 ":irc.foonet.org 004 tester irc.foonet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.foonet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=FooNet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.foonet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.foonet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (0 ":irc.foonet.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.foonet.org 253 tester 0 :unregistered connections")
+ (0 ":irc.foonet.org 254 tester 1 :channels formed")
+ (0 ":irc.foonet.org 255 tester :I have 3 clients and 0 servers")
+ (0 ":irc.foonet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0 ":irc.foonet.org 422 tester :MOTD File is missing"))
+
+((mode-user 12 "MODE tester +i")
+ (0 ":irc.foonet.org 221 tester +i")
+ (0 ":irc.foonet.org NOTICE tester :This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect."))
+
+((join 6 "JOIN #chan")
+ (0 ":tester!~u@9g6b728983yd2.irc JOIN #chan")
+ (0 ":irc.foonet.org 353 tester = #chan :alice tester @bob")
+ (0 ":irc.foonet.org 366 tester #chan :End of NAMES list"))
+
+((mode 8 "MODE #chan")
+ (0 ":irc.foonet.org 324 tester #chan +nt")
+ (0 ":irc.foonet.org 329 tester #chan 1620104779")
+ (0.1 ":bob!~u@rz2v467q4rwhy.irc PRIVMSG #chan :tester, welcome!")
+ (0.1 ":alice!~u@rz2v467q4rwhy.irc PRIVMSG #chan :tester, welcome!")
+ (0.1 ":bob!~u@rz2v467q4rwhy.irc PRIVMSG #chan :alice: But, as it seems, did violence on herself.")
+ (0.1 ":alice!~u@rz2v467q4rwhy.irc PRIVMSG #chan :bob: Well, this is the forest of Arden.")
+ (0.1 ":bob!~u@rz2v467q4rwhy.irc PRIVMSG #chan :alice: Signior Iachimo will not from it. Pray, let us follow 'em.")
+ (0.1 ":alice!~u@rz2v467q4rwhy.irc PRIVMSG #chan :bob: Our queen and all her elves come here anon.")
+ (0.1 ":bob!~u@rz2v467q4rwhy.irc PRIVMSG #chan :alice: The ground is bloody; search about the churchyard.")
+ (0.1 ":alice!~u@rz2v467q4rwhy.irc PRIVMSG #chan :bob: You have discharged this honestly: keep it to yourself. Many likelihoods informed me of this before, which hung so tottering in the balance that I could neither believe nor misdoubt. Pray you, leave me: stall this in your bosom; and I thank you for your honest care. I will speak with you further anon.")
+ (0.1 ":bob!~u@rz2v467q4rwhy.irc PRIVMSG #chan :alice: Give me that mattock, and the wrenching iron.")
+ (0.1 ":alice!~u@rz2v467q4rwhy.irc PRIVMSG #chan :bob: Stand you! You have land enough of your own; but he added to your having, gave you some ground.")
+ (0.1 ":bob!~u@rz2v467q4rwhy.irc PRIVMSG #chan :alice: Excellent workman! Thou canst not paint a man so bad as is thyself.")
+ (0.1 ":alice!~u@rz2v467q4rwhy.irc PRIVMSG #chan :bob: And will you, being a man of your breeding, be married under a bush, like a beggar ? Get you to church, and have a good priest that can tell you what marriage is: this fellow will but join you together as they join wainscot; then one of you will prove a shrunk panel, and like green timber, warp, warp.")
+ (0.1 ":bob!~u@rz2v467q4rwhy.irc PRIVMSG #chan :alice: Live, and be prosperous; and farewell, good fellow."))
diff --git a/test/lisp/erc/resources/base/flood/soju.eld b/test/lisp/erc/resources/base/flood/soju.eld
new file mode 100644
index 00000000000..05266ca9411
--- /dev/null
+++ b/test/lisp/erc/resources/base/flood/soju.eld
@@ -0,0 +1,87 @@
+;; -*- mode: lisp-data; -*-
+((pass 1 "PASS :changeme"))
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0.13 ":soju.im 001 tester :Welcome to soju, tester")
+ (0.0 ":soju.im 002 tester :Your host is soju.im")
+ (0.0 ":soju.im 004 tester soju.im soju aiwroO OovaimnqpsrtklbeI")
+ (0.0 ":soju.im 005 tester CHATHISTORY=1000 CASEMAPPING=ascii NETWORK=Soju :are supported")
+ (0.0 ":soju.im 422 tester :No MOTD"))
+
+((mode 1 "MODE tester +i")
+ (0.0 ":tester!tester@10.0.2.100 JOIN #chan/foonet")
+ (0.25 ":soju.im 331 tester #chan/foonet :No topic is set")
+ (0.0 ":soju.im 353 tester = #chan/foonet :@bob/foonet alice/foonet tester")
+ (0.01 ":soju.im 366 tester #chan/foonet :End of /NAMES list")
+ (0.0 ":tester!tester@10.0.2.100 JOIN #chan/barnet")
+ (0.04 ":soju.im 331 tester #chan/barnet :No topic is set")
+ (0.0 ":soju.im 353 tester = #chan/barnet :tester @mike/barnet joe/barnet")
+ (0.01 ":soju.im 366 tester #chan/barnet :End of /NAMES list")
+ (0.01 ":bob/foonet PRIVMSG #chan/foonet :alice: Then this breaking of his has been but a try for his friends.")
+ (0.16 ":alice/foonet PRIVMSG #chan/foonet :bob: By my troth, I take my young lord to be a very melancholy man.")
+ (0.91 ":bob/foonet PRIVMSG #chan/foonet :alice: No, truly, for the truest poetry is the most feigning; and lovers are given to poetry, and what they swear in poetry may be said as lovers they do feign.")
+ (0.01 ":alice/foonet PRIVMSG #chan/foonet :bob: Sir, his wife some two months since fled from his house: her pretence is a pilgrimage to Saint Jaques le Grand; which holy undertaking with most austere sanctimony she accomplished; and, there residing, the tenderness of her nature became as a prey to her grief; in fine, made a groan of her last breath, and now she sings in heaven.")
+ (0.0 ":mike/barnet PRIVMSG #chan/barnet :joe: Who ? not the duke ? yes, your beggar of fifty, and his use was to put a ducat in her clack-dish; the duke had crotchets in him. He would be drunk too; that let me inform you.")
+ (0.01 ":joe/barnet PRIVMSG #chan/barnet :mike: Prove it before these varlets here, thou honourable man, prove it.")
+ (0.0 ":mike/barnet PRIVMSG #chan/barnet :joe: That my report is just and full of truth.")
+ (0.0 ":joe/barnet PRIVMSG #chan/barnet :mike: It is impossible they bear it out.")
+ ;; Expected, since we blindly send +i
+ (0.0 ":soju.im 501 tester :Cannot change user mode in multi-upstream mode"))
+
+((~mode-foonet 5 "MODE #chan/foonet")
+ (0.0 ":soju.im 324 tester #chan/foonet +nt")
+ (0.16 ":soju.im 329 tester #chan/foonet 1647158643")
+ ;; Start frantic pinging
+ (0.0 "PING :soju-msgid-1"))
+
+((~mode-barnet 5 "MODE #chan/barnet")
+ (0.0 ":soju.im 324 tester #chan/barnet +nt")
+ (0.0 ":soju.im 329 tester #chan/barnet 1647158643"))
+
+((pong-1 5 "PONG :soju-msgid-1")
+ (0.0 ":bob/foonet!~u@g56t7uz8xjj4e.irc PRIVMSG #chan/foonet :alice: The king's coming; I know by his trumpets. Sirrah, inquire further after me; I had talk of you last night: though you are a fool and a knave, you shall eat: go to, follow.")
+ (0.0 ":mike/barnet!~u@qsidzk5cytcai.irc PRIVMSG #chan/barnet :joe: Up: so. How is 't ? Feel you your legs ? You stand.")
+ (0.0 ":alice/foonet!~u@g56t7uz8xjj4e.irc PRIVMSG #chan/foonet :bob: Consider then we come but in despite.")
+ (0.1 "PING :soju-msgid-2"))
+
+((pong-2 2 "PONG :soju-msgid-2")
+ (0.1 ":joe/barnet!~u@qsidzk5cytcai.irc PRIVMSG #chan/barnet :mike: All hail, Macbeth! that shalt be king hereafter.")
+ (0.1 "PING :soju-msgid-3"))
+
+((pong-3 2 "PONG :soju-msgid-3")
+ (0.1 ":bob/foonet!~u@g56t7uz8xjj4e.irc PRIVMSG #chan/foonet :alice: And that at my bidding you could so stand up.")
+ (0.1 "PING :soju-msgid-4"))
+
+((pong-4 2 "PONG :soju-msgid-4")
+ (0.03 ":mike/barnet!~u@qsidzk5cytcai.irc PRIVMSG #chan/barnet :joe: Now he tells how she plucked him to my chamber. O! I see that nose of yours, but not the dog I shall throw it to.")
+ (0.1 "PING :soju-msgid-5"))
+
+((pong-5 2 "PONG :soju-msgid-5")
+ (0.1 ":alice/foonet!~u@g56t7uz8xjj4e.irc PRIVMSG #chan/foonet :bob: For policy sits above conscience.")
+ (0.1 "PING :soju-msgid-6"))
+
+((pong-6 2 "PONG :soju-msgid-6")
+ (0.0 ":joe/barnet!~u@qsidzk5cytcai.irc PRIVMSG #chan/barnet :mike: Take heed o' the foul fiend. Obey thy parents; keep thy word justly; swear not; commit not with man's sworn spouse; set not thy sweet heart on proud array. Tom's a-cold.")
+ (0.1 "PING :soju-msgid-7"))
+
+((pong-7 2 "PONG :soju-msgid-7")
+ (0.08 ":mike/barnet!~u@qsidzk5cytcai.irc PRIVMSG #chan/barnet :joe: To suffer with him. Good love, call him back.")
+ (0.1 "PING :soju-msgid-8"))
+
+((pong-9 2 "PONG :soju-msgid-8")
+ (0.1 ":bob/foonet!~u@g56t7uz8xjj4e.irc PRIVMSG #chan/foonet :alice: Be not obdurate, open thy deaf ears.")
+ (0.0 "PING :soju-msgid-9"))
+
+((pong-10 2 "PONG :soju-msgid-9")
+ (0.04 ":joe/barnet!~u@qsidzk5cytcai.irc PRIVMSG #chan/barnet :mike: To get good guard and go along with me.")
+ (0.1 "PING :soju-msgid-10"))
+
+((~privmsg 2 "PRIVMSG #chan/foonet :alice: hi")
+ (0.1 ":alice/foonet!~u@g56t7uz8xjj4e.irc PRIVMSG #chan/foonet :tester: Good, very good; it is so then: good, very good. Let it be concealed awhile."))
+
+((pong-11 2 "PONG :soju-msgid-10")
+ (0.1 ":alice/foonet!~u@g56t7uz8xjj4e.irc PRIVMSG #chan/foonet :bob: Some man or other must present Wall; and let him have some plaster, or some loam, or some rough-cast about him, to signify wall; and let him hold his fingers thus, and through that cranny shall Pyramus and Thisby whisper.")
+ (0.0 "PING :soju-msgid-11"))
+
+((pong-12 5 "PONG :soju-msgid-11")
+ (0.1 ":mike/barnet!~u@qsidzk5cytcai.irc PRIVMSG #chan/barnet :joe: That's he that was Othello; here I am."))
diff --git a/test/lisp/erc/resources/base/gapless-connect/barnet.eld b/test/lisp/erc/resources/base/gapless-connect/barnet.eld
new file mode 100644
index 00000000000..4e658802ef6
--- /dev/null
+++ b/test/lisp/erc/resources/base/gapless-connect/barnet.eld
@@ -0,0 +1,40 @@
+;; -*- mode: lisp-data; -*-
+((pass 10 "PASS :barnet:changeme"))
+((nick 10 "NICK tester"))
+((user 0.2 "USER user 0 * :tester")
+ (0 ":irc.barnet.org 001 tester :Welcome to the barnet IRC Network tester")
+ (0 ":irc.barnet.org 002 tester :Your host is irc.barnet.org, running version oragono-2.5.1-4860c5cad0179db1")
+ (0 ":irc.barnet.org 003 tester :This server was created Fri, 19 Mar 2021 10:23:19 UTC")
+ (0 ":irc.barnet.org 004 tester irc.barnet.org oragono-2.5.1-4860c5cad0179db1 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.barnet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m INVEX KICKLEN=390 MAXLIST=beI:60 :are supported by this server")
+ (0 ":irc.barnet.org 005 tester MAXTARGETS=4 MODES MONITOR=100 NETWORK=barnet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.barnet.org 251 tester :There are 0 users and 1 invisible on 1 server(s)")
+ (0 ":irc.barnet.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.barnet.org 254 tester 0 :channels formed")
+ (0 ":irc.barnet.org 255 tester :I have 1 clients and 0 servers")
+ (0 ":irc.barnet.org 265 tester 1 1 :Current local users 1, max 1")
+ (0 ":irc.barnet.org 266 tester 1 1 :Current global users 1, max 1")
+ (0 ":irc.barnet.org 422 tester :MOTD File is missing"))
+
+((mode-user 10.2 "MODE tester +i")
+ ;; No mode answer
+ (0 ":irc.znc.in 306 tester :You have been marked as being away")
+ (0 ":tester!~u@8cgjyczyrjgby.irc JOIN #bar")
+ (0 ":irc.barnet.org 353 tester = #bar :@mike joe tester")
+ (0 ":irc.barnet.org 366 tester #bar :End of /NAMES list.")
+ (0 ":***!znc@znc.in PRIVMSG #bar :Buffer Playback...")
+ (0 ":joe!~u@8cgjyczyrjgby.irc PRIVMSG #bar :[10:23:28] tester, welcome!")
+ (0 ":mike!~u@8cgjyczyrjgby.irc PRIVMSG #bar :[10:23:28] tester, welcome!")
+ (0 ":joe!~u@8cgjyczyrjgby.irc PRIVMSG #bar :[10:24:49] mike: Bid me farewell, and let me hear thee going.")
+ (0 ":mike!~u@8cgjyczyrjgby.irc PRIVMSG #bar :[10:24:54] joe: By heaven, thy love is black as ebony.")
+ (0 ":***!znc@znc.in PRIVMSG #bar :Playback Complete.")
+ (0 ":irc.barnet.org NOTICE tester :[10:23:22] This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect.")
+ (0 ":irc.barnet.org 305 tester :You are no longer marked as being away"))
+
+((mode 20 "MODE #bar")
+ (0 ":irc.barnet.org 324 tester #bar +nt")
+ (0 ":irc.barnet.org 329 tester #bar 1616149403")
+ (0.1 ":mike!~u@8cgjyczyrjgby.irc PRIVMSG #bar :joe: To ask of whence you are: report it.")
+ (0.1 ":joe!~u@8cgjyczyrjgby.irc PRIVMSG #bar :mike: Friar, thou knowest not the duke so well as I do: he's a better woodman than thou takest him for.")
+ (0.1 ":mike!~u@8cgjyczyrjgby.irc PRIVMSG #bar :joe: Like the sequel, I. Signior Costard, adieu.")
+ (0.1 ":joe!~u@8cgjyczyrjgby.irc PRIVMSG #bar :mike: This is his second fit; he had one yesterday."))
diff --git a/test/lisp/erc/resources/base/gapless-connect/foonet.eld b/test/lisp/erc/resources/base/gapless-connect/foonet.eld
new file mode 100644
index 00000000000..4ac4a3e5968
--- /dev/null
+++ b/test/lisp/erc/resources/base/gapless-connect/foonet.eld
@@ -0,0 +1,41 @@
+;; -*- mode: lisp-data; -*-
+((pass 1 "PASS :foonet:changeme"))
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
+ (0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.foonet.org 003 tester :This server was created Sun, 25 Apr 2021 11:28:28 UTC")
+ (0 ":irc.foonet.org 004 tester irc.foonet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.foonet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.foonet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.foonet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (0 ":irc.foonet.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.foonet.org 254 tester 1 :channels formed")
+ (0 ":irc.foonet.org 255 tester :I have 3 clients and 0 servers")
+ (0 ":irc.foonet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0 ":irc.foonet.org 422 tester :MOTD File is missing"))
+
+((mode-user 10.2 "MODE tester +i")
+ ;; No mode answer
+ (0 ":irc.znc.in 306 tester :You have been marked as being away")
+ (0 ":tester!~u@xrir8fpe4d7ak.irc JOIN #foo")
+ (0 ":irc.foonet.org 353 tester = #foo :joe @mike tester")
+ (0 ":irc.foonet.org 366 tester #foo :End of /NAMES list.")
+ (0 ":***!znc@znc.in PRIVMSG #foo :Buffer Playback...")
+ (0 ":alice!~u@svpn88yjcdj42.irc PRIVMSG #foo :[07:02:41] bob: To-morrow is the joyful day, Audrey; to-morrow will we be married.")
+ (0 ":bob!~u@svpn88yjcdj42.irc PRIVMSG #foo :[07:02:44] alice: Why dost thou call them knaves ? thou know'st them not.")
+ (0 ":alice!~u@svpn88yjcdj42.irc PRIVMSG #foo :[07:03:05] bob: Now, by the faith of my love, I will: tell me where it is.")
+ (0 ":bob!~u@svpn88yjcdj42.irc PRIVMSG #foo :[07:03:09] alice: Give me the letter; I will look on it.")
+ (0 ":***!znc@znc.in PRIVMSG #foo :Playback Complete.")
+ (0 ":irc.foonet.org NOTICE tester :[11:29:00] This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect.")
+ (0 ":irc.foonet.org 305 tester :You are no longer marked as being away"))
+
+((mode 8 "MODE #foo")
+ (0 ":irc.foonet.org 324 tester #foo +nt")
+ (0 ":irc.foonet.org 329 tester #foo 1619593200")
+ (0.1 ":alice!~u@svpn88yjcdj42.irc PRIVMSG #foo :bob: By this hand, it will not kill a fly. But come, now I will be your Rosalind in a more coming-on disposition; and ask me what you will, I will grant it.")
+ (0.1 ":bob!~u@svpn88yjcdj42.irc PRIVMSG #foo :alice: That I must love a loathed enemy.")
+ (0.1 ":alice!~u@svpn88yjcdj42.irc PRIVMSG #foo :bob: His discretion, I am sure, cannot carry his valour, for the goose carries not the fox. It is well: leave it to his discretion, and let us listen to the moon.")
+ (0.1 ":bob!~u@svpn88yjcdj42.irc PRIVMSG #foo :alice: As living here and you no use of him."))
diff --git a/test/lisp/erc/resources/base/gapless-connect/pass-stub.eld b/test/lisp/erc/resources/base/gapless-connect/pass-stub.eld
new file mode 100644
index 00000000000..0c8dfd19d00
--- /dev/null
+++ b/test/lisp/erc/resources/base/gapless-connect/pass-stub.eld
@@ -0,0 +1,4 @@
+;; -*- mode: lisp-data; -*-
+((pass 3 "PASS :" token ":changeme"))
+
+((fake 1 "FAKE no op"))
diff --git a/test/lisp/erc/resources/base/mask-target-routing/foonet.eld b/test/lisp/erc/resources/base/mask-target-routing/foonet.eld
new file mode 100644
index 00000000000..796d5566b65
--- /dev/null
+++ b/test/lisp/erc/resources/base/mask-target-routing/foonet.eld
@@ -0,0 +1,45 @@
+;; -*- mode: lisp-data; -*-
+((pass 1 "PASS :changeme"))
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
+ (0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.foonet.org 003 tester :This server was created Mon, 31 May 2021 09:56:24 UTC")
+ (0 ":irc.foonet.org 004 tester irc.foonet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.foonet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.foonet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.foonet.org 251 tester :There are 0 users and 4 invisible on 1 server(s)")
+ (0 ":irc.foonet.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.foonet.org 254 tester 2 :channels formed")
+ (0 ":irc.foonet.org 255 tester :I have 4 clients and 0 servers")
+ (0 ":irc.foonet.org 265 tester 4 4 :Current local users 4, max 4")
+ (0 ":irc.foonet.org 266 tester 4 4 :Current global users 4, max 4")
+ (0 ":irc.foonet.org 422 tester :MOTD File is missing"))
+
+((mode-user 1.2 "MODE tester +i")
+ ;; No mode answer
+ (0 ":irc.znc.in 306 tester :You have been marked as being away")
+ (0 ":tester!~u@gq7yjr7gsu7nn.irc JOIN #foo")
+ (0 ":irc.foonet.org 353 tester = #foo :alice @bob rando tester")
+ (0 ":irc.foonet.org 366 tester #foo :End of /NAMES list.")
+ (0 ":***!znc@znc.in PRIVMSG #foo :Buffer Playback...")
+ (0 ":alice!~u@gq7yjr7gsu7nn.irc PRIVMSG #foo :[10:00:02] bob: All that he is hath reference to your highness.")
+ (0 ":bob!~u@gq7yjr7gsu7nn.irc PRIVMSG #foo :[10:00:06] alice: Excellent workman! Thou canst not paint a man so bad as is thyself.")
+ (0 ":***!znc@znc.in PRIVMSG #foo :Playback Complete.")
+ (0 ":irc.foonet.org NOTICE tester :[09:56:57] This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect.")
+ (0 ":irc.foonet.org 305 tester :You are no longer marked as being away"))
+
+((mode 5 "MODE #foo")
+ (0 ":irc.foonet.org 324 tester #foo +nt")
+ (0 ":irc.foonet.org 329 tester #foo 1622454985")
+ ;; Invalid msg
+ (0.1 ":rando!~u@em2i467d4ejul.irc PRIVMSG :")
+ (0.1 ":alice!~u@gq7yjr7gsu7nn.irc PRIVMSG #foo :bob: Farewell, pretty lady: you must hold the credit of your father.")
+ (0.1 ":bob!~u@gq7yjr7gsu7nn.irc NOTICE $* :[Global notice] going down soon.")
+ (0.1 ":alice!~u@rz2v467q4rwhy.irc PRIVMSG #foo :bob: Well, this is the forest of Arden.")
+ (0.1 ":bob!~u@gq7yjr7gsu7nn.irc NOTICE $$* :[Global notice] this is a warning.")
+ (0.1 ":alice!~u@rz2v467q4rwhy.irc PRIVMSG #foo :bob: Be married under a bush, like a beggar ? Get you to church, and have a good priest that can tell you what marriage is: this fellow will but join you together as they join wainscot; then one of you will prove a shrunk panel, and like green timber, warp, warp.")
+ (0.1 ":bob!~u@gq7yjr7gsu7nn.irc PRIVMSG $* :[Global msg] second warning.")
+ (0.1 ":alice!~u@rz2v467q4rwhy.irc PRIVMSG #foo :bob: And will you, being a man of your breeding.")
+ (0.1 ":bob!~u@gq7yjr7gsu7nn.irc NOTICE #* :[Global notice] final warning."))
diff --git a/test/lisp/erc/resources/base/netid/bouncer/barnet-again.eld b/test/lisp/erc/resources/base/netid/bouncer/barnet-again.eld
new file mode 100644
index 00000000000..766035a524c
--- /dev/null
+++ b/test/lisp/erc/resources/base/netid/bouncer/barnet-again.eld
@@ -0,0 +1,50 @@
+;; -*- mode: lisp-data; -*-
+((pass 10 "PASS :barnet:changeme"))
+((nick 3 "NICK tester"))
+((user 3 "USER user 0 * :tester")
+ (0 ":irc.barnet.org 001 tester :Welcome to the barnet IRC Network tester")
+ (0 ":irc.barnet.org 002 tester :Your host is irc.barnet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.barnet.org 003 tester :This server was created Wed, 12 May 2021 07:41:08 UTC")
+ (0 ":irc.barnet.org 004 tester irc.barnet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.barnet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.barnet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=barnet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.barnet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.barnet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (0 ":irc.barnet.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.barnet.org 254 tester 1 :channels formed")
+ (0 ":irc.barnet.org 255 tester :I have 3 clients and 0 servers")
+ (0 ":irc.barnet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0 ":irc.barnet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0 ":irc.barnet.org 422 tester :MOTD File is missing"))
+
+((mode-user 10.2 "MODE tester +i")
+ ;; No mode answer ^
+
+ (0 ":tester!~u@xrir8fpe4d7ak.irc JOIN #chan")
+ (0 ":irc.barnet.org 353 tester = #chan :joe @mike tester")
+ (0 ":irc.barnet.org 366 tester #chan :End of /NAMES list.")
+ (0 ":***!znc@znc.in PRIVMSG #chan :Buffer Playback...")
+ (0 ":joe!~u@xrir8fpe4d7ak.irc PRIVMSG #chan :[07:04:25] mike: Belike, for joy the emperor hath a son.")
+ (0 ":mike!~u@xrir8fpe4d7ak.irc PRIVMSG #chan :[07:04:27] joe: Protest their first of manhood.")
+ (0 ":joe!~u@xrir8fpe4d7ak.irc PRIVMSG #chan :[07:04:29] mike: As frozen water to a starved snake.")
+ (0 ":mike!~u@xrir8fpe4d7ak.irc PRIVMSG #chan :[07:04:34] joe: My mirth it much displeas'd, but pleas'd my woe.")
+ (0 ":joe!~u@xrir8fpe4d7ak.irc PRIVMSG #chan :[07:04:38] mike: Why, Marcus, no man should be mad but I.")
+ (0 ":mike!~u@xrir8fpe4d7ak.irc PRIVMSG #chan :[07:04:44] joe: Faith, I have heard too much, for your words and performances are no kin together.")
+ (0 ":***!znc@znc.in PRIVMSG #chan :Playback Complete.")
+ (0 ":irc.barnet.org NOTICE tester :[07:00:01] This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect.")
+
+ (0 ":irc.znc.in 306 tester :You have been marked as being away")
+ (0 ":irc.barnet.org 305 tester :You are no longer marked as being away"))
+
+((~join 3 "JOIN #chan"))
+
+((mode 5 "MODE #chan")
+ (0 ":irc.barnet.org 324 tester #chan +nt")
+ (0 ":irc.barnet.org 329 tester #chan 1620805269")
+ (0.1 ":joe!~u@svpn88yjcdj42.irc PRIVMSG #chan :mike: But, in defence, by mercy, 'tis most just.")
+ (0.1 ":mike!~u@xrir8fpe4d7ak.irc PRIVMSG #chan :joe: The Marshal of France, Monsieur la Far.")
+ (0.1 ":joe!~u@xrir8fpe4d7ak.irc PRIVMSG #chan :mike: And bide the penance of each three years' day.")
+ (0.1 ":mike!~u@xrir8fpe4d7ak.irc PRIVMSG #chan :joe: Madam, within; but never man so chang'd.")
+ (0.1 ":joe!~u@xrir8fpe4d7ak.irc PRIVMSG #chan :mike: As much in private, and I'll bid adieu."))
+
+((linger 10 LINGER))
diff --git a/test/lisp/erc/resources/base/netid/bouncer/barnet-drop.eld b/test/lisp/erc/resources/base/netid/bouncer/barnet-drop.eld
new file mode 100644
index 00000000000..2c3d297b9cf
--- /dev/null
+++ b/test/lisp/erc/resources/base/netid/bouncer/barnet-drop.eld
@@ -0,0 +1,41 @@
+;; -*- mode: lisp-data; -*-
+((pass 10 "PASS :barnet:changeme"))
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0 ":irc.barnet.org 001 tester :Welcome to the barnet IRC Network tester")
+ (0 ":irc.barnet.org 002 tester :Your host is irc.barnet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.barnet.org 003 tester :This server was created Wed, 12 May 2021 07:41:08 UTC")
+ (0 ":irc.barnet.org 004 tester irc.barnet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.barnet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.barnet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=barnet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.barnet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.barnet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (0 ":irc.barnet.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.barnet.org 254 tester 1 :channels formed")
+ (0 ":irc.barnet.org 255 tester :I have 3 clients and 0 servers")
+ (0 ":irc.barnet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0 ":irc.barnet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0 ":irc.barnet.org 422 tester :MOTD File is missing"))
+
+((mode-user 10.2 "MODE tester +i")
+ ;; No mode answer ^
+ (0 ":irc.znc.in 306 tester :You have been marked as being away")
+ (0 ":irc.barnet.org 305 tester :You are no longer marked as being away"))
+
+((join 1 "JOIN #chan")
+ (0 ":tester!~u@awyxgybtkx7uq.irc JOIN #chan")
+ (0 ":irc.barnet.org 353 tester = #chan :@joe mike tester")
+ (0 ":irc.barnet.org 366 tester #chan :End of NAMES list")
+ (0.1 ":joe!~u@awyxgybtkx7uq.irc PRIVMSG #chan :tester, welcome!")
+ (0 ":mike!~u@awyxgybtkx7uq.irc PRIVMSG #chan :tester, welcome!"))
+
+((mode 1 "MODE #chan")
+ (0 ":irc.barnet.org 324 tester #chan +nt")
+ (0 ":irc.barnet.org 329 tester #chan 1620805269")
+ (0.1 ":mike!~u@awyxgybtkx7uq.irc PRIVMSG #chan :joe: But you have outfaced them all.")
+ (0.1 ":joe!~u@awyxgybtkx7uq.irc PRIVMSG #chan :mike: Why, will shall break it; will, and nothing else.")
+ (0.1 ":mike!~u@awyxgybtkx7uq.irc PRIVMSG #chan :joe: Yes, a dozen; and as many to the vantage, as would store the world they played for.")
+ (0.05 ":joe!~u@awyxgybtkx7uq.irc PRIVMSG #chan :mike: As he regards his aged father's life.")
+ (0.05 ":mike!~u@awyxgybtkx7uq.irc PRIVMSG #chan :joe: It is a rupture that you may easily heal; and the cure of it not only saves your brother, but keeps you from dishonour in doing it."))
+
+((drop 0 DROP))
diff --git a/test/lisp/erc/resources/base/netid/bouncer/barnet.eld b/test/lisp/erc/resources/base/netid/bouncer/barnet.eld
new file mode 100644
index 00000000000..abfcc6ed481
--- /dev/null
+++ b/test/lisp/erc/resources/base/netid/bouncer/barnet.eld
@@ -0,0 +1,41 @@
+;; -*- mode: lisp-data; -*-
+((pass 3 "PASS :barnet:changeme"))
+((nick 3 "NICK tester"))
+((user 3 "USER user 0 * :tester")
+ (0 ":irc.barnet.org 001 tester :Welcome to the barnet IRC Network tester")
+ (0 ":irc.barnet.org 002 tester :Your host is irc.barnet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.barnet.org 003 tester :This server was created Wed, 12 May 2021 07:41:08 UTC")
+ (0 ":irc.barnet.org 004 tester irc.barnet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.barnet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.barnet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=barnet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.barnet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.barnet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (0 ":irc.barnet.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.barnet.org 254 tester 1 :channels formed")
+ (0 ":irc.barnet.org 255 tester :I have 3 clients and 0 servers")
+ (0 ":irc.barnet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0 ":irc.barnet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0 ":irc.barnet.org 422 tester :MOTD File is missing"))
+
+((mode-user 10.2 "MODE tester +i")
+ ;; No mode answer ^
+ (0 ":irc.znc.in 306 tester :You have been marked as being away")
+ (0 ":irc.barnet.org 305 tester :You are no longer marked as being away"))
+
+((join 1 "JOIN #chan")
+ (0 ":tester!~u@awyxgybtkx7uq.irc JOIN #chan")
+ (0 ":irc.barnet.org 353 tester = #chan :@joe mike tester")
+ (0 ":irc.barnet.org 366 tester #chan :End of NAMES list")
+ (0.1 ":joe!~u@awyxgybtkx7uq.irc PRIVMSG #chan :tester, welcome!")
+ (0 ":mike!~u@awyxgybtkx7uq.irc PRIVMSG #chan :tester, welcome!"))
+
+((mode 3 "MODE #chan")
+ (0 ":irc.barnet.org 324 tester #chan +nt")
+ (0 ":irc.barnet.org 329 tester #chan 1620805269")
+ (0.1 ":mike!~u@awyxgybtkx7uq.irc PRIVMSG #chan :joe: But you have outfaced them all.")
+ (0.1 ":joe!~u@awyxgybtkx7uq.irc PRIVMSG #chan :mike: Why, will shall break it; will, and nothing else.")
+ (0.1 ":mike!~u@awyxgybtkx7uq.irc PRIVMSG #chan :joe: Yes, a dozen; and as many to the vantage, as would store the world they played for.")
+ (0.05 ":joe!~u@awyxgybtkx7uq.irc PRIVMSG #chan :mike: As he regards his aged father's life.")
+ (0.05 ":mike!~u@awyxgybtkx7uq.irc PRIVMSG #chan :joe: It is a rupture that you may easily heal; and the cure of it not only saves your brother, but keeps you from dishonour in doing it."))
+
+((linger 1 LINGER))
diff --git a/test/lisp/erc/resources/base/netid/bouncer/foonet-again.eld b/test/lisp/erc/resources/base/netid/bouncer/foonet-again.eld
new file mode 100644
index 00000000000..bf8712305a4
--- /dev/null
+++ b/test/lisp/erc/resources/base/netid/bouncer/foonet-again.eld
@@ -0,0 +1,50 @@
+;; -*- mode: lisp-data; -*-
+((pass 10 "PASS :foonet:changeme"))
+((nick 3 "NICK tester"))
+((user 3 "USER user 0 * :tester")
+ (0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
+ (0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.foonet.org 003 tester :This server was created Wed, 12 May 2021 07:41:09 UTC")
+ (0 ":irc.foonet.org 004 tester irc.foonet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.foonet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.foonet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.foonet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (0 ":irc.foonet.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.foonet.org 254 tester 1 :channels formed")
+ (0 ":irc.foonet.org 255 tester :I have 3 clients and 0 servers")
+ (0 ":irc.foonet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0 ":irc.foonet.org 422 tester :MOTD File is missing"))
+
+((mode-user 10.2 "MODE tester +i")
+ ;; No mode answer ^
+ (0 ":tester!~u@nvfhxvqm92rm6.irc JOIN #chan")
+ (0 ":irc.foonet.org 353 tester = #chan :alice @bob tester")
+ (0 ":irc.foonet.org 366 tester #chan :End of /NAMES list.")
+ (0 ":***!znc@znc.in PRIVMSG #chan :Buffer Playback...")
+ (0 ":bob!~u@svpn88yjcdj42.irc PRIVMSG #chan :[07:04:02] alice: Here come the lovers, full of joy and mirth.")
+ (0 ":alice!~u@svpn88yjcdj42.irc PRIVMSG #chan :[07:04:07] bob: According to the fool's bolt, sir, and such dulcet diseases.")
+ (0 ":bob!~u@svpn88yjcdj42.irc PRIVMSG #chan :[07:04:10] alice: And hang himself. I pray you, do my greeting.")
+ (0 ":alice!~u@svpn88yjcdj42.irc PRIVMSG #chan :[07:04:18] bob: And you sat smiling at his cruel prey.")
+ (0 ":bob!~u@svpn88yjcdj42.irc PRIVMSG #chan :[07:04:21] alice: Or never after look me in the face.")
+ (0 ":alice!~u@svpn88yjcdj42.irc PRIVMSG #chan :[07:04:25] bob: If that may be, than all is well. Come, sit down, every mother's son, and rehearse your parts. Pyramus, you begin: when you have spoken your speech, enter into that brake; and so every one according to his cue.")
+ (0 ":bob!~u@svpn88yjcdj42.irc PRIVMSG #chan :[07:04:30] alice: Where I espied the panther fast asleep.")
+ (0 ":alice!~u@svpn88yjcdj42.irc PRIVMSG #chan :[07:04:32] bob: Alas! he is too young: yet he looks successfully.")
+ (0 ":***!znc@znc.in PRIVMSG #chan :Playback Complete.")
+
+ (0 ":irc.foonet.org NOTICE tester :[07:00:32] This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect.")
+ (0 ":irc.foonet.org 305 tester :You are no longer marked as being away"))
+
+((~join 3 "JOIN #chan"))
+
+((mode 8 "MODE #chan")
+ (0 ":irc.foonet.org 324 tester #chan +nt")
+ (0 ":irc.foonet.org 329 tester #chan 1620805271")
+ (0.1 ":alice!~u@svpn88yjcdj42.irc PRIVMSG #chan :bob: Grows, lives, and dies, in single blessedness.")
+ (0.1 ":bob!~u@svpn88yjcdj42.irc PRIVMSG #chan :alice: For these two hours, Rosalind, I will leave thee.")
+ (0.1 ":alice!~u@svpn88yjcdj42.irc PRIVMSG #chan :bob: By this hand, it will not kill a fly. But come, now I will be your Rosalind in a more coming-on disposition; and ask me what you will, I will grant it.")
+ (0.1 ":bob!~u@svpn88yjcdj42.irc PRIVMSG #chan :alice: That I must love a loathed enemy.")
+ (0.1 ":alice!~u@svpn88yjcdj42.irc PRIVMSG #chan :bob: As't please your lordship: I'll leave you."))
+
+((linger 10 LINGER))
diff --git a/test/lisp/erc/resources/base/netid/bouncer/foonet-drop.eld b/test/lisp/erc/resources/base/netid/bouncer/foonet-drop.eld
new file mode 100644
index 00000000000..e3c41e2133a
--- /dev/null
+++ b/test/lisp/erc/resources/base/netid/bouncer/foonet-drop.eld
@@ -0,0 +1,46 @@
+;; -*- mode: lisp-data; -*-
+((pass 1 "PASS :foonet:changeme"))
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
+ (0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.foonet.org 003 tester :This server was created Wed, 12 May 2021 07:41:09 UTC")
+ (0 ":irc.foonet.org 004 tester irc.foonet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.foonet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.foonet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.foonet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (0 ":irc.foonet.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.foonet.org 254 tester 1 :channels formed")
+ (0 ":irc.foonet.org 255 tester :I have 3 clients and 0 servers")
+ (0 ":irc.foonet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0 ":irc.foonet.org 422 tester :MOTD File is missing"))
+
+((mode-user 10.2 "MODE tester +i")
+ ;; No mode answer ^
+ (0 ":irc.znc.in 306 tester :You have been marked as being away")
+ (0 ":irc.foonet.org 305 tester :You are no longer marked as being away"))
+
+((join 1 "JOIN #chan")
+ (0 ":tester!~u@ertp7idh9jtgi.irc JOIN #chan")
+ (0 ":irc.foonet.org 353 tester = #chan :@alice bob tester")
+ (0 ":irc.foonet.org 366 tester #chan :End of NAMES list")
+ (0.1 ":alice!~u@ertp7idh9jtgi.irc PRIVMSG #chan :tester, welcome!")
+ (0 ":bob!~u@ertp7idh9jtgi.irc PRIVMSG #chan :tester, welcome!"))
+
+((mode 1 "MODE #chan")
+ (0 ":irc.foonet.org 324 tester #chan +nt")
+ (0 ":irc.foonet.org 329 tester #chan 1620805271")
+ (0.1 ":alice!~u@ertp7idh9jtgi.irc PRIVMSG #chan :bob: He cannot be heard of. Out of doubt he is transported.")
+ (0.1 ":bob!~u@ertp7idh9jtgi.irc PRIVMSG #chan :alice: More evident than this; for this was stol'n.")
+ (0.1 ":alice!~u@ertp7idh9jtgi.irc PRIVMSG #chan :bob: Sell when you can; you are not for all markets.")
+ (0.1 ":bob!~u@ertp7idh9jtgi.irc PRIVMSG #chan :alice: There's the fool hangs on your back already.")
+ (0.1 ":alice!~u@ertp7idh9jtgi.irc PRIVMSG #chan :bob: Why, if you have a stomach to't, monsieur, if you think your mystery in stratagem can bring this instrument of honour again into its native quarter, be magnanimous in the enterprise and go on; I will grace the attempt for a worthy exploit: if you speed well in it, the duke shall both speak of it, and extend to you what further becomes his greatness, even to the utmost syllable of your worthiness.")
+ (0.1 ":bob!~u@ertp7idh9jtgi.irc PRIVMSG #chan :alice: For he hath still been tried a holy man.")
+ (0.1 ":alice!~u@ertp7idh9jtgi.irc PRIVMSG #chan :bob: To have the touches dearest priz'd.")
+ (0.1 ":bob!~u@ertp7idh9jtgi.irc PRIVMSG #chan :alice: And must advise the emperor for his good.")
+ (0.1 ":alice!~u@ertp7idh9jtgi.irc PRIVMSG #chan :bob: Orlando, my liege; the youngest son of Sir Rowland de Boys.")
+ (0.1 ":bob!~u@ertp7idh9jtgi.irc PRIVMSG #chan :alice: The ape is dead, and I must conjure him."))
+
+((drop 0 DROP))
diff --git a/test/lisp/erc/resources/base/netid/bouncer/foonet.eld b/test/lisp/erc/resources/base/netid/bouncer/foonet.eld
new file mode 100644
index 00000000000..c241c59bb88
--- /dev/null
+++ b/test/lisp/erc/resources/base/netid/bouncer/foonet.eld
@@ -0,0 +1,46 @@
+;; -*- mode: lisp-data; -*-
+((pass 3 "PASS :foonet:changeme"))
+((nick 3 "NICK tester"))
+((user 3 "USER user 0 * :tester")
+ (0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
+ (0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.foonet.org 003 tester :This server was created Wed, 12 May 2021 07:41:09 UTC")
+ (0 ":irc.foonet.org 004 tester irc.foonet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.foonet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.foonet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.foonet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (0 ":irc.foonet.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.foonet.org 254 tester 1 :channels formed")
+ (0 ":irc.foonet.org 255 tester :I have 3 clients and 0 servers")
+ (0 ":irc.foonet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0 ":irc.foonet.org 422 tester :MOTD File is missing"))
+
+((mode-user 4.2 "MODE tester +i")
+ ;; No mode answer ^
+ (0 ":irc.znc.in 306 tester :You have been marked as being away")
+ (0 ":irc.foonet.org 305 tester :You are no longer marked as being away"))
+
+((join 1 "JOIN #chan")
+ (0 ":tester!~u@ertp7idh9jtgi.irc JOIN #chan")
+ (0 ":irc.foonet.org 353 tester = #chan :@alice bob tester")
+ (0 ":irc.foonet.org 366 tester #chan :End of NAMES list")
+ (0.1 ":alice!~u@ertp7idh9jtgi.irc PRIVMSG #chan :tester, welcome!")
+ (0 ":bob!~u@ertp7idh9jtgi.irc PRIVMSG #chan :tester, welcome!"))
+
+((mode 3 "MODE #chan")
+ (0 ":irc.foonet.org 324 tester #chan +nt")
+ (0 ":irc.foonet.org 329 tester #chan 1620805271")
+ (0.1 ":alice!~u@ertp7idh9jtgi.irc PRIVMSG #chan :bob: He cannot be heard of. Out of doubt he is transported.")
+ (0.1 ":bob!~u@ertp7idh9jtgi.irc PRIVMSG #chan :alice: More evident than this; for this was stol'n.")
+ (0.1 ":alice!~u@ertp7idh9jtgi.irc PRIVMSG #chan :bob: Sell when you can; you are not for all markets.")
+ (0.1 ":bob!~u@ertp7idh9jtgi.irc PRIVMSG #chan :alice: There's the fool hangs on your back already.")
+ (0.1 ":alice!~u@ertp7idh9jtgi.irc PRIVMSG #chan :bob: Why, if you have a stomach to't, monsieur, if you think your mystery in stratagem can bring this instrument of honour again into its native quarter, be magnanimous in the enterprise and go on; I will grace the attempt for a worthy exploit: if you speed well in it, the duke shall both speak of it, and extend to you what further becomes his greatness, even to the utmost syllable of your worthiness.")
+ (0.1 ":bob!~u@ertp7idh9jtgi.irc PRIVMSG #chan :alice: For he hath still been tried a holy man.")
+ (0.1 ":alice!~u@ertp7idh9jtgi.irc PRIVMSG #chan :bob: To have the touches dearest priz'd.")
+ (0.1 ":bob!~u@ertp7idh9jtgi.irc PRIVMSG #chan :alice: And must advise the emperor for his good.")
+ (0.1 ":alice!~u@ertp7idh9jtgi.irc PRIVMSG #chan :bob: Orlando, my liege; the youngest son of Sir Rowland de Boys.")
+ (0.1 ":bob!~u@ertp7idh9jtgi.irc PRIVMSG #chan :alice: The ape is dead, and I must conjure him."))
+
+((linger 1 LINGER))
diff --git a/test/lisp/erc/resources/base/netid/bouncer/stub-again.eld b/test/lisp/erc/resources/base/netid/bouncer/stub-again.eld
new file mode 100644
index 00000000000..c666ee4fa0f
--- /dev/null
+++ b/test/lisp/erc/resources/base/netid/bouncer/stub-again.eld
@@ -0,0 +1,4 @@
+;; -*- mode: lisp-data; -*-
+((pass 10 "PASS :" token ":changeme"))
+
+((fake 1 "FAKE no op"))
diff --git a/test/lisp/erc/resources/base/netid/samenet/chester.eld b/test/lisp/erc/resources/base/netid/samenet/chester.eld
new file mode 100644
index 00000000000..8c2448733ce
--- /dev/null
+++ b/test/lisp/erc/resources/base/netid/samenet/chester.eld
@@ -0,0 +1,48 @@
+;; -*- mode: lisp-data; -*-
+((pass 1 "PASS :changeme"))
+((nick 1 "NICK chester"))
+((user 1 "USER user 0 * :chester")
+ (0 ":irc.foonet.org 001 chester :Welcome to the foonet IRC Network chester")
+ (0 ":irc.foonet.org 002 chester :Your host is irc.foonet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.foonet.org 003 chester :This server was created Sun, 13 Jun 2021 05:45:20 UTC")
+ (0 ":irc.foonet.org 004 chester irc.foonet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.foonet.org 005 chester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.foonet.org 005 chester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.foonet.org 005 chester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.foonet.org 251 chester :There are 0 users and 3 invisible on 1 server(s)")
+ (0 ":irc.foonet.org 252 chester 0 :IRC Operators online")
+ (0 ":irc.foonet.org 253 chester 1 :unregistered connections")
+ (0 ":irc.foonet.org 254 chester 1 :channels formed")
+ (0 ":irc.foonet.org 255 chester :I have 3 clients and 0 servers")
+ (0 ":irc.foonet.org 265 chester 3 4 :Current local users 3, max 4")
+ (0 ":irc.foonet.org 266 chester 3 4 :Current global users 3, max 4")
+ (0 ":irc.foonet.org 422 chester :MOTD File is missing"))
+
+((mode-user 10.2 "MODE chester +i")
+ (0 ":irc.foonet.org 221 chester +i")
+ (0 ":irc.foonet.org NOTICE chester :This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect."))
+
+((join 14 "JOIN #chan")
+ (0 ":chester!~u@yuvqisyu7m7qs.irc JOIN #chan")
+ (0 ":irc.foonet.org 353 chester = #chan :tester chester @alice bob")
+ (0 ":irc.foonet.org 366 chester #chan :End of NAMES list"))
+
+((mode 10 "MODE #chan")
+ (0.0 ":irc.foonet.org 324 chester #chan +nt")
+ (0.0 ":irc.foonet.org 329 chester #chan 1623563121")
+ (0.0 ":alice!~u@wyb9b355rgzi8.irc PRIVMSG #chan :chester, welcome!")
+ (0.0 ":bob!~u@wyb9b355rgzi8.irc PRIVMSG #chan :chester, welcome!")
+ (0.1 ":bob!~u@wyb9b355rgzi8.irc PRIVMSG #chan :alice: That ever eye with sight made heart lament.")
+ (0.1 ":alice!~u@wyb9b355rgzi8.irc PRIVMSG #chan :bob: The bitter past, more welcome is the sweet.")
+ (0.1 ":bob!~u@wyb9b355rgzi8.irc PRIVMSG #chan :alice: Dispatch, I say, and find the forester.")
+ (0.1 ":tester!~u@yuvqisyu7m7qs.irc PRIVMSG #chan :chester: hi")
+ (0.1 ":alice!~u@wyb9b355rgzi8.irc PRIVMSG #chan :bob: This was lofty! Now name the rest of the players. This is Ercles' vein, a tyrant's vein; a lover is more condoling."))
+
+((privmsg 4 "PRIVMSG #chan :hi tester")
+ (0.1 ":bob!~u@wyb9b355rgzi8.irc PRIVMSG #chan :alice: As the ox hath his bow, sir, the horse his curb, and the falcon her bells, so man hath his desires; and as pigeons bill, so wedlock would be nibbling.")
+ (0.1 ":alice!~u@wyb9b355rgzi8.irc PRIVMSG #chan :bob: Most friendship is feigning, most loving mere folly.")
+ (0.1 ":bob!~u@wyb9b355rgzi8.irc PRIVMSG #chan :alice: To employ you towards this Roman. Come, our queen."))
+
+((quit 5 "QUIT :" quit)
+ (0.0 ":tester!~u@yuvqisyu7m7qs.irc QUIT :Quit: " quit)
+ (0.0 ":chester!~u@yuvqisyu7m7qs.irc QUIT :Quit: " quit))
diff --git a/test/lisp/erc/resources/base/netid/samenet/tester.eld b/test/lisp/erc/resources/base/netid/samenet/tester.eld
new file mode 100644
index 00000000000..76312a7a14a
--- /dev/null
+++ b/test/lisp/erc/resources/base/netid/samenet/tester.eld
@@ -0,0 +1,52 @@
+;; -*- mode: lisp-data; -*-
+((pass 1 "PASS :changeme"))
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
+ (0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.foonet.org 003 tester :This server was created Sun, 13 Jun 2021 05:45:20 UTC")
+ (0 ":irc.foonet.org 004 tester irc.foonet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.foonet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.foonet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.foonet.org 251 tester :There are 0 users and 4 invisible on 1 server(s)")
+ (0 ":irc.foonet.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.foonet.org 253 tester 0 :unregistered connections")
+ (0 ":irc.foonet.org 254 tester 1 :channels formed")
+ (0 ":irc.foonet.org 255 tester :I have 4 clients and 0 servers")
+ (0 ":irc.foonet.org 265 tester 4 4 :Current local users 4, max 4")
+ (0 ":irc.foonet.org 266 tester 4 4 :Current global users 4, max 4")
+ (0 ":irc.foonet.org 422 tester :MOTD File is missing"))
+
+((mode-user 10.2 "MODE tester +i")
+ (0 ":irc.foonet.org 221 tester +i")
+ (0 ":irc.foonet.org NOTICE tester :This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect."))
+
+((join 15 "JOIN #chan")
+ (0 ":tester!~u@yuvqisyu7m7qs.irc JOIN #chan")
+ (0 ":irc.foonet.org 353 tester = #chan :tester @alice bob")
+ (0 ":irc.foonet.org 366 tester #chan :End of NAMES list"))
+
+((mode 10 "MODE #chan")
+ (0.0 ":irc.foonet.org 324 tester #chan +nt")
+ (0.0 ":irc.foonet.org 329 tester #chan 1623563121")
+ (0.0 ":alice!~u@wyb9b355rgzi8.irc PRIVMSG #chan :tester, welcome!")
+ (0.0 ":bob!~u@wyb9b355rgzi8.irc PRIVMSG #chan :tester, welcome!")
+ (0.1 ":bob!~u@wyb9b355rgzi8.irc PRIVMSG #chan :alice: Marry, that, I think, be young Petruchio.")
+ (0.4 ":alice!~u@wyb9b355rgzi8.irc PRIVMSG #chan :bob: You speak of him when he was less furnished than now he is with that which makes him both without and within.")
+ (0.2 ":chester!~u@yuvqisyu7m7qs.irc JOIN #chan")
+ (0.1 ":alice!~u@wyb9b355rgzi8.irc PRIVMSG #chan :chester, welcome!")
+ (0.1 ":bob!~u@wyb9b355rgzi8.irc PRIVMSG #chan :chester, welcome!")
+ (0.1 ":bob!~u@wyb9b355rgzi8.irc PRIVMSG #chan :alice: That ever eye with sight made heart lament.")
+ (0.1 ":alice!~u@wyb9b355rgzi8.irc PRIVMSG #chan :bob: The bitter past, more welcome is the sweet.")
+ (0.1 ":bob!~u@wyb9b355rgzi8.irc PRIVMSG #chan :alice: Dispatch, I say, and find the forester."))
+
+((privmsg 3 "PRIVMSG #chan :chester: hi")
+ (0.1 ":alice!~u@wyb9b355rgzi8.irc PRIVMSG #chan :bob: This was lofty! Now name the rest of the players. This is Ercles' vein, a tyrant's vein; a lover is more condoling.")
+ (0.1 ":chester!~u@yuvqisyu7m7qs.irc PRIVMSG #chan :hi tester")
+ (0.1 ":bob!~u@wyb9b355rgzi8.irc PRIVMSG #chan :alice: As the ox hath his bow, sir, the horse his curb, and the falcon her bells, so man hath his desires; and as pigeons bill, so wedlock would be nibbling.")
+ (0.1 ":alice!~u@wyb9b355rgzi8.irc PRIVMSG #chan :bob: Most friendship is feigning, most loving mere folly.")
+ (0.1 ":bob!~u@wyb9b355rgzi8.irc PRIVMSG #chan :alice: To employ you towards this Roman. Come, our queen."))
+
+((quit 4 "QUIT :" quit)
+ (0 ":tester!~u@yuvqisyu7m7qs.irc QUIT :Quit: " quit))
diff --git a/test/lisp/erc/resources/base/reconnect/aborted-dupe.eld b/test/lisp/erc/resources/base/reconnect/aborted-dupe.eld
new file mode 100644
index 00000000000..8e299ec44c0
--- /dev/null
+++ b/test/lisp/erc/resources/base/reconnect/aborted-dupe.eld
@@ -0,0 +1,28 @@
+;; -*- mode: lisp-data; -*-
+((pass 3 "PASS :changeme"))
+((nick 1 "NICK tester"))
+
+((user 1 "USER user 0 * :tester")
+ (0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
+ (0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.foonet.org 003 tester :This server was created Tue, 04 May 2021 05:06:18 UTC")
+ (0 ":irc.foonet.org 004 tester irc.foonet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.foonet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=FooNet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.foonet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (-0.02 ":irc.foonet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (-0.02 ":irc.foonet.org 252 tester 0 :IRC Operators online")
+ (-0.02 ":irc.foonet.org 253 tester 0 :unregistered connections")
+ (-0.02 ":irc.foonet.org 254 tester 1 :channels formed")
+ (-0.02 ":irc.foonet.org 255 tester :I have 3 clients and 0 servers")
+ (-0.02 ":irc.foonet.org 265 tester 3 3 :Current local users 3, max 3")
+ (-0.02 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3")
+ (-0.02 ":irc.foonet.org 422 tester :MOTD File is missing"))
+
+((~mode-user 3.2 "MODE tester +i")
+ (-0.02 ":irc.foonet.org 221 tester +i")
+ (-0.02 ":irc.foonet.org NOTICE tester :This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect."))
+
+((~join 10 "JOIN #chan"))
+((eof 5 EOF))
+((drop 0 DROP))
diff --git a/test/lisp/erc/resources/base/reconnect/aborted.eld b/test/lisp/erc/resources/base/reconnect/aborted.eld
new file mode 100644
index 00000000000..5c32070d85f
--- /dev/null
+++ b/test/lisp/erc/resources/base/reconnect/aborted.eld
@@ -0,0 +1,45 @@
+;; -*- mode: lisp-data; -*-
+((pass 1 "PASS :changeme"))
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
+ (0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.foonet.org 003 tester :This server was created Tue, 04 May 2021 05:06:18 UTC")
+ (0 ":irc.foonet.org 004 tester irc.foonet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.foonet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=FooNet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.foonet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.foonet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (0 ":irc.foonet.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.foonet.org 253 tester 0 :unregistered connections")
+ (0 ":irc.foonet.org 254 tester 1 :channels formed")
+ (0 ":irc.foonet.org 255 tester :I have 3 clients and 0 servers")
+ (0 ":irc.foonet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0 ":irc.foonet.org 422 tester :MOTD File is missing"))
+
+((mode-user 3.2 "MODE tester +i")
+ (0 ":irc.foonet.org 221 tester +i")
+ (0 ":irc.foonet.org NOTICE tester :This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect."))
+
+((join 12 "JOIN #chan")
+ (0 ":tester!~u@9g6b728983yd2.irc JOIN #chan")
+ (0 ":irc.foonet.org 353 tester = #chan :alice tester @bob")
+ (0 ":irc.foonet.org 366 tester #chan :End of NAMES list"))
+
+((mode 10 "MODE #chan")
+ (0 ":irc.foonet.org 324 tester #chan +nt")
+ (0 ":irc.foonet.org 329 tester #chan 1620104779")
+ (0.1 ":bob!~u@rz2v467q4rwhy.irc PRIVMSG #chan :tester, welcome!")
+ (0.1 ":alice!~u@rz2v467q4rwhy.irc PRIVMSG #chan :tester, welcome!")
+ (0.1 ":bob!~u@rz2v467q4rwhy.irc PRIVMSG #chan :alice: But, as it seems, did violence on herself.")
+ (0.1 ":alice!~u@rz2v467q4rwhy.irc PRIVMSG #chan :bob: Well, this is the forest of Arden.")
+ (0.1 ":bob!~u@rz2v467q4rwhy.irc PRIVMSG #chan :alice: Signior Iachimo will not from it. Pray, let us follow 'em.")
+ (0.1 ":alice!~u@rz2v467q4rwhy.irc PRIVMSG #chan :bob: Our queen and all her elves come here anon.")
+ (0.1 ":bob!~u@rz2v467q4rwhy.irc PRIVMSG #chan :alice: The ground is bloody; search about the churchyard.")
+ (0.1 ":alice!~u@rz2v467q4rwhy.irc PRIVMSG #chan :bob: You have discharged this honestly: keep it to yourself. Many likelihoods informed me of this before, which hung so tottering in the balance that I could neither believe nor misdoubt. Pray you, leave me: stall this in your bosom; and I thank you for your honest care. I will speak with you further anon.")
+ (0.1 ":bob!~u@rz2v467q4rwhy.irc PRIVMSG #chan :alice: Give me that mattock, and the wrenching iron.")
+ (0.1 ":alice!~u@rz2v467q4rwhy.irc PRIVMSG #chan :bob: Stand you! You have land enough of your own; but he added to your having, gave you some ground.")
+ (0.1 ":bob!~u@rz2v467q4rwhy.irc PRIVMSG #chan :alice: Excellent workman! Thou canst not paint a man so bad as is thyself.")
+ (0.1 ":alice!~u@rz2v467q4rwhy.irc PRIVMSG #chan :bob: And will you, being a man of your breeding, be married under a bush, like a beggar ? Get you to church, and have a good priest that can tell you what marriage is: this fellow will but join you together as they join wainscot; then one of you will prove a shrunk panel, and like green timber, warp, warp.")
+ (0.1 ":bob!~u@rz2v467q4rwhy.irc PRIVMSG #chan :alice: Live, and be prosperous; and farewell, good fellow."))
diff --git a/test/lisp/erc/resources/base/reconnect/options-again.eld b/test/lisp/erc/resources/base/reconnect/options-again.eld
new file mode 100644
index 00000000000..f1fcc439cc3
--- /dev/null
+++ b/test/lisp/erc/resources/base/reconnect/options-again.eld
@@ -0,0 +1,45 @@
+;; -*- mode: lisp-data; -*-
+((pass 1 "PASS :changeme"))
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
+ (0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.foonet.org 003 tester :This server was created Tue, 04 May 2021 05:06:18 UTC")
+ (0 ":irc.foonet.org 004 tester irc.foonet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.foonet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=FooNet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.foonet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.foonet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (0 ":irc.foonet.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.foonet.org 253 tester 0 :unregistered connections")
+ (0 ":irc.foonet.org 254 tester 1 :channels formed")
+ (0 ":irc.foonet.org 255 tester :I have 3 clients and 0 servers")
+ (0 ":irc.foonet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0 ":irc.foonet.org 422 tester :MOTD File is missing"))
+
+((mode-user 3.2 "MODE tester +i")
+ (0 ":irc.foonet.org 221 tester +i")
+ (0 ":irc.foonet.org NOTICE tester :This server is still in debug mode."))
+
+((~join-chan 12 "JOIN #chan")
+ (0 ":tester!~u@9g6b728983yd2.irc JOIN #chan")
+ (0 ":irc.foonet.org 353 tester = #chan :alice tester @bob")
+ (0 ":irc.foonet.org 366 tester #chan :End of NAMES list"))
+
+((~join-spam 12 "JOIN #spam")
+ (0 ":tester!~u@9g6b728983yd2.irc JOIN #spam")
+ (0 ":irc.foonet.org 353 tester = #spam :alice tester @bob")
+ (0 ":irc.foonet.org 366 tester #spam :End of NAMES list"))
+
+((~mode-chan 4 "MODE #chan")
+ (0 ":irc.foonet.org 324 tester #chan +nt")
+ (0 ":irc.foonet.org 329 tester #chan 1620104779")
+ (0.1 ":bob!~u@rz2v467q4rwhy.irc PRIVMSG #chan :alice: But, as it seems, did violence on herself.")
+ (0.1 ":alice!~u@rz2v467q4rwhy.irc PRIVMSG #chan :bob: Well, this is the forest of Arden."))
+
+((mode-spam 4 "MODE #spam")
+ (0 ":irc.foonet.org 324 tester #spam +nt")
+ (0 ":irc.foonet.org 329 tester #spam 1620104779")
+ (0.1 ":bob!~u@rz2v467q4rwhy.irc PRIVMSG #spam :alice: Signior Iachimo will not from it. Pray, let us follow 'em.")
+ (0.1 ":alice!~u@rz2v467q4rwhy.irc PRIVMSG #spam :bob: Our queen and all her elves come here anon."))
diff --git a/test/lisp/erc/resources/base/reconnect/options.eld b/test/lisp/erc/resources/base/reconnect/options.eld
new file mode 100644
index 00000000000..3b305d85594
--- /dev/null
+++ b/test/lisp/erc/resources/base/reconnect/options.eld
@@ -0,0 +1,35 @@
+;; -*- mode: lisp-data; -*-
+((pass 1 "PASS :changeme"))
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
+ (0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.foonet.org 003 tester :This server was created Tue, 04 May 2021 05:06:18 UTC")
+ (0 ":irc.foonet.org 004 tester irc.foonet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.foonet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=FooNet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.foonet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.foonet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (0 ":irc.foonet.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.foonet.org 253 tester 0 :unregistered connections")
+ (0 ":irc.foonet.org 254 tester 1 :channels formed")
+ (0 ":irc.foonet.org 255 tester :I have 3 clients and 0 servers")
+ (0 ":irc.foonet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0 ":irc.foonet.org 422 tester :MOTD File is missing"))
+
+((mode-user 3.2 "MODE tester +i")
+ (0 ":irc.foonet.org 221 tester +i")
+ (0 ":irc.foonet.org NOTICE tester :This server is in debug mode.")
+
+ (0 ":tester!~u@9g6b728983yd2.irc JOIN #chan")
+ (0 ":irc.foonet.org 353 tester = #chan :alice tester @bob")
+ (0 ":irc.foonet.org 366 tester #chan :End of NAMES list"))
+
+((mode-chan 4 "MODE #chan")
+ (0 ":irc.foonet.org 324 tester #chan +nt")
+ (0 ":irc.foonet.org 329 tester #chan 1620104779")
+ (0.1 ":bob!~u@rz2v467q4rwhy.irc PRIVMSG #chan :tester, welcome!")
+ (0.1 ":alice!~u@rz2v467q4rwhy.irc PRIVMSG #chan :tester, welcome!"))
+
+((drop 0 DROP))
diff --git a/test/lisp/erc/resources/base/reconnect/timer-last.eld b/test/lisp/erc/resources/base/reconnect/timer-last.eld
new file mode 100644
index 00000000000..23849bc1bad
--- /dev/null
+++ b/test/lisp/erc/resources/base/reconnect/timer-last.eld
@@ -0,0 +1,6 @@
+;; -*- mode: lisp-data; -*-
+((pass 1 "PASS :changeme"))
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0 ":irc.znc.in 464 tester :Invalid Password"))
+((linger 1 LINGER))
diff --git a/test/lisp/erc/resources/base/reconnect/timer.eld b/test/lisp/erc/resources/base/reconnect/timer.eld
new file mode 100644
index 00000000000..95c6af8d880
--- /dev/null
+++ b/test/lisp/erc/resources/base/reconnect/timer.eld
@@ -0,0 +1,6 @@
+;; -*- mode: lisp-data; -*-
+((pass 1 "PASS :changeme"))
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0 ":irc.znc.in 464 tester :Invalid Password"))
+((drop 0 DROP))
diff --git a/test/lisp/erc/resources/base/renick/queries/bouncer-barnet.eld b/test/lisp/erc/resources/base/renick/queries/bouncer-barnet.eld
new file mode 100644
index 00000000000..fc6cdaafe91
--- /dev/null
+++ b/test/lisp/erc/resources/base/renick/queries/bouncer-barnet.eld
@@ -0,0 +1,54 @@
+;; -*- mode: lisp-data; -*-
+((pass 3 "PASS :barnet:changeme"))
+((nick 3 "NICK tester"))
+((user 3 "USER user 0 * :tester")
+ (0 ":irc.barnet.org 001 tester :Welcome to the barnet IRC Network tester")
+ (0 ":irc.barnet.org 002 tester :Your host is irc.barnet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.barnet.org 003 tester :This server was created Tue, 01 Jun 2021 07:49:23 UTC")
+ (0 ":irc.barnet.org 004 tester irc.barnet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.barnet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.barnet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=barnet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.barnet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.barnet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (0 ":irc.barnet.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.barnet.org 254 tester 1 :channels formed")
+ (0 ":irc.barnet.org 255 tester :I have 3 clients and 0 servers")
+ (0 ":irc.barnet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0 ":irc.barnet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0 ":irc.barnet.org 422 tester :MOTD File is missing"))
+
+((mode-user 3.2 "MODE tester +i")
+ ;; No mode answer
+ (0 ":irc.znc.in 306 tester :You have been marked as being away")
+ (0 ":tester!~u@286u8jcpis84e.irc JOIN #chan")
+ (0 ":irc.barnet.org 353 tester = #chan :@joe mike rando tester")
+ (0 ":irc.barnet.org 366 tester #chan :End of /NAMES list.")
+ (0 ":***!znc@znc.in PRIVMSG #chan :Buffer Playback...")
+ (0 ":joe!~u@286u8jcpis84e.irc PRIVMSG #chan :[09:19:19] mike: Chi non te vede, non te pretia.")
+ (0 ":mike!~u@286u8jcpis84e.irc PRIVMSG #chan :[09:19:28] joe: The valiant heart's not whipt out of his trade.")
+ (0 ":***!znc@znc.in PRIVMSG #chan :Playback Complete.")
+ (0 ":rando!~u@95i756tt32ym8.irc PRIVMSG tester :[09:18:20] Why'd you pull that scene at the arcade?")
+ (0 ":rando!~u@95i756tt32ym8.irc PRIVMSG tester :[09:18:32] I had to mess up this rentacop came after me with nunchucks.")
+ (0 ":irc.barnet.org NOTICE tester :[09:13:24] This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect.")
+ (0 ":irc.barnet.org 305 tester :You are no longer marked as being away"))
+
+((mode 5 "MODE #chan")
+ (0 ":irc.barnet.org 324 tester #chan +nt")
+ (0 ":irc.barnet.org 329 tester #chan 1622538742")
+ (0.1 ":joe!~u@286u8jcpis84e.irc PRIVMSG #chan :mike: By favours several which they did bestow.")
+ (0.1 ":mike!~u@286u8jcpis84e.irc PRIVMSG #chan :joe: You, Roderigo! come, sir, I am for you."))
+
+((privmsg-a 5 "PRIVMSG rando :Linda said you were gonna kill me.")
+ (0.1 ":joe!~u@286u8jcpis84e.irc PRIVMSG #chan :mike: Play, music, then! Nay, you must do it soon.")
+ (0.1 ":rando!~u@95i756tt32ym8.irc PRIVMSG tester :Linda said? I never saw her before I came up here.")
+ (0.1 ":mike!~u@286u8jcpis84e.irc PRIVMSG #chan :joe: Of arts inhibited and out of warrant."))
+
+((privmsg-b 3 "PRIVMSG rando :You aren't with Wage?")
+ (0.1 ":joe!~u@286u8jcpis84e.irc PRIVMSG #chan :mike: But most of all, agreeing with the proclamation.")
+ (0.1 ":rando!~u@95i756tt32ym8.irc PRIVMSG tester :I think you screwed up, Case.")
+ (0.1 ":mike!~u@286u8jcpis84e.irc PRIVMSG #chan :joe: Good gentleman, go your gait, and let poor volk pass. An chud ha' bin zwaggered out of my life, 'twould not ha' bin zo long as 'tis by a vortnight. Nay, come not near th' old man; keep out, che vor ye, or ise try whether your costard or my ballow be the harder. Chill be plain with you.")
+ ;; Nick change
+ (0.1 ":rando!~u@95i756tt32ym8.irc NICK frenemy")
+ (0.1 ":joe!~u@286u8jcpis84e.irc PRIVMSG #chan :mike: Till time beget some careful remedy.")
+ (0.1 ":frenemy!~u@95i756tt32ym8.irc PRIVMSG tester :I showed up and you just fit me right into your reality picture.")
+ (0.1 ":mike!~u@286u8jcpis84e.irc PRIVMSG #chan :joe: For I have lost him on a dangerous sea."))
diff --git a/test/lisp/erc/resources/base/renick/queries/bouncer-foonet.eld b/test/lisp/erc/resources/base/renick/queries/bouncer-foonet.eld
new file mode 100644
index 00000000000..162e8bf9655
--- /dev/null
+++ b/test/lisp/erc/resources/base/renick/queries/bouncer-foonet.eld
@@ -0,0 +1,52 @@
+;; -*- mode: lisp-data; -*-
+((pass 1 "PASS :foonet:changeme"))
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
+ (0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.foonet.org 003 tester :This server was created Tue, 01 Jun 2021 07:49:22 UTC")
+ (0 ":irc.foonet.org 004 tester irc.foonet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.foonet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.foonet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.foonet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (0 ":irc.foonet.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.foonet.org 254 tester 1 :channels formed")
+ (0 ":irc.foonet.org 255 tester :I have 3 clients and 0 servers")
+ (0 ":irc.foonet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0 ":irc.foonet.org 422 tester :MOTD File is missing"))
+
+((mode-user 5.2 "MODE tester +i")
+ ;; No mode answer
+ (0 ":irc.znc.in 306 tester :You have been marked as being away")
+ (0 ":tester!~u@u4mvbswyw8gbg.irc JOIN #chan")
+ (0 ":irc.foonet.org 353 tester = #chan :alice @bob rando tester")
+ (0 ":irc.foonet.org 366 tester #chan :End of /NAMES list.")
+ (0 ":***!znc@znc.in PRIVMSG #chan :Buffer Playback...")
+ (0 ":bob!~u@u4mvbswyw8gbg.irc PRIVMSG #chan :[09:19:28] alice: Great men should drink with harness on their throats.")
+ (0 ":alice!~u@u4mvbswyw8gbg.irc PRIVMSG #chan :[09:19:31] bob: Your lips will feel them the sooner: shallow again. A more sounder instance; come.")
+ (0 ":***!znc@znc.in PRIVMSG #chan :Playback Complete.")
+ (0 ":rando!~u@bivkhq8yav938.irc PRIVMSG tester :[09:17:51] u thur?")
+ (0 ":rando!~u@bivkhq8yav938.irc PRIVMSG tester :[09:17:58] guess not")
+ (0 ":irc.foonet.org NOTICE tester :[09:12:53] This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect.")
+ (0 ":irc.foonet.org 305 tester :You are no longer marked as being away"))
+
+((mode 10 "MODE #chan")
+ (0 ":irc.foonet.org 324 tester #chan +nt")
+ (0 ":irc.foonet.org 329 tester #chan 1622538742")
+ (0.1 ":bob!~u@u4mvbswyw8gbg.irc PRIVMSG #chan :alice: When there is nothing living but thee, thou shalt be welcome. I had rather be a beggar's dog than Apemantus.")
+ (0.1 ":alice!~u@u4mvbswyw8gbg.irc PRIVMSG #chan :bob: You have simply misused our sex in your love-prate: we must have your doublot and hose plucked over your head, and show the world what the bird hath done to her own nest."))
+
+((privmsg-a 6 "PRIVMSG rando :I here")
+ (0.1 ":bob!~u@u4mvbswyw8gbg.irc PRIVMSG #chan :alice: And I will make thee think thy swan a crow.")
+ (0.1 ":rando!~u@bivkhq8yav938.irc PRIVMSG tester :u are dumb")
+ (0.1 ":alice!~u@u4mvbswyw8gbg.irc PRIVMSG #chan :bob: Lie not, to say mine eyes are murderers."))
+
+((privmsg-b 3 "PRIVMSG rando :not so")
+ (0.1 ":bob!~u@u4mvbswyw8gbg.irc PRIVMSG #chan :alice: Commit myself, my person, and the cause.")
+ ;; Nick change
+ (0.1 ":rando!~u@bivkhq8yav938.irc NICK frenemy")
+ (0.1 ":alice!~u@u4mvbswyw8gbg.irc PRIVMSG #chan :bob: Of raging waste! It cannot hold; it will not.")
+ (0.1 ":frenemy!~u@bivkhq8yav938.irc PRIVMSG tester :doubly so")
+ (0.1 ":bob!~u@u4mvbswyw8gbg.irc PRIVMSG #chan :alice: These words are razors to my wounded heart."))
diff --git a/test/lisp/erc/resources/base/renick/queries/solo.eld b/test/lisp/erc/resources/base/renick/queries/solo.eld
new file mode 100644
index 00000000000..12fa7d264e9
--- /dev/null
+++ b/test/lisp/erc/resources/base/renick/queries/solo.eld
@@ -0,0 +1,55 @@
+;; -*- mode: lisp-data; -*-
+((pass 1 "PASS :foonet:changeme"))
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
+ (0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.foonet.org 003 tester :This server was created Mon, 31 May 2021 09:56:24 UTC")
+ (0 ":irc.foonet.org 004 tester irc.foonet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.foonet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.foonet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.foonet.org 251 tester :There are 0 users and 4 invisible on 1 server(s)")
+ (0 ":irc.foonet.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.foonet.org 254 tester 2 :channels formed")
+ (0 ":irc.foonet.org 255 tester :I have 4 clients and 0 servers")
+ (0 ":irc.foonet.org 265 tester 4 4 :Current local users 4, max 4")
+ (0 ":irc.foonet.org 266 tester 4 4 :Current global users 4, max 4")
+ (0 ":irc.foonet.org 422 tester :MOTD File is missing"))
+
+((mode-user 8 "MODE tester +i")
+ ;; No mode answer
+ (0 ":irc.znc.in 306 tester :You have been marked as being away")
+ (0 ":tester!~u@gq7yjr7gsu7nn.irc JOIN #foo")
+ (0 ":irc.foonet.org 353 tester = #foo :alice @bob Lal tester")
+ (0 ":irc.foonet.org 366 tester #foo :End of /NAMES list.")
+ (0 ":***!znc@znc.in PRIVMSG #foo :Buffer Playback...")
+ (0 ":alice!~u@gq7yjr7gsu7nn.irc PRIVMSG #foo :[10:00:02] bob: All that he is hath reference to your highness.")
+ (0 ":bob!~u@gq7yjr7gsu7nn.irc PRIVMSG #foo :[10:00:06] alice: Excellent workman! Thou canst not paint a man so bad as is thyself.")
+ (0 ":***!znc@znc.in PRIVMSG #foo :Playback Complete.")
+ (0 ":irc.foonet.org NOTICE tester :[09:56:57] This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect.")
+ (0 ":irc.foonet.org 305 tester :You are no longer marked as being away"))
+
+((mode 1 "MODE #foo")
+ (0 ":irc.foonet.org 324 tester #foo +nt")
+ (0 ":irc.foonet.org 329 tester #foo 1622454985")
+ (0.1 ":alice!~u@gq7yjr7gsu7nn.irc PRIVMSG #foo :bob: Farewell, pretty lady: you must hold the credit of your father.")
+ (0.1 ":bob!~u@gq7yjr7gsu7nn.irc PRIVMSG #foo :alice: On Thursday, sir ? the time is very short."))
+
+((privmsg-a 10 "PRIVMSG #foo :hi")
+ (0.2 ":Lal!~u@b82mytupn2t5k.irc PRIVMSG tester :hello")
+ (0.2 ":bob!~u@gq7yjr7gsu7nn.irc PRIVMSG #foo :alice: And brought to yoke, the enemies of Rome.")
+ (0.2 ":alice!~u@gq7yjr7gsu7nn.irc PRIVMSG #foo :bob: Thou art thy father's daughter; there's enough."))
+
+((privmsg-b 10 "PRIVMSG Lal :hi")
+ (0.2 ":bob!~u@gq7yjr7gsu7nn.irc PRIVMSG #foo :alice: Here are the beetle brows shall blush for me.")
+ (0.2 ":Lal!~u@b82mytupn2t5k.irc NICK Linguo")
+ (0.2 ":alice!~u@gq7yjr7gsu7nn.irc PRIVMSG #foo :bob: He hath abandoned his physicians, madam; under whose practices he hath persecuted time with hope, and finds no other advantage in the process but only the losing of hope by time."))
+
+((privmsg-c 10 "PRIVMSG Linguo :howdy Linguo")
+ (0.1 ":bob!~u@gq7yjr7gsu7nn.irc PRIVMSG #foo :alice: And brought to yoke, the enemies of Rome.")
+ (0.2 ":Linguo!~u@b82mytupn2t5k.irc PART #foo"))
+
+((part 10 "PART #foo :\2ERC\2")
+ (0 ":tester!~u@gq7yjr7gsu7nn.irc PART #foo :\2ERC\2")
+ (0.1 ":Linguo!~u@b82mytupn2t5k.irc PRIVMSG tester :get along little doggie"))
diff --git a/test/lisp/erc/resources/base/renick/self/auto.eld b/test/lisp/erc/resources/base/renick/self/auto.eld
new file mode 100644
index 00000000000..851db7f1cf7
--- /dev/null
+++ b/test/lisp/erc/resources/base/renick/self/auto.eld
@@ -0,0 +1,46 @@
+;; -*- mode: lisp-data; -*-
+((pass 1 "PASS :foonet:changeme"))
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0 ":irc.foonet.org 001 tester :Welcome to the FooNet Internet Relay Chat Network tester")
+ (0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org[188.240.145.101/6697], running version solanum-1.0-dev")
+ (0 ":irc.foonet.org 003 tester :This server was created Sat May 22 2021 at 19:04:17 UTC")
+ (0 ":irc.foonet.org 004 tester irc.foonet.org solanum-1.0-dev DGQRSZaghilopsuwz CFILMPQSbcefgijklmnopqrstuvz bkloveqjfI")
+ (0 ":irc.foonet.org 005 tester WHOX FNC KNOCK SAFELIST ELIST=CTU CALLERID=g MONITOR=100 ETRACE CHANTYPES=# EXCEPTS INVEX CHANMODES=eIbq,k,flj,CFLMPQScgimnprstuz :are supported by this server")
+ (0 ":irc.foonet.org 005 tester CHANLIMIT=#:250 PREFIX=(ov)@+ MAXLIST=bqeI:100 MODES=4 NETWORK=foonet STATUSMSG=@+ CASEMAPPING=rfc1459 NICKLEN=16 MAXNICKLEN=16 CHANNELLEN=50 TOPICLEN=390 DEAF=D :are supported by this server")
+ (0 ":irc.foonet.org 005 tester TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,PRIVMSG:4,NOTICE:4,ACCEPT:,MONITOR: EXTBAN=$,ajrxz CLIENTVER=3.0 :are supported by this server")
+ (0 ":irc.foonet.org 251 tester :There are 33 users and 14113 invisible on 17 servers")
+ (0 ":irc.foonet.org 252 tester 34 :IRC Operators online")
+ (0 ":irc.foonet.org 254 tester 12815 :channels formed")
+ (0 ":irc.foonet.org 255 tester :I have 726 clients and 1 servers")
+ (0 ":irc.foonet.org 265 tester 726 739 :Current local users 726, max 739")
+ (0 ":irc.foonet.org 266 tester 14146 14541 :Current global users 14146, max 14541")
+ (0 ":irc.foonet.org 250 tester :Highest connection count: 740 (739 clients) (3790 connections received)")
+ (0 ":tester!~u@gq7yjr7gsu7nn.irc NICK :dummy")
+ (0 ":irc.foonet.org 375 dummy :- irc.foonet.org Message of the Day - ")
+ (0 ":irc.foonet.org 372 dummy :- This server provided by NORDUnet/SUNET")
+ (0 ":irc.foonet.org 372 dummy :- Welcome to foonet, the IRC network for free & open-source software")
+ (0 ":irc.foonet.org 372 dummy :- and peer directed projects.")
+ (0 ":irc.foonet.org 372 dummy :- ")
+ (0 ":irc.foonet.org 372 dummy :- Please visit us in #libera for questions and support.")
+ (0 ":irc.foonet.org 376 dummy :End of /MOTD command."))
+
+((mode-user 10.2 "MODE dummy +i")
+ (0 ":dummy!~u@gq7yjr7gsu7nn.irc MODE dummy :+RZi")
+ (0 ":irc.znc.in 306 dummy :You have been marked as being away")
+ (0 ":dummy!~u@gq7yjr7gsu7nn.irc JOIN #foo")
+
+ (0 ":irc.foonet.org 353 dummy = #foo :alice @bob Lal dummy")
+ (0 ":irc.foonet.org 366 dummy #foo :End of /NAMES list.")
+ (0 ":***!znc@znc.in PRIVMSG #foo :Buffer Playback...")
+ (0 ":alice!~u@gq7yjr7gsu7nn.irc PRIVMSG #foo :[10:00:02] bob: All that he is hath reference to your highness.")
+ (0 ":bob!~u@gq7yjr7gsu7nn.irc PRIVMSG #foo :[10:00:06] alice: Excellent workman! Thou canst not paint a man so bad as is thyself.")
+ (0 ":***!znc@znc.in PRIVMSG #foo :Playback Complete.")
+ (0 ":irc.foonet.org NOTICE dummy :[09:56:57] This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect.")
+ (0 ":irc.foonet.org 305 dummy :You are no longer marked as being away"))
+
+((mode 10 "MODE #foo")
+ (0 ":irc.foonet.org 324 dummy #foo +nt")
+ (0 ":irc.foonet.org 329 dummy #foo 1622454985")
+ (0.1 ":alice!~u@gq7yjr7gsu7nn.irc PRIVMSG #foo :bob: Farewell, pretty lady: you must hold the credit of your father.")
+ (0.1 ":bob!~u@gq7yjr7gsu7nn.irc PRIVMSG #foo :alice: On Thursday, sir ? the time is very short."))
diff --git a/test/lisp/erc/resources/base/renick/self/manual.eld b/test/lisp/erc/resources/base/renick/self/manual.eld
new file mode 100644
index 00000000000..dd107b806d5
--- /dev/null
+++ b/test/lisp/erc/resources/base/renick/self/manual.eld
@@ -0,0 +1,50 @@
+;; -*- mode: lisp-data; -*-
+((pass 1 "PASS :foonet:changeme"))
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0 ":irc.foonet.org 001 tester :Welcome to the FooNet Internet Relay Chat Network tester")
+ (0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org[188.240.145.101/6697], running version solanum-1.0-dev")
+ (0 ":irc.foonet.org 003 tester :This server was created Sat May 22 2021 at 19:04:17 UTC")
+ (0 ":irc.foonet.org 004 tester irc.foonet.org solanum-1.0-dev DGQRSZaghilopsuwz CFILMPQSbcefgijklmnopqrstuvz bkloveqjfI")
+ (0 ":irc.foonet.org 005 tester WHOX FNC KNOCK SAFELIST ELIST=CTU CALLERID=g MONITOR=100 ETRACE CHANTYPES=# EXCEPTS INVEX CHANMODES=eIbq,k,flj,CFLMPQScgimnprstuz :are supported by this server")
+ (0 ":irc.foonet.org 005 tester CHANLIMIT=#:250 PREFIX=(ov)@+ MAXLIST=bqeI:100 MODES=4 NETWORK=foonet STATUSMSG=@+ CASEMAPPING=rfc1459 NICKLEN=16 MAXNICKLEN=16 CHANNELLEN=50 TOPICLEN=390 DEAF=D :are supported by this server")
+ (0 ":irc.foonet.org 005 tester TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,PRIVMSG:4,NOTICE:4,ACCEPT:,MONITOR: EXTBAN=$,ajrxz CLIENTVER=3.0 :are supported by this server")
+ (0 ":irc.foonet.org 251 tester :There are 33 users and 14113 invisible on 17 servers")
+ (0 ":irc.foonet.org 252 tester 34 :IRC Operators online")
+ (0 ":irc.foonet.org 254 tester 12815 :channels formed")
+ (0 ":irc.foonet.org 255 tester :I have 726 clients and 1 servers")
+ (0 ":irc.foonet.org 265 tester 726 739 :Current local users 726, max 739")
+ (0 ":irc.foonet.org 266 tester 14146 14541 :Current global users 14146, max 14541")
+ (0 ":irc.foonet.org 250 tester :Highest connection count: 740 (739 clients) (3790 connections received)")
+ (0 ":irc.foonet.org 375 tester :- irc.foonet.org Message of the Day - ")
+ (0 ":irc.foonet.org 372 tester :- This server provided by NORDUnet/SUNET")
+ (0 ":irc.foonet.org 372 tester :- Welcome to foonet, the IRC network for free & open-source software")
+ (0 ":irc.foonet.org 372 tester :- and peer directed projects.")
+ (0 ":irc.foonet.org 372 tester :- ")
+ (0 ":irc.foonet.org 372 tester :- Please visit us in #libera for questions and support.")
+ (0 ":irc.foonet.org 376 tester :End of /MOTD command."))
+
+((mode-user 1.2 "MODE tester +i")
+ (0 ":tester!~u@gq7yjr7gsu7nn.irc MODE tester :+RZi")
+ (0 ":irc.znc.in 306 tester :You have been marked as being away")
+ (0 ":tester!~u@gq7yjr7gsu7nn.irc JOIN #foo")
+
+ (0 ":irc.foonet.org 353 tester = #foo :alice @bob Lal tester")
+ (0 ":irc.foonet.org 366 tester #foo :End of /NAMES list.")
+ (0 ":***!znc@znc.in PRIVMSG #foo :Buffer Playback...")
+ (0 ":alice!~u@gq7yjr7gsu7nn.irc PRIVMSG #foo :[10:00:02] bob: All that he is hath reference to your highness.")
+ (0 ":bob!~u@gq7yjr7gsu7nn.irc PRIVMSG #foo :[10:00:06] alice: Excellent workman! Thou canst not paint a man so bad as is thyself.")
+ (0 ":***!znc@znc.in PRIVMSG #foo :Playback Complete.")
+ (0 ":irc.foonet.org NOTICE tester :[09:56:57] This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect.")
+ (0 ":irc.foonet.org 305 tester :You are no longer marked as being away"))
+
+((mode 1 "MODE #foo")
+ (0 ":irc.foonet.org 324 tester #foo +nt")
+ (0 ":irc.foonet.org 329 tester #foo 1622454985")
+ (0.1 ":alice!~u@gq7yjr7gsu7nn.irc PRIVMSG #foo :bob: Farewell, pretty lady: you must hold the credit of your father.")
+ (0.1 ":bob!~u@gq7yjr7gsu7nn.irc PRIVMSG #foo :alice: On Thursday, sir ? the time is very short."))
+
+((nick 2 "NICK dummy")
+ (0 ":tester!~u@gq7yjr7gsu7nn.irc NICK :dummy")
+ (0.1 ":dummy!~u@gq7yjr7gsu7nn.irc MODE dummy :+RZi")
+ (0.1 ":bob!~u@gq7yjr7gsu7nn.irc PRIVMSG #foo :dummy: Hi."))
diff --git a/test/lisp/erc/resources/base/renick/self/qual-chester.eld b/test/lisp/erc/resources/base/renick/self/qual-chester.eld
new file mode 100644
index 00000000000..75b50fe68bd
--- /dev/null
+++ b/test/lisp/erc/resources/base/renick/self/qual-chester.eld
@@ -0,0 +1,40 @@
+;; -*- mode: lisp-data; -*-
+((pass 1 "PASS :changeme"))
+((nick 1 "NICK chester"))
+((user 1 "USER user 0 * :chester")
+ (0 ":irc.foonet.org 001 chester :Welcome to the foonet IRC Network chester")
+ (0 ":irc.foonet.org 002 chester :Your host is irc.foonet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.foonet.org 003 chester :This server was created Sun, 13 Jun 2021 05:45:20 UTC")
+ (0 ":irc.foonet.org 004 chester irc.foonet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.foonet.org 005 chester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.foonet.org 005 chester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.foonet.org 005 chester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.foonet.org 251 chester :There are 0 users and 3 invisible on 1 server(s)")
+ (0 ":irc.foonet.org 252 chester 0 :IRC Operators online")
+ (0 ":irc.foonet.org 253 chester 1 :unregistered connections")
+ (0 ":irc.foonet.org 254 chester 1 :channels formed")
+ (0 ":irc.foonet.org 255 chester :I have 3 clients and 0 servers")
+ (0 ":irc.foonet.org 265 chester 3 4 :Current local users 3, max 4")
+ (0 ":irc.foonet.org 266 chester 3 4 :Current global users 3, max 4")
+ (0 ":irc.foonet.org 422 chester :MOTD File is missing"))
+
+((mode-user 1.2 "MODE chester +i")
+ (0 ":irc.foonet.org 221 chester +i")
+ (0 ":irc.foonet.org NOTICE chester :This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect."))
+
+((join 14 "JOIN #chan")
+ (0 ":chester!~u@yuvqisyu7m7qs.irc JOIN #chan")
+ (0 ":irc.foonet.org 353 chester = #chan :tester chester @alice bob")
+ (0 ":irc.foonet.org 366 chester #chan :End of NAMES list"))
+
+((mode 10 "MODE #chan")
+ (0.0 ":irc.foonet.org 324 chester #chan +nt")
+ (0.0 ":irc.foonet.org 329 chester #chan 1623563121")
+ (0.0 ":alice!~u@wyb9b355rgzi8.irc PRIVMSG #chan :chester, welcome!")
+ (0.0 ":bob!~u@wyb9b355rgzi8.irc PRIVMSG #chan :chester, welcome!")
+ (0 ":tester!~u@gq7yjr7gsu7nn.irc NICK :dummy")
+ (0.1 ":bob!~u@wyb9b355rgzi8.irc PRIVMSG #chan :alice: That ever eye with sight made heart lament.")
+ (0.1 ":alice!~u@wyb9b355rgzi8.irc PRIVMSG #chan :bob: The bitter past, more welcome is the sweet.")
+ (0.1 ":bob!~u@wyb9b355rgzi8.irc PRIVMSG #chan :alice: Dispatch, I say, and find the forester."))
+
+((linger 10 LINGER))
diff --git a/test/lisp/erc/resources/base/renick/self/qual-tester.eld b/test/lisp/erc/resources/base/renick/self/qual-tester.eld
new file mode 100644
index 00000000000..25199226658
--- /dev/null
+++ b/test/lisp/erc/resources/base/renick/self/qual-tester.eld
@@ -0,0 +1,46 @@
+;; -*- mode: lisp-data; -*-
+((pass 1 "PASS :changeme"))
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
+ (0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.foonet.org 003 tester :This server was created Sun, 13 Jun 2021 05:45:20 UTC")
+ (0 ":irc.foonet.org 004 tester irc.foonet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.foonet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.foonet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.foonet.org 251 tester :There are 0 users and 4 invisible on 1 server(s)")
+ (0 ":irc.foonet.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.foonet.org 253 tester 0 :unregistered connections")
+ (0 ":irc.foonet.org 254 tester 1 :channels formed")
+ (0 ":irc.foonet.org 255 tester :I have 4 clients and 0 servers")
+ (0 ":irc.foonet.org 265 tester 4 4 :Current local users 4, max 4")
+ (0 ":irc.foonet.org 266 tester 4 4 :Current global users 4, max 4")
+ (0 ":irc.foonet.org 422 tester :MOTD File is missing"))
+
+((mode-user 1.2 "MODE tester +i")
+ (0 ":irc.foonet.org 221 tester +i")
+ (0 ":irc.foonet.org NOTICE tester :This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect."))
+
+((join 15 "JOIN #chan")
+ (0 ":tester!~u@yuvqisyu7m7qs.irc JOIN #chan")
+ (0 ":irc.foonet.org 353 tester = #chan :tester @alice bob")
+ (0 ":irc.foonet.org 366 tester #chan :End of NAMES list"))
+
+((mode 10 "MODE #chan")
+ (0.0 ":irc.foonet.org 324 tester #chan +nt")
+ (0.0 ":irc.foonet.org 329 tester #chan 1623563121")
+ (0.0 ":alice!~u@wyb9b355rgzi8.irc PRIVMSG #chan :tester, welcome!")
+ (0.0 ":bob!~u@wyb9b355rgzi8.irc PRIVMSG #chan :tester, welcome!")
+ (0.1 ":bob!~u@wyb9b355rgzi8.irc PRIVMSG #chan :alice: Marry, that, I think, be young Petruchio.")
+ (0.4 ":alice!~u@wyb9b355rgzi8.irc PRIVMSG #chan :bob: You speak of him when he was less furnished than now he is with that which makes him both without and within.")
+ (0.2 ":chester!~u@yuvqisyu7m7qs.irc JOIN #chan")
+ (0.1 ":alice!~u@wyb9b355rgzi8.irc PRIVMSG #chan :chester, welcome!")
+ (0.1 ":bob!~u@wyb9b355rgzi8.irc PRIVMSG #chan :chester, welcome!"))
+
+((nick 5 "NICK dummy")
+ (0 ":tester!~u@gq7yjr7gsu7nn.irc NICK :dummy")
+ (0.1 ":dummy!~u@gq7yjr7gsu7nn.irc MODE dummy :+RZi")
+ (0.1 ":bob!~u@wyb9b355rgzi8.irc PRIVMSG #chan :alice: That ever eye with sight made heart lament.")
+ (0.1 ":alice!~u@wyb9b355rgzi8.irc PRIVMSG #chan :bob: The bitter past, more welcome is the sweet.")
+ (0.1 ":bob!~u@wyb9b355rgzi8.irc PRIVMSG #chan :alice: Dispatch, I say, and find the forester."))
diff --git a/test/lisp/erc/resources/base/reuse-buffers/channel/barnet.eld b/test/lisp/erc/resources/base/reuse-buffers/channel/barnet.eld
new file mode 100644
index 00000000000..82700c5912c
--- /dev/null
+++ b/test/lisp/erc/resources/base/reuse-buffers/channel/barnet.eld
@@ -0,0 +1,68 @@
+;; -*- mode: lisp-data; -*-
+((pass 3 "PASS :barnet:changeme"))
+((nick 3 "NICK tester"))
+((user 3 "USER user 0 * :tester")
+ (0 ":irc.barnet.org 001 tester :Welcome to the barnet IRC Network tester")
+ (0 ":irc.barnet.org 002 tester :Your host is irc.barnet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.barnet.org 003 tester :This server was created Wed, 05 May 2021 09:05:33 UTC")
+ (0 ":irc.barnet.org 004 tester irc.barnet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.barnet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.barnet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=barnet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.barnet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.barnet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (0 ":irc.barnet.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.barnet.org 254 tester 1 :channels formed")
+ (0 ":irc.barnet.org 255 tester :I have 3 clients and 0 servers")
+ (0 ":irc.barnet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0 ":irc.barnet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0 ":irc.barnet.org 422 tester :MOTD File is missing"))
+
+((mode-user 10.2 "MODE tester +i")
+ ;; No mode answer
+ (0 ":irc.znc.in 306 tester :You have been marked as being away")
+ (0 ":tester!~u@wvys46tx8tpmk.irc JOIN #chan")
+ (0 ":irc.barnet.org 353 tester = #chan :joe @mike tester")
+ (0 ":irc.barnet.org 366 tester #chan :End of /NAMES list.")
+ (0 ":***!znc@znc.in PRIVMSG #chan :Buffer Playback...")
+ (0 ":mike!~u@wvys46tx8tpmk.irc PRIVMSG #chan :[09:09:16] joe: Tush! none but minstrels like of sonneting.")
+ (0 ":joe!~u@wvys46tx8tpmk.irc PRIVMSG #chan :[09:09:19] mike: Prithee, nuncle, be contented; 'tis a naughty night to swim in. Now a little fire in a wide field were like an old lecher's heart; a small spark, all the rest on's body cold. Look! here comes a walking fire.")
+ (0 ":mike!~u@wvys46tx8tpmk.irc PRIVMSG #chan :[09:09:22] joe: My name is Edgar, and thy father's son.")
+ (0 ":joe!~u@wvys46tx8tpmk.irc PRIVMSG #chan :[09:09:26] mike: Good my lord, be good to me; your honour is accounted a merciful man; good my lord.")
+ (0 ":mike!~u@wvys46tx8tpmk.irc PRIVMSG #chan :[09:09:31] joe: Thy child shall live, and I will see it nourish'd.")
+ (0 ":joe!~u@wvys46tx8tpmk.irc PRIVMSG #chan :[09:09:33] mike: Quick, quick; fear nothing; I'll be at thy elbow.")
+ (0 ":***!znc@znc.in PRIVMSG #chan :Playback Complete.")
+ (0 ":irc.barnet.org NOTICE tester :[09:05:35] This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect.")
+ (0 ":irc.barnet.org 305 tester :You are no longer marked as being away"))
+
+((mode 3 "MODE #chan")
+ (0 ":irc.barnet.org 324 tester #chan +nt")
+ (0 ":irc.barnet.org 329 tester #chan 1620205534")
+ (0.1 ":mike!~u@wvys46tx8tpmk.irc PRIVMSG #chan :joe: That will be given to the loudest noise we make.")
+ (0.1 ":joe!~u@wvys46tx8tpmk.irc PRIVMSG #chan :mike: If it please your honour, I am the poor duke's constable, and my name is Elbow: I do lean upon justice, sir; and do bring in here before your good honour two notorious benefactors.")
+ (0.1 ":mike!~u@wvys46tx8tpmk.irc PRIVMSG #chan :joe: Following the signs, woo'd but the sign of she.")
+ (0.5 ":joe!~u@wvys46tx8tpmk.irc PRIVMSG #chan :mike: That, sir, which I will not report after her.")
+ (0.1 ":mike!~u@wvys46tx8tpmk.irc PRIVMSG #chan :joe: Boyet, prepare: I will away to-night.")
+ (0.1 ":joe!~u@wvys46tx8tpmk.irc PRIVMSG #chan :mike: If the man be a bachelor, sir, I can; but if he be a married man, he is his wife's head, and I can never cut off a woman's head.")
+ (0.1 ":mike!~u@wvys46tx8tpmk.irc PRIVMSG #chan :joe: Thyself upon thy virtues, they on thee.")
+ (0.1 ":joe!~u@wvys46tx8tpmk.irc PRIVMSG #chan :mike: Arm it in rags, a pigmy's straw doth pierce it."))
+
+((part 5.1 "PART #chan :" quit)
+ (0 ":tester!~u@wvys46tx8tpmk.irc PART #chan :" quit))
+
+((join 10.1 "JOIN #chan")
+ (0 ":tester!~u@wvys46tx8tpmk.irc JOIN #chan")
+ (0 ":irc.barnet.org 353 tester = #chan :@mike joe tester")
+ (0 ":irc.barnet.org 366 tester #chan :End of NAMES list")
+ (0.1 ":mike!~u@wvys46tx8tpmk.irc PRIVMSG #chan :tester, welcome!")
+ (0 ":joe!~u@wvys46tx8tpmk.irc PRIVMSG #chan :tester, welcome!"))
+
+((mode 1 "MODE #chan")
+ (0 ":irc.barnet.org 324 tester #chan +nt")
+ (0 ":irc.barnet.org 329 tester #chan 1620205534")
+ (0.1 ":mike!~u@wvys46tx8tpmk.irc PRIVMSG #chan :joe: Chi non te vede, non te pretia.")
+ (0.1 ":joe!~u@wvys46tx8tpmk.irc PRIVMSG #chan :mike: Well, if ever thou dost fall from this faith, thou wilt prove a notable argument.")
+ (0.1 ":mike!~u@wvys46tx8tpmk.irc PRIVMSG #chan :joe: Of heavenly oaths, vow'd with integrity.")
+ (0.1 ":joe!~u@wvys46tx8tpmk.irc PRIVMSG #chan :mike: These herblets shall, which we upon you strew.")
+ (0.1 ":mike!~u@wvys46tx8tpmk.irc PRIVMSG #chan :joe: Aaron will have his soul black like his face."))
+
+((linger 0.5 LINGER))
diff --git a/test/lisp/erc/resources/base/reuse-buffers/channel/foonet.eld b/test/lisp/erc/resources/base/reuse-buffers/channel/foonet.eld
new file mode 100644
index 00000000000..a11cfac2e73
--- /dev/null
+++ b/test/lisp/erc/resources/base/reuse-buffers/channel/foonet.eld
@@ -0,0 +1,66 @@
+;; -*- mode: lisp-data; -*-
+((pass 1 "PASS :foonet:changeme"))
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
+ (0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.foonet.org 003 tester :This server was created Wed, 05 May 2021 09:05:34 UTC")
+ (0 ":irc.foonet.org 004 tester irc.foonet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.foonet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.foonet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.foonet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (0 ":irc.foonet.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.foonet.org 254 tester 1 :channels formed")
+ (0 ":irc.foonet.org 255 tester :I have 3 clients and 0 servers")
+ (0 ":irc.foonet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0 ":irc.foonet.org 422 tester :MOTD File is missing"))
+
+((mode-user 12 "MODE tester +i")
+ ;; No mode answer
+ (0 ":irc.znc.in 306 tester :You have been marked as being away")
+ (0 ":tester!~u@247eaxkrufj44.irc JOIN #chan")
+ (0 ":irc.foonet.org 353 tester = #chan :alice @bob tester")
+ (0 ":irc.foonet.org 366 tester #chan :End of /NAMES list.")
+ (0 ":***!znc@znc.in PRIVMSG #chan :Buffer Playback...")
+ (0 ":alice!~u@yppdd5tt4admc.irc PRIVMSG #chan :[09:07:19] bob: Is this; she hath bought the name of whore thus dearly.")
+ (0 ":bob!~u@yppdd5tt4admc.irc PRIVMSG #chan :[09:07:24] alice: He sent to me, sir,Here he comes.")
+ (0 ":alice!~u@yppdd5tt4admc.irc PRIVMSG #chan :[09:07:26] bob: Till I torment thee for this injury.")
+ (0 ":bob!~u@yppdd5tt4admc.irc PRIVMSG #chan :[09:07:29] alice: There's an Italian come; and 'tis thought, one of Leonatus' friends.")
+ (0 ":alice!~u@yppdd5tt4admc.irc PRIVMSG #chan :[09:09:33] bob: Ay, and the particular confirmations, point from point, to the full arming of the verity.")
+ (0 ":bob!~u@yppdd5tt4admc.irc PRIVMSG #chan :[09:09:35] alice: Kneel in the streets and beg for grace in vain.")
+ (0 ":***!znc@znc.in PRIVMSG #chan :Playback Complete.")
+ (0 ":irc.foonet.org NOTICE tester :[09:06:05] This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect.")
+ (0 ":irc.foonet.org 305 tester :You are no longer marked as being away"))
+
+((mode 10 "MODE #chan")
+ (0 ":irc.foonet.org 324 tester #chan +nt")
+ (0 ":irc.foonet.org 329 tester #chan 1620205534")
+ (0.5 ":bob!~u@yppdd5tt4admc.irc PRIVMSG #chan :alice: Nor I no strength to climb without thy help.")
+ (0.1 ":alice!~u@yppdd5tt4admc.irc PRIVMSG #chan :bob: Nothing, but let him have thanks. Demand of him my condition, and what credit I have with the duke.")
+ (0.1 ":bob!~u@yppdd5tt4admc.irc PRIVMSG #chan :alice: Show me this piece. I am joyful of your sights.")
+ (0.2 ":alice!~u@yppdd5tt4admc.irc PRIVMSG #chan :bob: Whilst I can shake my sword or hear the drum."))
+
+((part 5 "PART #chan :" quit)
+ (0 ":tester!~u@247eaxkrufj44.irc PART #chan :" quit))
+
+((join 10 "JOIN #chan")
+ (0 ":tester!~u@247eaxkrufj44.irc JOIN #chan")
+ (0 ":irc.foonet.org 353 tester = #chan :@bob alice tester")
+ (0 ":irc.foonet.org 366 tester #chan :End of NAMES list")
+ (0.1 ":alice!~u@yppdd5tt4admc.irc PRIVMSG #chan :tester, welcome!")
+ (0 ":bob!~u@yppdd5tt4admc.irc PRIVMSG #chan :tester, welcome!"))
+
+((mode 1 "MODE #chan")
+ (0 ":irc.foonet.org 324 tester #chan +nt")
+ (0 ":irc.foonet.org 329 tester #chan 1620205534")
+ (0.1 ":bob!~u@yppdd5tt4admc.irc PRIVMSG #chan :alice: Thou desirest me to stop in my tale against the hair.")
+ (0.1 ":alice!~u@yppdd5tt4admc.irc PRIVMSG #chan :bob: And dar'st not stand, nor look me in the face.")
+ (0.1 ":bob!~u@yppdd5tt4admc.irc PRIVMSG #chan :alice: It should not be, by the persuasion of his new feasting.")
+ (0.1 ":alice!~u@yppdd5tt4admc.irc PRIVMSG #chan :bob: It was not given me, nor I did not buy it.")
+ (0.1 ":bob!~u@yppdd5tt4admc.irc PRIVMSG #chan :alice: He that would vouch it in any place but here.")
+ (0.1 ":alice!~u@yppdd5tt4admc.irc PRIVMSG #chan :bob: In everything I wait upon his will.")
+ (0.1 ":bob!~u@yppdd5tt4admc.irc PRIVMSG #chan :alice: Thou counterfeit'st most lively."))
+
+((linger 8 LINGER))
diff --git a/test/lisp/erc/resources/base/reuse-buffers/server/barnet.eld b/test/lisp/erc/resources/base/reuse-buffers/server/barnet.eld
new file mode 100644
index 00000000000..cc7aff10076
--- /dev/null
+++ b/test/lisp/erc/resources/base/reuse-buffers/server/barnet.eld
@@ -0,0 +1,24 @@
+;; -*- mode: lisp-data; -*-
+((pass 1 "PASS :barnet:changeme"))
+((nick 1 "NICK tester"))
+((user 2 "USER user 0 * :tester")
+ (0 ":irc.barnet.org 001 tester :Welcome to the barnet IRC Network tester")
+ (0 ":irc.barnet.org 002 tester :Your host is irc.barnet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.barnet.org 003 tester :This server was created Sun, 25 Apr 2021 11:28:28 UTC")
+ (0 ":irc.barnet.org 004 tester irc.barnet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.barnet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.barnet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=barnet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.barnet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.barnet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (0 ":irc.barnet.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.barnet.org 254 tester 1 :channels formed")
+ (0 ":irc.barnet.org 255 tester :I have 3 clients and 0 servers")
+ (0 ":irc.barnet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0 ":irc.barnet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0 ":irc.barnet.org 422 tester :MOTD File is missing"))
+
+((mode-user 10.2 "MODE tester +i")
+ ;; No mode answer
+ (0 ":irc.znc.in 306 tester :You have been marked as being away")
+ (0 ":irc.barnet.org NOTICE tester :[11:29:00] This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect.")
+ (0 ":irc.barnet.org 305 tester :You are no longer marked as being away"))
diff --git a/test/lisp/erc/resources/base/reuse-buffers/server/foonet.eld b/test/lisp/erc/resources/base/reuse-buffers/server/foonet.eld
new file mode 100644
index 00000000000..3a846108466
--- /dev/null
+++ b/test/lisp/erc/resources/base/reuse-buffers/server/foonet.eld
@@ -0,0 +1,24 @@
+;; -*- mode: lisp-data; -*-
+((pass 1 "PASS :foonet:changeme"))
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
+ (0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.foonet.org 003 tester :This server was created Sun, 25 Apr 2021 11:28:28 UTC")
+ (0 ":irc.foonet.org 004 tester irc.foonet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.foonet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.foonet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.foonet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (0 ":irc.foonet.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.foonet.org 254 tester 1 :channels formed")
+ (0 ":irc.foonet.org 255 tester :I have 3 clients and 0 servers")
+ (0 ":irc.foonet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0 ":irc.foonet.org 422 tester :MOTD File is missing"))
+
+((mode-user 10.2 "MODE tester +i")
+ ;; No mode answer
+ (0 ":irc.znc.in 306 tester :You have been marked as being away")
+ (0 ":irc.foonet.org NOTICE tester :[11:29:00] This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect.")
+ (0 ":irc.foonet.org 305 tester :You are no longer marked as being away"))
diff --git a/test/lisp/erc/resources/base/upstream-reconnect/soju-barnet.eld b/test/lisp/erc/resources/base/upstream-reconnect/soju-barnet.eld
new file mode 100644
index 00000000000..b8fc45e57b5
--- /dev/null
+++ b/test/lisp/erc/resources/base/upstream-reconnect/soju-barnet.eld
@@ -0,0 +1,64 @@
+;; -*- mode: lisp-data; -*-
+((pass 6 "PASS :changeme"))
+((nick 1 "NICK tester"))
+((user 1 "USER tester@vanilla/barnet 0 * :tester")
+ (0.01 ":soju.im 001 tester :Welcome to soju, tester")
+ (0.01 ":soju.im 002 tester :Your host is soju.im")
+ (0.00 ":soju.im 004 tester soju.im soju aiwroO OovaimnqpsrtklbeI")
+ (0.53 ":soju.im 005 tester CHATHISTORY=1000 CASEMAPPING=ascii BOUNCER_NETID=2 AWAYLEN=390 CHANLIMIT=#:100 INVEX NETWORK=barnet NICKLEN=32 WHOX MODES BOT=B ELIST=U MAXLIST=beI:60 :are supported")
+ (0.01 ":soju.im 005 tester TOPICLEN=390 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 EXCEPTS EXTBAN=,m KICKLEN=390 TARGMAX=NAMES:1,LIST:1,KICK:,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 MAXTARGETS=4 MONITOR=100 CHANTYPES=# PREFIX=(qaohv)~&@%+ UTF8ONLY :are supported")
+ (0.22 ":soju.im 221 tester +Zi")
+ (0.00 ":soju.im 422 tester :Use /motd to read the message of the day"))
+
+((mode 5 "MODE tester +i")
+ (0.00 ":tester!tester@10.0.2.100 JOIN #chan")
+ (0.06 ":soju.im 353 tester = #chan :tester @mike joe")
+ (0.01 ":soju.im 366 tester #chan :End of /NAMES list")
+ (0.23 ":irc.barnet.org 221 tester +Zi"))
+
+((mode 5 "MODE #chan")
+ (0.00 ":soju.im 324 tester #chan +tn")
+ (0.01 ":soju.im 329 tester #chan 1652878846")
+ (0.01 ":joe!~u@6d9pasqcqwb2s.irc PRIVMSG #chan :mike: There is five in the first show.")
+ (0.00 ":mike!~u@6d9pasqcqwb2s.irc PRIVMSG #chan :joe: Sir, I was an inward of his. A shy fellow was the duke; and, I believe I know the cause of his withdrawing.")
+ (0.00 ":joe!~u@6d9pasqcqwb2s.irc PRIVMSG #chan :mike: Proud of employment, willingly I go.")
+ (0.09 ":mike!~u@6d9pasqcqwb2s.irc PRIVMSG #chan :joe: Dull not device by coldness and delay.")
+ (0.09 ":joe!~u@6d9pasqcqwb2s.irc PRIVMSG #chan :mike: Our states are forfeit: seek not to undo us.")
+ (0.06 ":mike!~u@6d9pasqcqwb2s.irc PRIVMSG #chan :joe: Come, you are too severe a moraler. As the time, the place, and the condition of this country stands, I could heartily wish this had not befallen, but since it is as it is, mend it for your own good.")
+ (0.06 ":joe!~u@6d9pasqcqwb2s.irc PRIVMSG #chan :mike: Who hath upon him still that natural stamp.")
+ (0.07 ":mike!~u@6d9pasqcqwb2s.irc PRIVMSG #chan :joe: Arraign her first; 'tis Goneril. I here take my oath before this honourable assembly, she kicked the poor king her father.")
+ (0.06 ":joe!~u@6d9pasqcqwb2s.irc PRIVMSG #chan :mike: Lady, I will commend you to mine own heart.")
+ (0.08 ":mike!~u@6d9pasqcqwb2s.irc PRIVMSG #chan :joe: Look, what I will not, that I cannot do.")
+ (0.08 ":joe!~u@6d9pasqcqwb2s.irc PRIVMSG #chan :mike: That he would wed me, or else die my lover.")
+ (0.08 ":mike!~u@6d9pasqcqwb2s.irc PRIVMSG #chan :joe: Come your way, sir. Bless you, good father friar.")
+ (0.08 ":joe!~u@6d9pasqcqwb2s.irc PRIVMSG #chan :mike: Under correction, sir, we know whereuntil it doth amount.")
+ (0.08 ":mike!~u@6d9pasqcqwb2s.irc PRIVMSG #chan :joe: For I am nothing if not critical.")
+ (0.06 ":joe!~u@6d9pasqcqwb2s.irc PRIVMSG #chan :mike: Once more I'll read the ode that I have writ.")
+ (0.06 ":mike!~u@6d9pasqcqwb2s.irc PRIVMSG #chan :joe: This is the foul fiend Flibbertigibbet: he begins at curfew, and walks till the first cock; he gives the web and the pin, squints the eye, and makes the harelip; mildews the white wheat, and hurts the poor creature of earth.")
+ (0.06 ":joe!~u@6d9pasqcqwb2s.irc PRIVMSG #chan :mike: Sir, I praise the Lord for you, and so may my parishioners; for their sons are well tutored by you, and their daughters profit very greatly under you: you are a good member of the commonwealth.")
+ (0.08 ":mike!~u@6d9pasqcqwb2s.irc PRIVMSG #chan :joe: If it please your honour, I know not well what they are; but precise villains they are, that I am sure of, and void of all profanation in the world that good Christians ought to have.")
+ ;; Unexpected disconnect
+ (0.03 ":BouncerServ!BouncerServ@BouncerServ NOTICE tester :disconnected from barnet: failed to handle messages: failed to read IRC command: read tcp [::1]:54990->[::1]:6668: read: software caused connection abort")
+ ;; Eventual reconnect
+ (0.79 ":BouncerServ!BouncerServ@BouncerServ NOTICE tester :connected to barnet")
+ ;; No MOTD or other numerics
+ (0.01 ":soju.im 005 tester AWAYLEN=390 BOT=B CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m INVEX KICKLEN=390 :are supported")
+ (0.01 ":soju.im 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=barnet NICKLEN=32 PREFIX=(qaohv)~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8ONLY WHOX :are supported")
+ (0.22 ":irc.barnet.org 221 tester +Zi")
+ (0.01 ":irc.barnet.org NOTICE tester :This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect.")
+ ;; Server-initialed join
+ (0.01 ":tester!tester@10.0.2.100 JOIN #chan"))
+
+((mode 5 "MODE #chan")
+ (0.22 ":soju.im 353 tester = #chan :@mike joe tester")
+ (0.00 ":soju.im 366 tester #chan :End of /NAMES list")
+ (0.00 ":soju.im 324 tester #chan +nt")
+ (0.00 ":soju.im 329 tester #chan 1652878846")
+ (0.00 ":mike!~u@6d9pasqcqwb2s.irc PRIVMSG #chan :tester, welcome!")
+ (0.00 ":joe!~u@6d9pasqcqwb2s.irc PRIVMSG #chan :tester, welcome!")
+ (0.06 ":soju.im 324 tester #chan +nt")
+ (0.00 ":soju.im 329 tester #chan 1652878846")
+ (0.62 ":joe!~u@6d9pasqcqwb2s.irc PRIVMSG #chan :mike: Thou art my brother; so we'll hold thee ever.")
+ (0.00 ":mike!~u@6d9pasqcqwb2s.irc PRIVMSG #chan :joe: Very well! go to! I cannot go to, man; nor 'tis not very well: by this hand, I say, it is very scurvy, and begin to find myself fobbed in it.")
+ (0.00 ":joe!~u@6d9pasqcqwb2s.irc PRIVMSG #chan :mike: The heir of Alen on, Katharine her name.")
+ (0.09 ":mike!~u@6d9pasqcqwb2s.irc PRIVMSG #chan :joe: Go to; farewell! put money enough in your purse."))
diff --git a/test/lisp/erc/resources/base/upstream-reconnect/soju-foonet.eld b/test/lisp/erc/resources/base/upstream-reconnect/soju-foonet.eld
new file mode 100644
index 00000000000..63dfcb184c8
--- /dev/null
+++ b/test/lisp/erc/resources/base/upstream-reconnect/soju-foonet.eld
@@ -0,0 +1,72 @@
+;; -*- mode: lisp-data; -*-
+((pass 5 "PASS :changeme"))
+((nick 1 "NICK tester"))
+((user 1 "USER tester@vanilla/foonet 0 * :tester")
+ (0.01 ":soju.im 001 tester :Welcome to soju, tester")
+ (0.02 ":soju.im 002 tester :Your host is soju.im")
+ (0.01 ":soju.im 004 tester soju.im soju aiwroO OovaimnqpsrtklbeI")
+ (0.00 ":soju.im 005 tester CHATHISTORY=1000 CASEMAPPING=ascii BOUNCER_NETID=1 CHANTYPES=# PREFIX=(qaohv)~&@%+ UTF8ONLY AWAYLEN=390 NICKLEN=32 WHOX CHANLIMIT=#:100 INVEX NETWORK=foonet MODES :are supported")
+ (0.00 ":soju.im 005 tester TOPICLEN=390 BOT=B ELIST=U MAXLIST=beI:60 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 TARGMAX=NAMES:1,LIST:1,KICK:,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 EXCEPTS EXTBAN=,m KICKLEN=390 MAXTARGETS=4 MONITOR=100 :are supported")
+ (0.00 ":soju.im 221 tester +Zi")
+ (0.00 ":soju.im 422 tester :Use /motd to read the message of the day"))
+
+((mode 5 "MODE tester +i")
+ (0.2 ":irc.foonet.org 221 tester +Zi")
+ (0.0 ":tester!tester@10.0.2.100 JOIN #chan")
+ (0.0 ":soju.im 353 tester = #chan :tester @alice bob")
+ (0.1 ":soju.im 366 tester #chan :End of /NAMES list")
+ (0.0 ":bob!~u@h35cf3bf7rbt4.irc PRIVMSG #chan :alice: Princely shall be thy usage every way.")
+ (0.1 ":alice!~u@h35cf3bf7rbt4.irc PRIVMSG #chan :bob: Tell me thy reason why thou wilt marry."))
+
+((mode 5 "MODE #chan")
+ (0.00 ":soju.im 324 tester #chan +nt")
+ (0.01 ":soju.im 329 tester #chan 1652878847")
+ (0.02 ":bob!~u@h35cf3bf7rbt4.irc PRIVMSG #chan :alice: There is no leprosy but what thou speak'st.")
+ (0.09 ":alice!~u@h35cf3bf7rbt4.irc PRIVMSG #chan :bob: For I upon this bank will rest my head.")
+ (0.01 ":bob!~u@h35cf3bf7rbt4.irc PRIVMSG #chan :alice: To ruffle in the commonwealth of Rome.")
+ (0.08 ":alice!~u@h35cf3bf7rbt4.irc PRIVMSG #chan :bob: For I can nowhere find him like a man.")
+ (0.09 ":bob!~u@h35cf3bf7rbt4.irc PRIVMSG #chan :alice: Ay, sir; but she will none, she gives you thanks.")
+ (0.05 ":alice!~u@h35cf3bf7rbt4.irc PRIVMSG #chan :bob: That man should be at woman's command, and yet no hurt done! Though honesty be no puritan, yet it will do no hurt; it will wear the surplice of humility over the black gown of a big heart. I am going, forsooth: the business is for Helen to come hither.")
+ (0.07 ":bob!~u@h35cf3bf7rbt4.irc PRIVMSG #chan :alice: Indeed, I should have asked you that before.")
+ (0.09 ":alice!~u@h35cf3bf7rbt4.irc PRIVMSG #chan :bob: Faith, we met, and found the quarrel was upon the seventh cause.")
+ (0.05 ":bob!~u@h35cf3bf7rbt4.irc PRIVMSG #chan :alice: And then, I hope, thou wilt be satisfied.")
+ (0.06 ":alice!~u@h35cf3bf7rbt4.irc PRIVMSG #chan :bob: Well, I will forget the condition of my estate, to rejoice in yours.")
+ (0.05 ":bob!~u@h35cf3bf7rbt4.irc PRIVMSG #chan :alice: Ah! sirrah, this unlook'd-for sport comes well.")
+ (0.01 ":alice!~u@h35cf3bf7rbt4.irc PRIVMSG #chan :bob: Mayst thou inherit too! Welcome to Paris.")
+ (0.04 ":bob!~u@h35cf3bf7rbt4.irc PRIVMSG #chan :alice: That I would choose, were I to choose anew.")
+ (0.08 ":alice!~u@h35cf3bf7rbt4.irc PRIVMSG #chan :bob: Good Tom Drum, lend me a handkercher: so, I thank thee. Wait on me home, I'll make sport with thee: let thy curtsies alone, they are scurvy ones.")
+ (0.06 ":bob!~u@h35cf3bf7rbt4.irc PRIVMSG #chan :alice: Excellent workman! Thou canst not paint a man so bad as is thyself.")
+ (0.07 ":alice!~u@h35cf3bf7rbt4.irc PRIVMSG #chan :bob: That every braggart shall be found an ass.")
+ (0.07 ":bob!~u@h35cf3bf7rbt4.irc PRIVMSG #chan :alice: This is but a custom in your tongue; you bear a graver purpose, I hope.")
+ (0.02 ":alice!~u@h35cf3bf7rbt4.irc PRIVMSG #chan :bob: Well, we will have such a prologue, and it shall be written in eight and six.")
+ (0.01 ":bob!~u@h35cf3bf7rbt4.irc PRIVMSG #chan :alice: Tell me thy reason why thou wilt marry.")
+ (0.06 ":alice!~u@h35cf3bf7rbt4.irc PRIVMSG #chan :bob: According to the measure of their states.")
+
+ ;; Unexpected disconnect
+ (0.07 ":BouncerServ!BouncerServ@BouncerServ NOTICE tester :disconnected from foonet: failed to handle messages: failed to read IRC command: read tcp [::1]:57224->[::1]:6667: read: software caused connection abort")
+ ;; Eventual reconnect
+ (1.02 ":BouncerServ!BouncerServ@BouncerServ NOTICE tester :connected to foonet")
+ ;; No MOTD or other numerics
+ (0.01 ":soju.im 005 tester AWAYLEN=390 BOT=B CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m INVEX KICKLEN=390 :are supported")
+ (0.02 ":soju.im 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8ONLY WHOX :are supported")
+ (0.02 ":irc.foonet.org 221 tester +Zi")
+ (0.23 ":irc.foonet.org NOTICE tester :This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect.")
+ ;; Server-initialed join
+ (0.02 ":tester!tester@10.0.2.100 JOIN #chan"))
+
+((mode 5 "MODE #chan")
+ (0.03 ":soju.im 353 tester = #chan :@alice bob tester")
+ (0.03 ":soju.im 366 tester #chan :End of /NAMES list")
+ (0.00 ":soju.im 324 tester #chan +nt")
+ (0.00 ":soju.im 329 tester #chan 1652878847")
+ (0.00 ":bob!~u@h35cf3bf7rbt4.irc PRIVMSG #chan :tester, welcome!")
+ (0.00 ":alice!~u@h35cf3bf7rbt4.irc PRIVMSG #chan :tester, welcome!")
+ (0.46 ":soju.im 324 tester #chan +nt")
+ (0.01 ":soju.im 329 tester #chan 1652878847")
+ (0.00 ":bob!~u@h35cf3bf7rbt4.irc PRIVMSG #chan :alice: Thou desirest me to stop in my tale against the hair.")
+ (0.07 ":alice!~u@h35cf3bf7rbt4.irc PRIVMSG #chan :bob: But my intents are fix'd and will not leave me.")
+ (0.09 ":bob!~u@h35cf3bf7rbt4.irc PRIVMSG #chan :alice: That last is true; the sweeter rest was mine.")
+ (0.09 ":alice!~u@h35cf3bf7rbt4.irc PRIVMSG #chan :bob: No matter whither, so you come not here.")
+ (0.09 ":bob!~u@h35cf3bf7rbt4.irc PRIVMSG #chan :alice: My lord, in heart; and let the health go round."))
+
+((linger 12 LINGER))
diff --git a/test/lisp/erc/resources/base/upstream-reconnect/znc-barnet.eld b/test/lisp/erc/resources/base/upstream-reconnect/znc-barnet.eld
new file mode 100644
index 00000000000..bf5c2b5a749
--- /dev/null
+++ b/test/lisp/erc/resources/base/upstream-reconnect/znc-barnet.eld
@@ -0,0 +1,93 @@
+;; -*- mode: lisp-data; -*-
+((pass 6 "PASS :changeme"))
+((nick 1 "NICK tester"))
+((user 1 "USER tester@vanilla/barnet 0 * :tester")
+ (0.00 ":irc.barnet.org 001 tester :Welcome to the barnet IRC Network tester")
+ (0.01 ":irc.barnet.org 002 tester :Your host is irc.barnet.org, running version ergo-v2.8.0")
+ (0.01 ":irc.barnet.org 003 tester :This server was created Thu, 19 May 2022 05:33:02 UTC")
+ (0.00 ":irc.barnet.org 004 tester irc.barnet.org ergo-v2.8.0 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0.00 ":irc.barnet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0.01 ":irc.barnet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=barnet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0.01 ":irc.barnet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0.00 ":irc.barnet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (0.00 ":irc.barnet.org 252 tester 0 :IRC Operators online")
+ (0.11 ":irc.barnet.org 254 tester 1 :channels formed")
+ (0.00 ":irc.barnet.org 255 tester :I have 3 clients and 0 servers")
+ (0.00 ":irc.barnet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0.00 ":irc.barnet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0.00 ":irc.barnet.org 422 tester :MOTD File is missing"))
+
+((mode 5 "MODE tester +i")
+ (0.0 ":tester!~u@fsr9fwzfeeybc.irc JOIN #chan")
+ (0.05 ":irc.barnet.org 353 tester = #chan :@joe mike tester")
+ (0.01 ":irc.barnet.org 366 tester #chan :End of /NAMES list.")
+ (0.0 ":***!znc@znc.in PRIVMSG #chan :Buffer Playback...")
+ (0.0 ":joe!~u@6t6jcije78we2.irc PRIVMSG #chan :[05:48:13] mike: But send the midwife presently to me.")
+ (0.01 ":mike!~u@6t6jcije78we2.irc PRIVMSG #chan :[05:48:18] joe: Alas! poor rogue, I think, i' faith, she loves me.")
+ (0.01 ":joe!~u@6t6jcije78we2.irc PRIVMSG #chan :[05:48:20] mike: They did not bless us with one happy word.")
+ (0.01 ":mike!~u@6t6jcije78we2.irc PRIVMSG #chan :[05:48:24] joe: And hear the sentence of your moved prince.")
+ (0.21 ":joe!~u@6t6jcije78we2.irc PRIVMSG #chan :[05:48:29] mike: Swear me to this, and I will ne'er say no.")
+ (0.01 ":mike!~u@6t6jcije78we2.irc PRIVMSG #chan :[05:48:32] joe: As they had seen me with these hangman's hands.")
+ (0.01 ":joe!~u@6t6jcije78we2.irc PRIVMSG #chan :[05:48:34] mike: Boyet, prepare: I will away to-night.")
+ (0.01 ":mike!~u@6t6jcije78we2.irc PRIVMSG #chan :[05:48:36] joe: For being a little bad: so may my husband.")
+ (0.04 ":***!znc@znc.in PRIVMSG #chan :Playback Complete.")
+ (0.0 ":irc.barnet.org 221 tester +Zi")
+ (2.55 ":joe!~u@6t6jcije78we2.irc PRIVMSG #chan :mike: And whirl along with thee about the globe."))
+
+((mode 5 "MODE #chan")
+ (0.00 ":irc.barnet.org 324 tester #chan +nt")
+ (0.00 ":irc.barnet.org 329 tester #chan 1652938384")
+ (0.06 ":mike!~u@6t6jcije78we2.irc PRIVMSG #chan :joe: Unless good-counsel may the cause remove.")
+ (0.00 ":joe!~u@6t6jcije78we2.irc PRIVMSG #chan :mike: Thyself domestic officers thine enemy.")
+ (0.01 ":mike!~u@6t6jcije78we2.irc PRIVMSG #chan :joe: Go after her: she's desperate; govern her.")
+ (0.30 ":joe!~u@6t6jcije78we2.irc PRIVMSG #chan :mike: Or else to heaven she heaves them for revenge.")
+ (0.01 ":mike!~u@6t6jcije78we2.irc PRIVMSG #chan :joe: Keep up your bright swords, for the dew will rust them.")
+ (0.04 ":*status!znc@znc.in PRIVMSG tester :Disconnected from IRC (Connection aborted). Reconnecting...")
+ (0.41 ":*status!znc@znc.in PRIVMSG tester :Disconnected from IRC. Reconnecting...")
+ (0.59 ":*status!znc@znc.in PRIVMSG tester :Connected!")
+ (0.02 ":irc.barnet.org 001 tester :Welcome to the barnet IRC Network tester")
+ (0.01 ":irc.barnet.org 002 tester :Your host is irc.barnet.org, running version ergo-v2.8.0")
+ (0.01 ":irc.barnet.org 003 tester :This server was created Thu, 19 May 2022 05:33:02 UTC")
+ (0.01 ":irc.barnet.org 004 tester irc.barnet.org ergo-v2.8.0 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0.01 ":irc.barnet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0.01 ":irc.barnet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=barnet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0.22 ":irc.barnet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0.00 ":irc.barnet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (0.01 ":irc.barnet.org 252 tester 0 :IRC Operators online")
+ (0.00 ":irc.barnet.org 253 tester 0 :unregistered connections")
+ (0.00 ":irc.barnet.org 254 tester 1 :channels formed")
+ (0.00 ":irc.barnet.org 255 tester :I have 3 clients and 0 servers")
+ (0.00 ":irc.barnet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0.17 ":irc.barnet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0.00 ":irc.barnet.org 422 tester :MOTD File is missing")
+ (0.01 ":irc.barnet.org 221 tester +Zi")
+ (0.00 ":irc.barnet.org NOTICE tester :This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect.")
+ (0.05 ":irc.barnet.org 352 tester * ~u fsr9fwzfeeybc.irc irc.barnet.org tester H :0 ZNC - https://znc.in")
+ (0.02 ":irc.barnet.org 315 tester tester!*@* :End of WHO list")
+ (0.08 ":tester!~u@fsr9fwzfeeybc.irc JOIN #chan"))
+
+((mode 5 "MODE #chan")
+ (0.05 ":irc.barnet.org 353 tester = #chan :mike tester @joe")
+ (0.01 ":irc.barnet.org 366 tester #chan :End of NAMES list")
+ (0.00 ":mike!~u@6t6jcije78we2.irc PRIVMSG #chan :tester, welcome!")
+ (0.00 ":joe!~u@6t6jcije78we2.irc PRIVMSG #chan :tester, welcome!")
+ (0.02 ":irc.barnet.org 324 tester #chan +nt")
+ (0.01 ":irc.barnet.org 329 tester #chan 1652938384")
+ (0.00 ":joe!~u@6t6jcije78we2.irc PRIVMSG #chan :mike: See, here he comes, and I must ply my theme.")
+ (0.00 ":mike!~u@6t6jcije78we2.irc PRIVMSG #chan :joe: Confine yourself but in a patient list.")
+ (0.00 ":joe!~u@6t6jcije78we2.irc PRIVMSG #chan :mike: And bide the penance of each three years' day.")
+ (0.00 ":mike!~u@6t6jcije78we2.irc PRIVMSG #chan :joe: Bid me farewell, and let me hear thee going.")
+ (0.00 ":joe!~u@6t6jcije78we2.irc PRIVMSG #chan :mike: Nor shall not, if I do as I intend.")
+ (0.00 ":mike!~u@6t6jcije78we2.irc PRIVMSG #chan :joe: Our corn's to reap, for yet our tithe's to sow.")
+ (0.00 ":joe!~u@6t6jcije78we2.irc PRIVMSG #chan :mike: And almost broke my heart with extreme laughter.")
+ (0.00 ":mike!~u@6t6jcije78we2.irc PRIVMSG #chan :joe: Of modern seeming do prefer against him.")
+ (0.00 ":joe!~u@6t6jcije78we2.irc PRIVMSG #chan :mike: Like humble-visag'd suitors, his high will.")
+ (0.00 ":mike!~u@6t6jcije78we2.irc PRIVMSG #chan :joe: But yet, poor Claudio! There's no remedy.")
+ (0.00 ":joe!~u@6t6jcije78we2.irc PRIVMSG #chan :mike: Let him make treble satisfaction.")
+ (0.00 ":mike!~u@6t6jcije78we2.irc PRIVMSG #chan :joe: He's that he is; I may not breathe my censure.")
+ (0.00 ":joe!~u@6t6jcije78we2.irc PRIVMSG #chan :mike: To check their folly, passion's solemn tears.")
+ (0.00 ":mike!~u@6t6jcije78we2.irc PRIVMSG #chan :joe: Villain, I have done thy mother.")
+ (0.00 ":joe!~u@6t6jcije78we2.irc PRIVMSG #chan :mike: Please you, therefore, draw nigh, and take your places.")
+ (0.00 ":mike!~u@6t6jcije78we2.irc PRIVMSG #chan :joe: You shall not be admitted to his sight.")
+ (0.00 ":joe!~u@6t6jcije78we2.irc PRIVMSG #chan :mike: Sir, you shall present before her the Nine Worthies. Sir Nathaniel, as concerning some entertainment of time, some show in the posterior of this day, to be rendered by our assistance, at the king's command, and this most gallant, illustrate, and learned gentleman, before the princess; I say, none so fit as to present the Nine Worthies.")
+ (0.00 ":mike!~u@6d9pasqcqwb2s.irc PRIVMSG #chan :joe: Go to; farewell! put money enough in your purse."))
diff --git a/test/lisp/erc/resources/base/upstream-reconnect/znc-foonet.eld b/test/lisp/erc/resources/base/upstream-reconnect/znc-foonet.eld
new file mode 100644
index 00000000000..39c2950aa09
--- /dev/null
+++ b/test/lisp/erc/resources/base/upstream-reconnect/znc-foonet.eld
@@ -0,0 +1,86 @@
+;; -*- mode: lisp-data; -*-
+((pass 6 "PASS :changeme"))
+((nick 1 "NICK tester"))
+((user 1 "USER tester@vanilla/foonet 0 * :tester")
+ (0.16 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
+ (0.00 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version ergo-v2.8.0")
+ (0.00 ":irc.foonet.org 003 tester :This server was created Thu, 19 May 2022 05:33:02 UTC")
+ (0.00 ":irc.foonet.org 004 tester irc.foonet.org ergo-v2.8.0 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0.00 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0.01 ":irc.foonet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0.01 ":irc.foonet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0.00 ":irc.foonet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (0.00 ":irc.foonet.org 252 tester 0 :IRC Operators online")
+ (0.00 ":irc.foonet.org 254 tester 1 :channels formed")
+ (0.00 ":irc.foonet.org 255 tester :I have 3 clients and 0 servers")
+ (0.00 ":irc.foonet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0.00 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0.00 ":irc.foonet.org 422 tester :MOTD File is missing"))
+
+((mode 6 "MODE tester +i")
+ (0.00 ":tester!~u@rmtvrz9zcwbdq.irc JOIN #chan")
+ (0.09 ":irc.foonet.org 353 tester = #chan :@alice bob tester")
+ (0.00 ":irc.foonet.org 366 tester #chan :End of /NAMES list.")
+ (0.00 ":***!znc@znc.in PRIVMSG #chan :Buffer Playback...")
+ (0.00 ":bob!~u@rmtvrz9zcwbdq.irc PRIVMSG #chan :[05:48:11] alice: And be aveng'd on cursed Tamora.")
+ (0.00 ":alice!~u@rmtvrz9zcwbdq.irc PRIVMSG #chan :[05:48:13] bob: The stronger part of it by her own letters, which make her story true, even to the point of her death: her death itself, which could not be her office to say is come, was faithfully confirmed by the rector of the place.")
+ (0.01 ":bob!~u@rmtvrz9zcwbdq.irc PRIVMSG #chan :[05:48:15] alice: The ape is dead, and I must conjure him.")
+ (0.00 ":alice!~u@rmtvrz9zcwbdq.irc PRIVMSG #chan :[05:48:17] bob: Not so; but I answer you right painted cloth, from whence you have studied your questions.")
+ (0.01 ":bob!~u@rmtvrz9zcwbdq.irc PRIVMSG #chan :[05:48:21] alice: The valiant Paris seeks you for his love.")
+ (0.00 ":alice!~u@rmtvrz9zcwbdq.irc PRIVMSG #chan :[05:48:26] bob: To prison with her; and away with him.")
+ (0.00 ":bob!~u@rmtvrz9zcwbdq.irc PRIVMSG #chan :[05:48:30] alice: Tell them there I have gold; look, so I have.")
+ (0.00 ":alice!~u@rmtvrz9zcwbdq.irc PRIVMSG #chan :[05:48:35] bob: Will even weigh, and both as light as tales.")
+ (0.00 ":***!znc@znc.in PRIVMSG #chan :Playback Complete.")
+ (0.00 ":irc.foonet.org 221 tester +Zi")
+ (0.08 ":bob!~u@rmtvrz9zcwbdq.irc PRIVMSG #chan :alice: By some vile forfeit of untimely death."))
+
+((mode 3.51 "MODE #chan")
+ (0.1 ":irc.foonet.org 324 tester #chan +nt")
+ (0.0 ":irc.foonet.org 329 tester #chan 1652938384")
+ (0.0 ":alice!~u@rmtvrz9zcwbdq.irc PRIVMSG #chan :bob: What does this knave here ? Get you gone, sirrah: the complaints I have heard of you I do not all believe: 'tis my slowness that I do not; for I know you lack not folly to commit them, and have ability enough to make such knaveries yours.")
+ (0.0 ":bob!~u@rmtvrz9zcwbdq.irc PRIVMSG #chan :alice: When sects and factions were newly born.")
+ (0.1 ":alice!~u@rmtvrz9zcwbdq.irc PRIVMSG #chan :bob: Fall, when Love please! marry, to each, but one.")
+ (0.1 ":bob!~u@rmtvrz9zcwbdq.irc PRIVMSG #chan :alice: For I ne'er saw true beauty till this night.")
+ (0.1 ":alice!~u@rmtvrz9zcwbdq.irc PRIVMSG #chan :bob: Or say, sweet love, what thou desir'st to eat.")
+ (0.1 ":bob!~u@rmtvrz9zcwbdq.irc PRIVMSG #chan :alice: Yes, and will nobly him remunerate.")
+ (0.1 ":*status!znc@znc.in PRIVMSG tester :Disconnected from IRC (Connection aborted). Reconnecting...")
+ (0.4 ":*status!znc@znc.in PRIVMSG tester :Disconnected from IRC. Reconnecting...")
+ (0.9 ":*status!znc@znc.in PRIVMSG tester :Connected!")
+ (0.0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
+ (0.0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version ergo-v2.8.0")
+ (0.0 ":irc.foonet.org 003 tester :This server was created Thu, 19 May 2022 05:33:02 UTC")
+ (0.0 ":irc.foonet.org 004 tester irc.foonet.org ergo-v2.8.0 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0.1 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0.0 ":irc.foonet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0.0 ":irc.foonet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0.0 ":irc.foonet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (0.0 ":irc.foonet.org 252 tester 0 :IRC Operators online")
+ (0.0 ":irc.foonet.org 253 tester 0 :unregistered connections")
+ (0.1 ":irc.foonet.org 254 tester 1 :channels formed")
+ (0.0 ":irc.foonet.org 255 tester :I have 3 clients and 0 servers")
+ (0.0 ":irc.foonet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0.0 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0.0 ":irc.foonet.org 422 tester :MOTD File is missing")
+ (0.0 ":irc.foonet.org 221 tester +Zi")
+ (0.0 ":irc.foonet.org NOTICE tester :This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect.")
+ (0.6 ":irc.foonet.org 352 tester * ~u rmtvrz9zcwbdq.irc irc.foonet.org tester H :0 ZNC - https://znc.in")
+ (0.0 ":irc.foonet.org 315 tester tester!*@* :End of WHO list")
+ (0.0 ":tester!~u@rmtvrz9zcwbdq.irc JOIN #chan"))
+
+((mode 6 "MODE #chan")
+ (0.0 ":irc.foonet.org 353 tester = #chan :@alice bob tester")
+ (0.0 ":irc.foonet.org 366 tester #chan :End of NAMES list")
+ (0.0 ":alice!~u@rmtvrz9zcwbdq.irc PRIVMSG #chan :tester, welcome!")
+ (0.0 ":bob!~u@rmtvrz9zcwbdq.irc PRIVMSG #chan :tester, welcome!")
+ (0.0 ":alice!~u@rmtvrz9zcwbdq.irc PRIVMSG #chan :bob: Being of no power to make his wishes good.")
+ (0.0 ":irc.foonet.org 324 tester #chan +nt")
+ (0.0 ":irc.foonet.org 329 tester #chan 1652938384")
+ (0.0 ":bob!~u@rmtvrz9zcwbdq.irc PRIVMSG #chan :alice: In everything I wait upon his will.")
+ (0.0 ":alice!~u@rmtvrz9zcwbdq.irc PRIVMSG #chan :bob: Make choice of which your highness will see first.")
+ (0.0 ":bob!~u@rmtvrz9zcwbdq.irc PRIVMSG #chan :alice: We waste our lights in vain, like lamps by day.")
+ (0.0 ":alice!~u@rmtvrz9zcwbdq.irc PRIVMSG #chan :bob: No, I know that; but it is fit I should commit offence to my inferiors.")
+ (0.1 ":bob!~u@rmtvrz9zcwbdq.irc PRIVMSG #chan :alice: By my head, here come the Capulets.")
+ (0.0 ":alice!~u@rmtvrz9zcwbdq.irc PRIVMSG #chan :bob: Well, I will forget the condition of my estate, to rejoice in yours.")
+ (0.0 ":bob!~u@h35cf3bf7rbt4.irc PRIVMSG #chan :alice: My lord, in heart; and let the health go round."))
+
+((linger 12 LINGER))
diff --git a/test/lisp/erc/resources/erc-d/erc-d-i.el b/test/lisp/erc/resources/erc-d/erc-d-i.el
new file mode 100644
index 00000000000..db113335a82
--- /dev/null
+++ b/test/lisp/erc/resources/erc-d/erc-d-i.el
@@ -0,0 +1,124 @@
+;;; erc-d-i.el --- IRC helpers for ERC test server -*- lexical-binding: t -*-
+
+;; Copyright (C) 2020-2022 Free Software Foundation, Inc.
+;;
+;; This file is part of GNU Emacs.
+;;
+;; This program is free software: you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation, either version 3 of the
+;; License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see
+;; <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'cl-lib)
+
+(cl-defstruct (erc-d-i-message (:conc-name erc-d-i-message.))
+ "Identical to `erc-response'.
+When member `compat' is nil, it means the raw message was decoded as
+UTF-8 text before parsing, which is nonstandard."
+ (unparsed "" :type string)
+ (sender "" :type string)
+ (command "" :type string)
+ (command-args nil :type (list-of string))
+ (contents "" :type string)
+ (tags nil :type (list-of (cons symbol string)))
+ (compat t :type boolean))
+
+(defconst erc-d-i--tag-escapes
+ '((";" . "\\:") (" " . "\\s") ("\\" . "\\\\") ("\r" . "\\r") ("\n" . "\\n")))
+
+;; These are not mirror inverses; unescaping may drop stranded or
+;; misplaced backslashes.
+
+(defconst erc-d-i--tag-escaped-regexp (rx (or ?\; ?\ ?\\ ?\r ?\n)))
+
+(defconst erc-d-i--tag-unescaped-regexp
+ (rx (or "\\:" "\\s" "\\\\" "\\r" "\\n"
+ (seq "\\" (or string-end (not (or ":" "s" "n" "r" "\\")))))))
+
+(defun erc-d-i--unescape-tag-value (str)
+ "Undo substitution of char placeholders in raw tag value STR."
+ (replace-regexp-in-string erc-d-i--tag-unescaped-regexp
+ (lambda (s)
+ (or (car (rassoc s erc-d-i--tag-escapes))
+ (substring s 1)))
+ str t t))
+
+(defun erc-d-i--escape-tag-value (str)
+ "Swap out banned chars in tag value STR with message representation."
+ (replace-regexp-in-string erc-d-i--tag-escaped-regexp
+ (lambda (s)
+ (cdr (assoc s erc-d-i--tag-escapes)))
+ str t t))
+
+(defconst erc-d-i--invalid-tag-regexp (rx (any "\0\7\r\n; ")))
+
+(defun erc-d-i--validate-tags (raw)
+ "Validate tags portion of some RAW incoming message.
+RAW must not have a leading \"@\" or a trailing space. The spec says
+validation shouldn't be performed on keys and that undecodeable values
+or ones with illegal (unescaped) chars may be dropped. This does not
+respect any of that. Its purpose is to catch bad input created by us."
+ (unless (> 4094 (string-bytes raw))
+ ;; 417 ERR_INPUTTOOLONG Input line was too long
+ (error "Message tags exceed 4094 bytes: %S" raw))
+ (let (tags
+ (tag-strings (split-string raw ";")))
+ (dolist (s tag-strings (nreverse tags))
+ (let* ((m (if (>= emacs-major-version 28)
+ (string-search "=" s)
+ (string-match-p "=" s)))
+ (key (if m (substring s 0 m) s))
+ (val (when-let* (m ; check first, like (m), but shadow
+ (v (substring s (1+ m)))
+ ((not (string-equal v ""))))
+ (when (string-match-p erc-d-i--invalid-tag-regexp v)
+ (error "Bad tag: %s" s))
+ (thread-first v
+ (decode-coding-string 'utf-8 t)
+ (erc-d-i--unescape-tag-value)))))
+ (when (string-empty-p key)
+ (error "Tag missing key: %S" s))
+ (setf (alist-get (intern key) tags) val)))))
+
+(defun erc-d-i--parse-message (s &optional decode)
+ "Parse string S into `erc-d-i-message' object.
+With DECODE, decode as UTF-8 text."
+ (when (string-suffix-p "\r\n" s)
+ (error "Unstripped message encountered"))
+ (when decode
+ (setq s (decode-coding-string s 'utf-8 t)))
+ (let ((mes (make-erc-d-i-message :unparsed s :compat (not decode)))
+ tokens)
+ (when-let* (((not (string-empty-p s)))
+ ((eq ?@ (aref s 0)))
+ (m (string-match " " s))
+ (u (substring s 1 m)))
+ (setf (erc-d-i-message.tags mes) (erc-d-i--validate-tags u)
+ s (substring s (1+ m))))
+ (if-let* ((m (string-match " :" s))
+ (other-toks (split-string (substring s 0 m) " " t))
+ (rest (substring s (+ 2 m))))
+ (setf (erc-d-i-message.contents mes) rest
+ tokens (nconc other-toks (list rest)))
+ (setq tokens (split-string s " " t " ")))
+ (when (and tokens (eq ?: (aref (car tokens) 0)))
+ (setf (erc-d-i-message.sender mes) (substring (pop tokens) 1)))
+ (setf (erc-d-i-message.command mes) (or (pop tokens) "")
+ (erc-d-i-message.command-args mes) tokens)
+ mes))
+
+(provide 'erc-d-i)
+;;; erc-d-i.el ends here
diff --git a/test/lisp/erc/resources/erc-d/erc-d-t.el b/test/lisp/erc/resources/erc-d/erc-d-t.el
new file mode 100644
index 00000000000..a1a7e7e88d5
--- /dev/null
+++ b/test/lisp/erc/resources/erc-d/erc-d-t.el
@@ -0,0 +1,170 @@
+;;; erc-d-t.el --- ERT helpers for ERC test server -*- lexical-binding: t -*-
+
+;; Copyright (C) 2020-2022 Free Software Foundation, Inc.
+;;
+;; This file is part of GNU Emacs.
+;;
+;; This program is free software: you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation, either version 3 of the
+;; License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see
+;; <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;; Code:
+(eval-and-compile
+ (let* ((d (file-name-directory (or (macroexp-file-name) buffer-file-name)))
+ (load-path (cons (directory-file-name d) load-path)))
+ (require 'erc-d-u)))
+
+(require 'ert)
+
+(defun erc-d-t-kill-related-buffers ()
+ "Kill all erc- or erc-d- related buffers."
+ (let (buflist)
+ (dolist (buf (buffer-list))
+ (with-current-buffer buf
+ (when (or erc-d-u--process-buffer
+ (derived-mode-p 'erc-mode))
+ (push buf buflist))))
+ (dolist (buf buflist)
+ (when (and (boundp 'erc-server-flood-timer)
+ (timerp erc-server-flood-timer))
+ (cancel-timer erc-server-flood-timer))
+ (when-let ((proc (get-buffer-process buf)))
+ (delete-process proc))
+ (when (buffer-live-p buf)
+ (kill-buffer buf))))
+ (while (when-let ((buf (pop erc-d-u--canned-buffers)))
+ (kill-buffer buf))))
+
+(defun erc-d-t-silence-around (orig &rest args)
+ "Run ORIG function with ARGS silently.
+Use this on `erc-handle-login' and `erc-server-connect'."
+ (let ((inhibit-message t))
+ (apply orig args)))
+
+(defvar erc-d-t-cleanup-sleep-secs 0.1)
+
+(defmacro erc-d-t-with-cleanup (bindings cleanup &rest body)
+ "Execute BODY and run CLEANUP form regardless of outcome.
+`let*'-bind BINDINGS and make them available in BODY and CLEANUP.
+After CLEANUP, destroy any values in BINDINGS that remain bound to
+buffers or processes. Sleep `erc-d-t-cleanup-sleep-secs' before
+returning."
+ (declare (indent 2))
+ `(let* ,bindings
+ (unwind-protect
+ (progn ,@body)
+ ,cleanup
+ (when noninteractive
+ (let (bufs procs)
+ (dolist (o (list ,@(mapcar (lambda (b) (or (car-safe b) b))
+ bindings)))
+ (when (bufferp o)
+ (push o bufs))
+ (when (processp o)
+ (push o procs)))
+ (dolist (proc procs)
+ (delete-process proc)
+ (when-let ((buf (process-buffer proc)))
+ (push buf bufs)))
+ (dolist (buf bufs)
+ (when-let ((proc (get-buffer-process buf)))
+ (delete-process proc))
+ (when (bufferp buf)
+ (ignore-errors (kill-buffer buf)))))
+ (sleep-for erc-d-t-cleanup-sleep-secs)))))
+
+(defmacro erc-d-t-wait-for (max-secs msg &rest body)
+ "Wait for BODY to become non-nil.
+Or signal error with MSG after MAX-SECS. When MAX-SECS is negative,
+signal if BODY is ever non-nil before MAX-SECS elapses. On success,
+return BODY's value.
+
+Note: this assumes BODY is waiting on a peer's output. It tends to
+artificially accelerate consumption of all process output, which may not
+be desirable."
+ (declare (indent 2))
+ (unless (or (stringp msg) (memq (car-safe msg) '(format concat)))
+ (push msg body)
+ (setq msg (prin1-to-string body)))
+ (let ((inverted (make-symbol "inverted"))
+ (time-out (make-symbol "time-out"))
+ (result (make-symbol "result")))
+ `(ert-info ((concat "Awaiting: " ,msg))
+ (let ((,time-out (abs ,max-secs))
+ (,inverted (< ,max-secs 0))
+ (,result ',result))
+ (with-timeout (,time-out (if ,inverted
+ (setq ,inverted nil)
+ (error "Failed awaiting: %s" ,msg)))
+ (while (not (setq ,result (progn ,@body)))
+ (when (and (accept-process-output nil 0.1) (not noninteractive))
+ (redisplay))))
+ (when ,inverted
+ (error "Failed awaiting: %s" ,msg))
+ ,result))))
+
+(defmacro erc-d-t-ensure-for (max-secs msg &rest body)
+ "Ensure BODY remains non-nil for MAX-SECS.
+On failure, emit MSG."
+ (declare (indent 2))
+ (unless (or (stringp msg) (memq (car-safe msg) '(format concat)))
+ (push msg body)
+ (setq msg (prin1-to-string body)))
+ `(erc-d-t-wait-for (- (abs ,max-secs)) ,msg (not (progn ,@body))))
+
+(defun erc-d-t-search-for (timeout text &optional from on-success)
+ "Wait for TEXT to appear in current buffer before TIMEOUT secs.
+With marker or number FROM, only consider the portion of the buffer from
+that point forward. If TEXT is a cons, interpret it as an RX regular
+expression. If ON-SUCCESS is a function, call it when TEXT is found."
+ (save-restriction
+ (widen)
+ (let* ((rxp (consp text))
+ (fun (if rxp #'search-forward-regexp #'search-forward))
+ (pat (if rxp (rx-to-string text) text))
+ res)
+ (erc-d-t-wait-for timeout (format "string: %s" text)
+ (goto-char (or from (point-min)))
+ (setq res (funcall fun pat nil t))
+ (if (and on-success res)
+ (funcall on-success)
+ res)))))
+
+(defun erc-d-t-absent-for (timeout text &optional from on-success)
+ "Assert TEXT doesn't appear in current buffer for TIMEOUT secs."
+ (erc-d-t-search-for (- (abs timeout)) text from on-success))
+
+(defun erc-d-t-make-expecter ()
+ "Return function to search for new output in buffer.
+Assume new text is only inserted at or after `erc-insert-marker'.
+
+The returned function works like `erc-d-t-search-for', but it never
+revisits previously covered territory, and the optional fourth argument,
+ON-SUCCESS, is nonexistent. To reset, specify a FROM argument."
+ (let (positions)
+ (lambda (timeout text &optional reset-from)
+ (let* ((pos (cdr (assq (current-buffer) positions)))
+ (cb (lambda ()
+ (unless pos
+ (push (cons (current-buffer) (setq pos (make-marker)))
+ positions))
+ (marker-position
+ (set-marker pos (min (point) (1- (point-max))))))))
+ (when reset-from
+ (set-marker pos reset-from))
+ (erc-d-t-search-for timeout text pos cb)))))
+
+(provide 'erc-d-t)
+;;; erc-d-t.el ends here
diff --git a/test/lisp/erc/resources/erc-d/erc-d-tests.el b/test/lisp/erc/resources/erc-d/erc-d-tests.el
new file mode 100644
index 00000000000..f64b5e8a74c
--- /dev/null
+++ b/test/lisp/erc/resources/erc-d/erc-d-tests.el
@@ -0,0 +1,1346 @@
+;;; erc-d-tests.el --- tests for erc-d -*- lexical-binding: t -*-
+
+;; Copyright (C) 2020-2022 Free Software Foundation, Inc.
+;;
+;; This file is part of GNU Emacs.
+;;
+;; This program is free software: you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation, either version 3 of the
+;; License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see
+;; <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;; Code:
+(require 'ert-x)
+(eval-and-compile
+ (let ((load-path (cons (expand-file-name ".." (ert-resource-directory))
+ load-path)))
+ (require 'erc-d)
+ (require 'erc-d-t)))
+
+(require 'erc)
+
+;; Temporary kludge to silence warning
+(put 'erc-parse-tags 'erc-v3-warned-p t)
+
+(ert-deftest erc-d-u--canned-load-dialog--basic ()
+ (should-not (get-buffer "basic.eld"))
+ (should-not erc-d-u--canned-buffers)
+ (let* ((exes (erc-d-u--canned-load-dialog 'basic))
+ (reap (lambda ()
+ (cl-loop with e = (erc-d-u--read-dialog exes)
+ for s = (erc-d-u--read-exchange e)
+ while s collect s))))
+ (should (get-buffer "basic.eld"))
+ (should (memq (get-buffer "basic.eld") erc-d-u--canned-buffers))
+ (should (equal (funcall reap) '((pass 10.0 "PASS " (? ?:) "changeme"))))
+ (should (equal (funcall reap) '((nick 0.2 "NICK tester"))))
+ (let ((r (funcall reap)))
+ (should (equal (car r) '(user 0.2 "USER user 0 * :tester")))
+ (should (equal
+ (car (last r))
+ '(0 ":irc.example.org 422 tester :MOTD File is missing"))))
+ (should (equal (car (funcall reap)) '(mode-user 5 "MODE tester +i")))
+ (should (equal (funcall reap)
+ '((mode-chan 1.2 "MODE #chan")
+ (0.1 ":bob!~bob@example.org PRIVMSG #chan :hey"))))
+ ;; See `define-error' site for `iter-end-of-sequence'
+ (ert-info ("EOB detected") (should-not (erc-d-u--read-dialog exes))))
+ (should-not (get-buffer "basic.eld"))
+ (should-not erc-d-u--canned-buffers))
+
+(defun erc-d-tests--make-hunk-reader (hunks)
+ (let ((p (erc-d-u--read-dialog hunks)))
+ (lambda () (erc-d-u--read-exchange p))))
+
+;; Fuzzies need to be able to access any non-exhausted genny.
+(ert-deftest erc-d-u--canned-load-dialog--intermingled ()
+ (should-not (get-buffer "basic.eld"))
+ (should-not erc-d-u--canned-buffers)
+ (let* ((exes (erc-d-u--canned-load-dialog 'basic))
+ (pass (erc-d-tests--make-hunk-reader exes))
+ (nick (erc-d-tests--make-hunk-reader exes))
+ (user (erc-d-tests--make-hunk-reader exes))
+ (modu (erc-d-tests--make-hunk-reader exes))
+ (modc (erc-d-tests--make-hunk-reader exes)))
+
+ (should (equal (funcall user) '(user 0.2 "USER user 0 * :tester")))
+ (should (equal (funcall modu) '(mode-user 5 "MODE tester +i")))
+ (should (equal (funcall modc) '(mode-chan 1.2 "MODE #chan")))
+
+ (cl-loop repeat 8 do (funcall user)) ; skip a few
+ (should (equal (funcall user)
+ '(0 ":irc.example.org 254 tester 1 :channels formed")))
+ (should (equal (funcall modu)
+ '(0 ":irc.example.org 221 tester +Zi")))
+ (should (equal (cl-loop for s = (funcall modc) while s collect s) ; done
+ '((0.1 ":bob!~bob@example.org PRIVMSG #chan :hey"))))
+
+ (cl-loop repeat 3 do (funcall user))
+ (cl-loop repeat 3 do (funcall modu))
+
+ (ert-info ("Change up the order")
+ (should
+ (equal (funcall modu)
+ '(0 ":irc.example.org 366 alice #chan :End of NAMES list")))
+ (should
+ (equal (funcall user)
+ '(0 ":irc.example.org 422 tester :MOTD File is missing"))))
+
+ ;; Exhaust these
+ (should (equal (cl-loop for s = (funcall pass) while s collect s) ; done
+ '((pass 10.0 "PASS " (? ?:) "changeme"))))
+ (should (equal (cl-loop for s = (funcall nick) while s collect s) ; done
+ '((nick 0.2 "NICK tester"))))
+
+ (ert-info ("End of file but no teardown because hunks outstanding")
+ (should-not (erc-d-u--read-dialog exes))
+ (should (get-buffer "basic.eld")))
+
+ ;; Finish
+ (should-not (funcall user))
+ (should-not (funcall modu)))
+
+ (should-not (get-buffer "basic.eld"))
+ (should-not erc-d-u--canned-buffers))
+
+;; This indirectly tests `erc-d-u--canned-read' cleanup/teardown
+
+(ert-deftest erc-d-u--rewrite-for-slow-mo ()
+ (should-not (get-buffer "basic.eld"))
+ (should-not (get-buffer "basic.eld<2>"))
+ (should-not (get-buffer "basic.eld<3>"))
+ (should-not erc-d-u--canned-buffers)
+ (let ((exes (erc-d-u--canned-load-dialog 'basic))
+ (exes-lower (erc-d-u--canned-load-dialog 'basic))
+ (exes-custom (erc-d-u--canned-load-dialog 'basic))
+ (reap (lambda (e) (cl-loop with p = (erc-d-u--read-dialog e)
+ for s = (erc-d-u--read-exchange p)
+ while s collect s))))
+ (should (get-buffer "basic.eld"))
+ (should (get-buffer "basic.eld<2>"))
+ (should (get-buffer "basic.eld<3>"))
+ (should (equal (list (get-buffer "basic.eld<3>")
+ (get-buffer "basic.eld<2>")
+ (get-buffer "basic.eld"))
+ erc-d-u--canned-buffers))
+
+ (ert-info ("Rewrite for slowmo basic")
+ (setq exes (erc-d-u--rewrite-for-slow-mo 10 exes))
+ (should (equal (funcall reap exes)
+ '((pass 20.0 "PASS " (? ?:) "changeme"))))
+ (should (equal (funcall reap exes)
+ '((nick 10.2 "NICK tester"))))
+ (let ((r (funcall reap exes)))
+ (should (equal (car r) '(user 10.2 "USER user 0 * :tester")))
+ (should (equal
+ (car (last r))
+ '(0 ":irc.example.org 422 tester :MOTD File is missing"))))
+ (should (equal (car (funcall reap exes))
+ '(mode-user 15 "MODE tester +i")))
+ (should (equal (car (funcall reap exes))
+ '(mode-chan 11.2 "MODE #chan")))
+ (should-not (erc-d-u--read-dialog exes)))
+
+ (ert-info ("Rewrite for slowmo bounded")
+ (setq exes-lower (erc-d-u--rewrite-for-slow-mo -5 exes-lower))
+ (should (equal (funcall reap exes-lower)
+ '((pass 10.0 "PASS " (? ?:) "changeme"))))
+ (should (equal (funcall reap exes-lower)
+ '((nick 5 "NICK tester"))))
+ (should (equal (car (funcall reap exes-lower))
+ '(user 5 "USER user 0 * :tester")))
+ (should (equal (car (funcall reap exes-lower))
+ '(mode-user 5 "MODE tester +i")))
+ (should (equal (car (funcall reap exes-lower))
+ '(mode-chan 5 "MODE #chan")))
+ (should-not (erc-d-u--read-dialog exes-lower)))
+
+ (ert-info ("Rewrite for slowmo custom")
+ (setq exes-custom (erc-d-u--rewrite-for-slow-mo
+ (lambda (n) (* 2 n)) exes-custom))
+ (should (equal (funcall reap exes-custom)
+ '((pass 20.0 "PASS " (? ?:) "changeme"))))
+ (should (equal (funcall reap exes-custom)
+ '((nick 0.4 "NICK tester"))))
+ (should (equal (car (funcall reap exes-custom))
+ '(user 0.4 "USER user 0 * :tester")))
+ (should (equal (car (funcall reap exes-custom))
+ '(mode-user 10 "MODE tester +i")))
+ (should (equal (car (funcall reap exes-custom))
+ '(mode-chan 2.4 "MODE #chan")))
+ (should-not (erc-d-u--read-dialog exes-custom))))
+
+ (should-not (get-buffer "basic.eld"))
+ (should-not (get-buffer "basic.eld<2>"))
+ (should-not (get-buffer "basic.eld<3>"))
+ (should-not erc-d-u--canned-buffers))
+
+(ert-deftest erc-d--active-ex-p ()
+ (let ((ring (make-ring 5)))
+ (ert-info ("Empty ring returns nil for not active")
+ (should-not (erc-d--active-ex-p ring)))
+ (ert-info ("One fuzzy member returns nil for not active")
+ (ring-insert ring (make-erc-d-exchange :tag '~foo))
+ (should-not (erc-d--active-ex-p ring)))
+ (ert-info ("One active member returns t for active")
+ (ring-insert-at-beginning ring (make-erc-d-exchange :tag 'bar))
+ (should (erc-d--active-ex-p ring)))))
+
+(defun erc-d-tests--parse-message-upstream (raw)
+ "Hack shim for parsing RAW line recvd from peer."
+ (cl-letf (((symbol-function #'erc-handle-parsed-server-response)
+ (lambda (_ p) p)))
+ (let ((erc-active-buffer nil))
+ (erc-parse-server-response nil raw))))
+
+(ert-deftest erc-d-i--validate-tags ()
+ (should (erc-d-i--validate-tags
+ (concat "batch=4cc99692bf24a4bec4aa03da437364f5;"
+ "time=2021-01-04T00:32:13.839Z")))
+ (should (erc-d-i--validate-tags "+foo=bar;baz=spam"))
+ (should (erc-d-i--validate-tags "foo=\\:ok;baz=\\s"))
+ (should (erc-d-i--validate-tags "foo=\303\247edilla"))
+ (should (erc-d-i--validate-tags "foo=\\"))
+ (should (erc-d-i--validate-tags "foo=bar\\baz"))
+ (should-error (erc-d-i--validate-tags "foo=\\\\;baz=\\\r\\\n"))
+ (should-error (erc-d-i--validate-tags "foo=\n"))
+ (should-error (erc-d-i--validate-tags "foo=\0ok"))
+ (should-error (erc-d-i--validate-tags "foo=bar baz"))
+ (should-error (erc-d-i--validate-tags "foo=bar\r"))
+ (should-error (erc-d-i--validate-tags "foo=bar;")))
+
+(ert-deftest erc-d-i--parse-message ()
+ (let* ((raw (concat "@time=2020-11-23T09:10:33.088Z "
+ ":tilde.chat BATCH +1 chathistory :#meta"))
+ (upstream (erc-d-tests--parse-message-upstream raw))
+ (ours (erc-d-i--parse-message raw)))
+
+ (ert-info ("Baseline upstream")
+ (should (equal (erc-response.unparsed upstream) raw))
+ (should (equal (erc-response.sender upstream) "tilde.chat"))
+ (should (equal (erc-response.command upstream) "BATCH"))
+ (should (equal (erc-response.command-args upstream)
+ '("+1" "chathistory" "#meta")))
+ (should (equal (erc-response.contents upstream) "#meta")))
+
+ (ert-info ("Ours my not compare cl-equalp but is otherwise the same")
+ (should (equal (erc-d-i-message.unparsed ours) raw))
+ (should (equal (erc-d-i-message.sender ours) "tilde.chat"))
+ (should (equal (erc-d-i-message.command ours) "BATCH"))
+ (should (equal (erc-d-i-message.command-args ours)
+ '("+1" "chathistory" "#meta")))
+ (should (equal (erc-d-i-message.contents ours) "#meta"))
+ (should (equal (erc-d-i-message.tags ours)
+ '((time . "2020-11-23T09:10:33.088Z")))))
+
+ (ert-info ("No compat decodes the whole message as utf-8")
+ (setq ours (erc-d-i--parse-message
+ "@foo=\303\247edilla TAGMSG #ch\303\240n"
+ 'decode))
+ (should-not (erc-d-i-message.compat ours))
+ (should (equal (erc-d-i-message.command-args ours) '("#chàn")))
+ (should (equal (erc-d-i-message.contents ours) ""))
+ (should (equal (erc-d-i-message.tags ours) '((foo . "çedilla")))))))
+
+(ert-deftest erc-d-i--unescape-tag-value ()
+ (should (equal (erc-d-i--unescape-tag-value
+ "\\sabc\\sdef\\s\\sxyz\\s")
+ " abc def xyz "))
+ (should (equal (erc-d-i--unescape-tag-value
+ "\\\\abc\\\\def\\\\\\\\xyz\\\\")
+ "\\abc\\def\\\\xyz\\"))
+ (should (equal (erc-d-i--unescape-tag-value "a\\bc") "abc"))
+ (should (equal (erc-d-i--unescape-tag-value
+ "\\\\abc\\\\def\\\\\\\\xyz\\")
+ "\\abc\\def\\\\xyz"))
+ (should (equal (erc-d-i--unescape-tag-value "a\\:b\\r\\nc\\sd")
+ "a;b\r\nc d")))
+
+(ert-deftest erc-d-i--escape-tag-value ()
+ (should (equal (erc-d-i--escape-tag-value " abc def xyz ")
+ "\\sabc\\sdef\\s\\sxyz\\s"))
+ (should (equal (erc-d-i--escape-tag-value "\\abc\\def\\\\xyz\\")
+ "\\\\abc\\\\def\\\\\\\\xyz\\\\"))
+ (should (equal (erc-d-i--escape-tag-value "a;b\r\nc d")
+ "a\\:b\\r\\nc\\sd")))
+
+;; TODO add tests for msg-join, mask-match, userhost-split,
+;; validate-hostname
+
+(ert-deftest erc-d-i--parse-message--irc-parser-tests ()
+ (let* ((data (with-temp-buffer
+ (insert-file-contents
+ (expand-file-name "irc-parser-tests.eld"
+ (ert-resource-directory)))
+ (read (current-buffer))))
+ (tests (assoc-default 'tests (assoc-default 'msg-split data)))
+ input atoms m ours)
+ (dolist (test tests)
+ (setq input (assoc-default 'input test)
+ atoms (assoc-default 'atoms test)
+ m (erc-d-i--parse-message input))
+ (ert-info ("Parses tags correctly")
+ (setq ours (erc-d-i-message.tags m))
+ (if-let ((tags (assoc-default 'tags atoms)))
+ (pcase-dolist (`(,key . ,value) ours)
+ (should (string= (cdr (assq key tags)) (or value ""))))
+ (should-not ours)))
+ (ert-info ("Parses verbs correctly")
+ (setq ours (erc-d-i-message.command m))
+ (if-let ((verbs (assoc-default 'verb atoms)))
+ (should (string= (downcase verbs) (downcase ours)))
+ (should (string-empty-p ours))))
+ (ert-info ("Parses sources correctly")
+ (setq ours (erc-d-i-message.sender m))
+ (if-let ((source (assoc-default 'source atoms)))
+ (should (string= source ours))
+ (should (string-empty-p ours))))
+ (ert-info ("Parses params correctly")
+ (setq ours (erc-d-i-message.command-args m))
+ (if-let ((params (assoc-default 'params atoms)))
+ (should (equal ours params))
+ (should-not ours))))))
+
+(defun erc-d-tests--new-ex (existing raw-hunk)
+ (let* ((f (lambda (_) (pop raw-hunk)))
+ (sd (make-erc-d-u-scan-d :f f)))
+ (setf (erc-d-exchange-hunk existing) (make-erc-d-u-scan-e :sd sd)
+ (erc-d-exchange-spec existing) (make-erc-d-spec)))
+ (erc-d--iter existing))
+
+(ert-deftest erc-d--render-entries ()
+ (let* ((erc-nick "foo")
+ (dialog (make-erc-d-dialog :vars `((:a . 1)
+ (c . ((a b) (: a space b)))
+ (d . (c alpha digit))
+ (bee . 2)
+ (f . ,(lambda () "3"))
+ (i . erc-nick))))
+ (exchange (make-erc-d-exchange :dialog dialog))
+ (mex (apply-partially #'erc-d-tests--new-ex exchange))
+ it)
+
+ (erc-d-exchange-reload dialog exchange)
+
+ (ert-info ("Baseline Outgoing")
+ (setq it (funcall mex '((0 "abc"))))
+ (should (equal (funcall it) 0))
+ (should (equal (funcall it) "abc")))
+
+ (ert-info ("Incoming are regexp escaped")
+ (setq it (funcall mex '((i 0.0 "fsf" ".org"))))
+ (should (equal (cons (funcall it) (funcall it)) '(i . 0.0)))
+ (should (equal (funcall it) "\\`fsf\\.org")))
+
+ (ert-info ("Incoming can access vars via rx-let")
+ (setq it (funcall mex '((i 0.0 bee))))
+ (should (equal (cons (funcall it) (funcall it)) '(i . 0.0)))
+ (should (equal (funcall it) "\\`\002")))
+
+ (ert-info ("Incoming rx-let params")
+ (setq it (funcall mex '((i 0.0 d))))
+ (should (equal (cons (funcall it) (funcall it)) '(i . 0.0)))
+ (should (equal (funcall it) "\\`[[:alpha:]][[:space:]][[:digit:]]")))
+
+ (ert-info ("Incoming literal rx forms")
+ (setq it (funcall mex '((i 0.0 (= 3 alpha) ".org"))))
+ (should (equal (cons (funcall it) (funcall it)) '(i . 0.0)))
+ (should (equal (funcall it) "\\`[[:alpha:]]\\{3\\}\\.org")))
+
+ (ert-info ("Self-quoting disallowed")
+ (setq it (funcall mex '((0 :a "abc"))))
+ (should (equal (funcall it) 0))
+ (should-error (funcall it)))
+
+ (ert-info ("Global vars and short vars")
+ (setq it (funcall mex '((0 i f erc-nick))))
+ (should (equal (funcall it) 0))
+ (should (equal (funcall it) "foo3foo")))
+
+ (ert-info ("Exits clean")
+ (when (listp (alist-get 'f (erc-d-dialog-vars dialog))) ; may be compiled
+ (should (eq 'closure (car (alist-get 'f (erc-d-dialog-vars dialog))))))
+ (should-not (funcall it))
+ (should (equal (erc-d-dialog-vars dialog)
+ `((:a . 1)
+ (c . ((a b) (: a space b)))
+ (d . (c alpha digit))
+ (bee . 2)
+ (f . ,(alist-get 'f (erc-d-dialog-vars dialog)))
+ (i . erc-nick)))))))
+
+(ert-deftest erc-d--render-entries--matches ()
+ (let* ((alist (list
+ (cons 'f (lambda (a) (funcall a :match 1)))
+ (cons 'g (lambda () (match-string 2 "foo bar baz")))
+ (cons 'h (lambda (a) (concat (funcall a :match 0)
+ (funcall a :request))))
+ (cons 'i (lambda (_ e) (erc-d-exchange-request e)))
+ (cons 'j (lambda ()
+ (set-match-data '(0 1))
+ (match-string 0 "j")))))
+ (dialog (make-erc-d-dialog :vars alist))
+ (exchange (make-erc-d-exchange :dialog dialog
+ :request "foo bar baz"
+ ;; 11 222
+ :match-data '(4 11 4 6 8 11)))
+ (mex (apply-partially #'erc-d-tests--new-ex exchange))
+ it)
+
+ (erc-d-exchange-reload dialog exchange)
+
+ (ert-info ("One arg, match")
+ (setq it (funcall mex '((0 f))))
+ (should (equal (funcall it) 0))
+ (should (equal (funcall it) "ba")))
+
+ (ert-info ("No args")
+ (setq it (funcall mex '((0 g))))
+ (should (equal (funcall it) 0))
+ (should (equal (funcall it) "baz")))
+
+ (ert-info ("Second arg is exchange object")
+ (setq it (funcall mex '((0 i))))
+ (should (equal (funcall it) 0))
+ (should (equal (funcall it) "foo bar baz")))
+
+ (ert-info ("One arg, multiple calls")
+ (setq it (funcall mex '((0 h))))
+ (should (equal (funcall it) 0))
+ (should (equal (funcall it) "bar bazfoo bar baz")))
+
+ (ert-info ("Match data restored")
+ (setq it (funcall mex '((0 j))))
+ (should (equal (funcall it) 0))
+ (should (equal (funcall it) "j"))
+
+ (setq it (funcall mex '((0 g))))
+ (should (equal (funcall it) 0))
+ (should (equal (funcall it) "baz")))
+
+ (ert-info ("Bad signature")
+ (let ((qlist (list 'f '(lambda (p q x) (ignore)))))
+ (setf (erc-d-dialog-vars dialog) qlist)
+ (should-error (erc-d-exchange-reload dialog exchange))))))
+
+(ert-deftest erc-d--render-entries--dynamic ()
+ (let* ((alist (list
+ (cons 'foo "foo")
+ (cons 'f (lambda (a) (funcall a :get-binding 'foo)))
+ (cons 'h (lambda (a) (upcase (funcall a :get-var 'foo))))
+ (cons 'g (lambda (a)
+ (funcall a :rebind 'g (funcall a :get-var 'f))
+ "bar"))
+ (cons 'j (lambda (a) (funcall a :set "123") "abc"))
+ (cons 'k (lambda () "abc"))))
+ (dialog (make-erc-d-dialog :vars alist))
+ (exchange (make-erc-d-exchange :dialog dialog))
+ (mex (apply-partially #'erc-d-tests--new-ex exchange))
+ it)
+
+ (erc-d-exchange-reload dialog exchange)
+
+ (ert-info ("Initial reference calls function")
+ (setq it (funcall mex '((0 j) (0 j))))
+ (should (equal (funcall it) 0))
+ (should (equal (funcall it) "abc")))
+
+ (ert-info ("Subsequent reference expands to string")
+ (should (equal (funcall it) 0))
+ (should (equal (funcall it) "123")))
+
+ (ert-info ("Outside manipulation: initial reference calls function")
+ (setq it (funcall mex '((0 k) (0 k))))
+ (should (equal (funcall it) 0))
+ (should (equal (funcall it) "abc")))
+
+ (ert-info ("Outside manipulation: subsequent reference expands to string")
+ (erc-d-exchange-rebind dialog exchange 'k "123")
+ (should (equal (funcall it) 0))
+ (should (equal (funcall it) "123")))
+
+ (ert-info ("Swap one function for another")
+ (setq it (funcall mex '((0 g) (0 g))))
+ (should (equal (funcall it) 0))
+ (should (equal (funcall it) "bar"))
+ (should (equal (funcall it) 0))
+ (should (equal (funcall it) "foo")))
+
+ (ert-info ("Bindings accessible inside functions")
+ (setq it (funcall mex '((0 f h))))
+ (should (equal (funcall it) 0))
+ (should (equal (funcall it) "fooFOO")))
+
+ (ert-info ("Rebuild alist by sending flag")
+ (setq it (funcall mex '((0 f) (1 f) (2 f) (i 3 f))))
+ (should (equal (funcall it) 0))
+ (should (equal (funcall it) "foo"))
+ (erc-d-exchange-rebind dialog exchange 'f "bar")
+ (should (equal (funcall it) 1))
+ (should (equal (funcall it) "bar"))
+ (setq alist (setf (alist-get 'f (erc-d-dialog-vars dialog))
+ (lambda nil "baz")))
+ (should (eq (funcall it) 2))
+ (should (equal (funcall it 'reload) "baz"))
+ (setq alist (setf (alist-get 'f (erc-d-dialog-vars dialog)) "spam"))
+ (should (eq (funcall it) 'i))
+ (should (eq (funcall it 'reload) 3))
+ (should (equal (funcall it) "\\`spam")))))
+
+(ert-deftest erc-d-t-with-cleanup ()
+ (should-not (get-buffer "*echo*"))
+ (should-not (get-buffer "*foo*"))
+ (should-not (get-buffer "*bar*"))
+ (should-not (get-buffer "*baz*"))
+ (erc-d-t-with-cleanup
+ ((echo (start-process "echo" (get-buffer-create "*echo*") "sleep" "1"))
+ (buffer-foo (get-buffer-create "*foo*"))
+ (buffer-bar (get-buffer-create "*bar*"))
+ (clean-up (list (intern (process-name echo)))) ; let*
+ buffer-baz)
+ (ert-info ("Clean Up")
+ (should (equal clean-up '(ran echo)))
+ (should (bufferp buffer-baz))
+ (should (bufferp buffer-foo))
+ (setq buffer-foo nil))
+ (setq buffer-baz (get-buffer-create "*baz*"))
+ (push 'ran clean-up))
+ (ert-info ("Buffers and procs destroyed")
+ (should-not (get-buffer "*echo*"))
+ (should-not (get-buffer "*bar*"))
+ (should-not (get-buffer "*baz*")))
+ (ert-info ("Buffer foo spared")
+ (should (get-buffer "*foo*"))
+ (kill-buffer "*foo*")))
+
+(ert-deftest erc-d-t-wait-for ()
+ :tags '(:unstable)
+ (let (v)
+ (run-at-time 0.2 nil (lambda () (setq v t)))
+ (should (erc-d-t-wait-for 0.4 "result becomes non-nil" v))
+ (should-error (erc-d-t-wait-for 0.4 "result stays nil" (not v)))
+ (setq v nil)
+ (should-not (erc-d-t-wait-for -0.4 "inverted stays nil" v))
+ (run-at-time 0.2 nil (lambda () (setq v t)))
+ (setq v nil)
+ (should-error (erc-d-t-wait-for -0.4 "inverted becomes non-nil" v))))
+
+(defvar erc-d-tests-with-server-password "changeme")
+
+;; Compromise between removing `autojoin' from `erc-modules' entirely
+;; and allowing side effects to meddle excessively
+(defvar erc-autojoin-channels-alist)
+
+;; This is only meant to be used by tests in this file.
+(cl-defmacro erc-d-tests-with-server ((dumb-server-var erc-server-buffer-var)
+ dialog &rest body)
+ "Create server for DIALOG and run BODY.
+DIALOG may also be a list of dialogs. ERC-SERVER-BUFFER-VAR and
+DUMB-SERVER-VAR are bound accordingly in BODY."
+ (declare (indent 2))
+ (when (eq '_ dumb-server-var)
+ (setq dumb-server-var (make-symbol "dumb-server-var")))
+ (when (eq '_ erc-server-buffer-var)
+ (setq erc-server-buffer-var (make-symbol "erc-server-buffer-var")))
+ (if (listp dialog)
+ (setq dialog (mapcar (lambda (f) (list 'quote f)) dialog))
+ (setq dialog `((quote ,dialog))))
+ `(let* (auth-source-do-cache
+ (,dumb-server-var (erc-d-run "localhost" t ,@dialog))
+ ,erc-server-buffer-var
+ ;;
+ (erc-server-flood-penalty 0.05)
+ erc-autojoin-channels-alist
+ erc-server-auto-reconnect)
+ (should-not erc-d--slow-mo)
+ (with-current-buffer "*erc-d-server*" (erc-d-t-search-for 4 "Starting"))
+ ;; Allow important messages through, even in -batch mode.
+ (advice-add #'erc-handle-login :around #'erc-d-t-silence-around)
+ (advice-add #'erc-server-connect :around #'erc-d-t-silence-around)
+ (unless (or noninteractive erc-debug-irc-protocol)
+ (erc-toggle-debug-irc-protocol))
+ (setq ,erc-server-buffer-var
+ (erc :server "localhost"
+ :password erc-d-tests-with-server-password
+ :port (process-contact ,dumb-server-var :service)
+ :nick "tester"
+ :full-name "tester"))
+ (unwind-protect
+ (progn
+ ,@body
+ (erc-d-t-wait-for 1 "dumb-server death"
+ (not (process-live-p ,dumb-server-var))))
+ (when (process-live-p erc-server-process)
+ (delete-process erc-server-process))
+ (advice-remove #'erc-handle-login #'erc-d-t-silence-around)
+ (advice-remove #'erc-server-connect #'erc-d-t-silence-around)
+ (when noninteractive
+ (kill-buffer ,erc-server-buffer-var)
+ (erc-d-t-kill-related-buffers)))))
+
+(defmacro erc-d-tests-with-failure-spy (found func-syms &rest body)
+ "Wrap functions with advice for inspecting errors caused by BODY.
+Do this for functions whose names appear in FUNC-SYMS. When running
+advice code, add errors to list FOUND. Note: the teardown finalizer is
+not added by default. Also, `erc-d-linger-secs' likely has to be
+nonzero for this to work."
+ (declare (indent 2))
+ ;; Catch errors thrown by timers that `should-error'ignores
+ `(progn
+ (let ((ad (lambda (f o &rest r)
+ (condition-case err
+ (apply o r)
+ (error (push err ,found)
+ (advice-remove f 'spy))))))
+ (dolist (sym ,func-syms)
+ (advice-add sym :around (apply-partially ad sym) '((name . spy)))))
+ (progn ,@body)
+ (dolist (sym ,func-syms)
+ (advice-remove sym 'spy))
+ (setq ,found (nreverse ,found))))
+
+(ert-deftest erc-d-run-nonstandard-messages ()
+ :tags '(:expensive-test)
+ (let* ((erc-d-linger-secs 0.2)
+ (dumb-server (erc-d-run "localhost" t 'nonstandard))
+ (dumb-server-buffer (get-buffer "*erc-d-server*"))
+ (expect (erc-d-t-make-expecter))
+ client)
+ (with-current-buffer "*erc-d-server*" (erc-d-t-search-for 4 "Starting"))
+ (setq client (open-network-stream "erc-d-client" nil
+ "localhost"
+ (process-contact dumb-server :service)
+ :coding 'binary))
+ (ert-info ("Server splits CRLF delimited lines")
+ (process-send-string client "ONE one\r\nTWO two\r\n")
+ (with-current-buffer dumb-server-buffer
+ (funcall expect 1 '(: "<- nonstandard:" (+ digit) " ONE one" eol))
+ (funcall expect 1 '(regex "<- nonstandard:[[:digit:]]+ TWO two$"))))
+ (ert-info ("Server doesn't discard empty lines")
+ (process-send-string client "\r\n")
+ (with-current-buffer dumb-server-buffer
+ (funcall expect 1 '(regex "<- nonstandard:[[:digit:]]+ $"))))
+ (ert-info ("Server preserves spaces")
+ (process-send-string client " \r\n")
+ (with-current-buffer dumb-server-buffer
+ (funcall expect 1 '(regex "<- nonstandard:[[:digit:]]+ \\{2\\}$")))
+ (process-send-string client " \r\n")
+ (with-current-buffer dumb-server-buffer
+ (funcall expect 1 '(regex "<- nonstandard:[[:digit:]]+ \\{3\\}$"))))
+ (erc-d-t-wait-for 3 "dumb-server death"
+ (not (process-live-p dumb-server)))
+ (delete-process client)
+ (when noninteractive
+ (kill-buffer dumb-server-buffer))))
+
+(ert-deftest erc-d-run-basic ()
+ :tags '(:expensive-test)
+ (erc-d-tests-with-server (_ _) basic
+ (with-current-buffer (erc-d-t-wait-for 3 (get-buffer "#chan"))
+ (erc-d-t-search-for 2 "hey"))
+ (when noninteractive
+ (kill-buffer "#chan"))))
+
+(ert-deftest erc-d-run-eof ()
+ :tags '(:expensive-test)
+ (skip-unless noninteractive)
+ (erc-d-tests-with-server (_ erc-s-buf) eof
+ (with-current-buffer (erc-d-t-wait-for 3 (get-buffer "#chan"))
+ (erc-d-t-search-for 2 "hey"))
+ (with-current-buffer erc-s-buf
+ (process-send-eof erc-server-process))))
+
+(ert-deftest erc-d-run-eof-fail ()
+ :tags '(:expensive-test)
+ (let (errors)
+ (erc-d-tests-with-failure-spy errors '(erc-d--teardown)
+ (erc-d-tests-with-server (_ _) eof
+ (with-current-buffer (erc-d-t-wait-for 5 (get-buffer "#chan"))
+ (erc-d-t-search-for 2 "hey"))
+ (erc-d-t-wait-for 10 errors)))
+ (should (string-match-p "Timed out awaiting request.*__EOF__"
+ (cadr (pop errors))))))
+
+(ert-deftest erc-d-run-linger ()
+ :tags '(:expensive-test)
+ (erc-d-tests-with-server (dumb-s _) linger
+ (with-current-buffer (erc-d-t-wait-for 6 (get-buffer "#chan"))
+ (erc-d-t-search-for 2 "hey"))
+ (with-current-buffer (process-buffer dumb-s)
+ (erc-d-t-search-for 2 "Lingering for 1.00 seconds"))
+ (with-current-buffer (process-buffer dumb-s)
+ (erc-d-t-search-for 3 "Lingered for 1.00 seconds"))))
+
+(ert-deftest erc-d-run-linger-fail ()
+ :tags '(:expensive-test)
+ (let ((erc-server-flood-penalty 0.1)
+ errors)
+ (erc-d-tests-with-failure-spy
+ errors '(erc-d--teardown erc-d-command)
+ (erc-d-tests-with-server (_ _) linger
+ (with-current-buffer (erc-d-t-wait-for 5 (get-buffer "#chan"))
+ (erc-d-t-search-for 2 "hey")
+ (erc-cmd-MSG "#chan hi"))
+ (erc-d-t-wait-for 10 "Bad match" errors)))
+ (should (string-match-p "Match failed.*hi" (cadr (pop errors))))))
+
+(ert-deftest erc-d-run-linger-direct ()
+ :tags '(:expensive-test)
+ (let* ((dumb-server (erc-d-run "localhost" t
+ 'linger-multi-a 'linger-multi-b))
+ (port (process-contact dumb-server :service))
+ (dumb-server-buffer (get-buffer "*erc-d-server*"))
+ (client-buffer-a (get-buffer-create "*erc-d-client-a*"))
+ (client-buffer-b (get-buffer-create "*erc-d-client-b*"))
+ (start (current-time))
+ client-a client-b)
+ (with-current-buffer "*erc-d-server*" (erc-d-t-search-for 4 "Starting"))
+ (setq client-a (open-network-stream "erc-d-client-a" client-buffer-a
+ "localhost" port
+ :coding 'binary)
+ client-b (open-network-stream "erc-d-client-b" client-buffer-b
+ "localhost" port
+ :coding 'binary))
+ (process-send-string client-a "PASS :a\r\n")
+ (sleep-for 0.01)
+ (process-send-string client-b "PASS :b\r\n")
+ (sleep-for 0.01)
+ (erc-d-t-wait-for 3 "dumb-server death"
+ (not (process-live-p dumb-server)))
+ (ert-info ("Ensure linger of one second")
+ (should (time-less-p 1 (time-subtract (current-time) start)))
+ (should (time-less-p (time-subtract (current-time) start) 1.5)))
+ (delete-process client-a)
+ (delete-process client-b)
+ (when noninteractive
+ (kill-buffer client-buffer-a)
+ (kill-buffer client-buffer-b)
+ (kill-buffer dumb-server-buffer))))
+
+(ert-deftest erc-d-run-drop-direct ()
+ :tags '(:unstable)
+ (let* ((dumb-server (erc-d-run "localhost" t 'drop-a 'drop-b))
+ (port (process-contact dumb-server :service))
+ (dumb-server-buffer (get-buffer "*erc-d-server*"))
+ (client-buffer-a (get-buffer-create "*erc-d-client-a*"))
+ (client-buffer-b (get-buffer-create "*erc-d-client-b*"))
+ (start (current-time))
+ client-a client-b)
+ (with-current-buffer "*erc-d-server*" (erc-d-t-search-for 4 "Starting"))
+ (setq client-a (open-network-stream "erc-d-client-a" client-buffer-a
+ "localhost" port
+ :coding 'binary)
+ client-b (open-network-stream "erc-d-client-b" client-buffer-b
+ "localhost" port
+ :coding 'binary))
+ (process-send-string client-a "PASS :a\r\n")
+ (sleep-for 0.01)
+ (process-send-string client-b "PASS :b\r\n")
+ (erc-d-t-wait-for 3 "client-a dies" (not (process-live-p client-a)))
+ (should (time-less-p (time-subtract (current-time) start) 0.32))
+ (erc-d-t-wait-for 3 "dumb-server death"
+ (not (process-live-p dumb-server)))
+ (ert-info ("Ensure linger of one second")
+ (should (time-less-p 1 (time-subtract (current-time) start))))
+ (delete-process client-a)
+ (delete-process client-b)
+ (when noninteractive
+ (kill-buffer client-buffer-a)
+ (kill-buffer client-buffer-b)
+ (kill-buffer dumb-server-buffer))))
+
+(ert-deftest erc-d-run-no-match ()
+ :tags '(:expensive-test)
+ (let ((erc-d-linger-secs 1)
+ erc-server-auto-reconnect
+ errors)
+ (erc-d-tests-with-failure-spy errors '(erc-d--teardown erc-d-command)
+ (erc-d-tests-with-server (_ erc-server-buffer) no-match
+ (with-current-buffer erc-server-buffer
+ (erc-d-t-search-for 2 "away")
+ (erc-cmd-JOIN "#foo")
+ (erc-d-t-wait-for 10 "Bad match" errors))))
+ (should (string-match-p "Match failed.*foo.*chan" (cadr (pop errors))))
+ (should-not (get-buffer "#foo"))))
+
+(ert-deftest erc-d-run-timeout ()
+ :tags '(:expensive-test)
+ (let ((erc-d-linger-secs 1)
+ err errors)
+ (erc-d-tests-with-failure-spy errors '(erc-d--teardown)
+ (erc-d-tests-with-server (_ _) timeout
+ (erc-d-t-wait-for 10 "error caught" errors)))
+ (setq err (pop errors))
+ (should (eq (car err) 'erc-d-timeout))
+ (should (string-match-p "Timed out" (cadr err)))))
+
+(ert-deftest erc-d-run-unexpected ()
+ :tags '(:expensive-test)
+ (let ((erc-d-linger-secs 2)
+ errors)
+ (erc-d-tests-with-failure-spy
+ errors '(erc-d--teardown erc-d-command)
+ (erc-d-tests-with-server (_ _) unexpected
+ (ert-info ("All specs consumed when more input arrives")
+ (erc-d-t-wait-for 10 "error caught" (cdr errors)))))
+ (should (string-match-p "unexpected.*MODE" (cadr (pop errors))))
+ ;; Nonsensical normally because func would have already exited when
+ ;; first error was thrown
+ (should (string-match-p "Match failed" (cadr (pop errors))))))
+
+(ert-deftest erc-d-run-unexpected-depleted ()
+ :tags '(:expensive-test)
+ (let ((erc-d-linger-secs 3)
+ errors)
+ (erc-d-tests-with-failure-spy errors '(erc-d--teardown erc-d-command)
+ (let* ((dumb-server-buffer (get-buffer-create "*erc-d-server*"))
+ (dumb-server (erc-d-run "localhost" t 'depleted))
+ (expect (erc-d-t-make-expecter))
+ (client-buf (get-buffer-create "*erc-d-client*"))
+ client-proc)
+ (with-current-buffer dumb-server-buffer
+ (erc-d-t-search-for 3 "Starting"))
+ (setq client-proc (make-network-process
+ :buffer client-buf
+ :name "erc-d-client"
+ :family 'ipv4
+ :noquery t
+ :coding 'binary
+ :service (process-contact dumb-server :service)
+ :host "localhost"))
+ (with-current-buffer dumb-server-buffer
+ (funcall expect 3 "open from"))
+ (process-send-string client-proc "PASS :changeme\r\n")
+ (sleep-for 0.01)
+ (process-send-string client-proc "NICK tester\r\n")
+ (sleep-for 0.01)
+ (process-send-string client-proc "USER user 0 * :tester\r\n")
+ (sleep-for 0.01)
+ (when (process-live-p client-proc)
+ (process-send-string client-proc "BLAH :too much\r\n")
+ (sleep-for 0.01))
+ (with-current-buffer client-buf
+ (funcall expect 3 "Welcome to the Internet"))
+ (erc-d-t-wait-for 2 "dumb-server death"
+ (not (process-live-p dumb-server)))
+ (delete-process client-proc)
+ (when noninteractive
+ (kill-buffer client-buf)
+ (kill-buffer dumb-server-buffer))))
+ (should (string-match-p "unexpected.*BLAH" (cadr (pop errors))))
+ ;; Wouldn't happen IRL
+ (should (string-match-p "unexpected.*BLAH" (cadr (pop errors))))
+ (should-not errors)))
+
+(defun erc-d-tests--dynamic-match-user (_dialog exchange)
+ "Shared pattern/response handler for canned dynamic DIALOG test."
+ (should (string= (match-string 1 (erc-d-exchange-request exchange))
+ "tester")))
+
+(defun erc-d-tests--run-dynamic ()
+ "Perform common assertions for \"dynamic\" dialog."
+ (erc-d-tests-with-server (dumb-server erc-server-buffer) dynamic
+ (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "#chan"))
+ (erc-d-t-search-for 2 "tester: hey"))
+ (with-current-buffer erc-server-buffer
+ (let ((expect (erc-d-t-make-expecter)))
+ (funcall expect 2 "host is irc.fsf.org")
+ (funcall expect 2 "modes for tester")))
+ (with-current-buffer (process-buffer dumb-server)
+ (erc-d-t-search-for 2 "irc.fsf.org"))
+ (when noninteractive
+ (kill-buffer "#chan"))))
+
+(ert-deftest erc-d-run-dynamic-default-match ()
+ :tags '(:expensive-test)
+ (let* (dynamic-tally
+ (erc-d-tmpl-vars '((user . "user")
+ (ignored . ((a b) (: a space b)))
+ (realname . (group (+ graph)))))
+ (nick (lambda (a)
+ (push '(nick . match-user) dynamic-tally)
+ (funcall a :set (funcall a :match 1) 'export)))
+ (dom (lambda (a)
+ (push '(dom . match-user) dynamic-tally)
+ (funcall a :set erc-d-server-fqdn)))
+ (erc-d-match-handlers
+ (list :user (lambda (d e)
+ (erc-d-exchange-rebind d e 'nick nick)
+ (erc-d-exchange-rebind d e 'dom dom)
+ (erc-d-tests--dynamic-match-user d e))
+ :mode-user (lambda (d e)
+ (erc-d-exchange-rebind d e 'nick "tester")
+ (erc-d-exchange-rebind d e 'dom dom))))
+ (erc-d-server-fqdn "irc.fsf.org"))
+ (erc-d-tests--run-dynamic)
+ (should (equal '((dom . match-user) (nick . match-user) (dom . match-user))
+ dynamic-tally))))
+
+(ert-deftest erc-d-run-dynamic-default-match-rebind ()
+ :tags '(:expensive-test)
+ (let* (tally
+ ;;
+ (erc-d-tmpl-vars '((user . "user")
+ (ignored . ((a b) (: a space b)))
+ (realname . (group (+ graph)))))
+ (erc-d-match-handlers
+ (list :user
+ (lambda (d e)
+ (erc-d-exchange-rebind
+ d e 'nick
+ (lambda (a)
+ (push 'bind-nick tally)
+ (funcall a :rebind 'nick (funcall a :match 1) 'export)))
+ (erc-d-exchange-rebind
+ d e 'dom
+ (lambda ()
+ (push 'bind-dom tally)
+ (erc-d-exchange-rebind d e 'dom erc-d-server-fqdn)))
+ (erc-d-tests--dynamic-match-user d e))
+ :mode-user
+ (lambda (d e)
+ (erc-d-exchange-rebind d e 'nick "tester")
+ (erc-d-exchange-rebind d e 'dom erc-d-server-fqdn))))
+ (erc-d-server-fqdn "irc.fsf.org"))
+ (erc-d-tests--run-dynamic)
+ (should (equal '(bind-nick bind-dom) tally))))
+
+(ert-deftest erc-d-run-dynamic-runtime-stub ()
+ :tags '(:expensive-test)
+ (let ((erc-d-tmpl-vars '((token . (group (or "barnet" "foonet")))))
+ (erc-d-match-handlers
+ (list :pass (lambda (d _e)
+ (erc-d-load-replacement-dialog d 'dynamic-foonet))))
+ (erc-d-tests-with-server-password "foonet:changeme"))
+ (erc-d-tests-with-server (_ erc-server-buffer)
+ (dynamic-stub dynamic-foonet)
+ (with-current-buffer (erc-d-t-wait-for 3 (get-buffer "#chan"))
+ (erc-d-t-search-for 2 "alice:")
+ (erc-d-t-absent-for 0.1 "joe"))
+ (with-current-buffer erc-server-buffer
+ (let ((expect (erc-d-t-make-expecter)))
+ (funcall expect 2 "host is irc.foonet.org")
+ (funcall expect 2 "NETWORK=FooNet")))
+ (when noninteractive
+ (kill-buffer "#chan")))))
+
+(ert-deftest erc-d-run-dynamic-runtime-stub-skip ()
+ :tags '(:expensive-test)
+ (let ((erc-d-tmpl-vars '((token . "barnet")))
+ (erc-d-match-handlers
+ (list :pass (lambda (d _e)
+ (erc-d-load-replacement-dialog
+ d 'dynamic-barnet 1))))
+ (erc-d-tests-with-server-password "barnet:changeme"))
+ (erc-d-tests-with-server (_ erc-server-buffer)
+ (dynamic-stub dynamic-barnet)
+ (with-current-buffer (erc-d-t-wait-for 3 (get-buffer "#chan"))
+ (erc-d-t-search-for 2 "joe:")
+ (erc-d-t-absent-for 0.1 "alice"))
+ (with-current-buffer erc-server-buffer
+ (let ((expect (erc-d-t-make-expecter)))
+ (funcall expect 2 "host is irc.barnet.org")
+ (funcall expect 2 "NETWORK=BarNet")))
+ (when noninteractive
+ (kill-buffer "#chan")))))
+
+;; Two servers, in-process, one client per
+(ert-deftest erc-d-run-dual-direct ()
+ :tags '(:expensive-test)
+ (let* ((erc-d--slow-mo -1)
+ (server-a (erc-d-run "localhost" t "erc-d-server-a" 'dynamic-foonet))
+ (server-b (erc-d-run "localhost" t "erc-d-server-b" 'dynamic-barnet))
+ (server-a-buffer (get-buffer "*erc-d-server-a*"))
+ (server-b-buffer (get-buffer "*erc-d-server-b*"))
+ (client-a-buffer (get-buffer-create "*erc-d-client-a*"))
+ (client-b-buffer (get-buffer-create "*erc-d-client-b*"))
+ client-a client-b)
+ (with-current-buffer server-a-buffer (erc-d-t-search-for 4 "Starting"))
+ (with-current-buffer server-b-buffer (erc-d-t-search-for 4 "Starting"))
+ (setq client-a (make-network-process
+ :buffer client-a-buffer
+ :name "erc-d-client-a"
+ :family 'ipv4
+ :noquery t
+ :coding 'binary
+ :service (process-contact server-a :service)
+ :host "localhost")
+ client-b (make-network-process
+ :buffer client-b-buffer
+ :name "erc-d-client-b"
+ :family 'ipv4
+ :noquery t
+ :coding 'binary
+ :service (process-contact server-b :service)
+ :host "localhost"))
+ ;; Also tests slo-mo indirectly because FAKE would fail without it
+ (process-send-string client-a "NICK tester\r\n")
+ (process-send-string client-b "FAKE noop\r\nNICK tester\r\n")
+ (sleep-for 0.01)
+ (process-send-string client-a "USER user 0 * :tester\r\n")
+ (process-send-string client-b "USER user 0 * :tester\r\n")
+ (sleep-for 0.01)
+ (process-send-string client-a "MODE tester +i\r\n")
+ (process-send-string client-b "MODE tester +i\r\n")
+ (sleep-for 0.01)
+ (process-send-string client-a "MODE #chan\r\n")
+ (process-send-string client-b "MODE #chan\r\n")
+ (sleep-for 0.01)
+ (erc-d-t-wait-for 2 "server-a death" (not (process-live-p server-a)))
+ (erc-d-t-wait-for 2 "server-b death" (not (process-live-p server-b)))
+ (when noninteractive
+ (kill-buffer client-a-buffer)
+ (kill-buffer client-b-buffer)
+ (kill-buffer server-a-buffer)
+ (kill-buffer server-b-buffer))))
+
+;; This can be removed; only exists to get a baseline for next test
+(ert-deftest erc-d-run-fuzzy-direct ()
+ :tags '(:expensive-test)
+ (let* ((erc-d-tmpl-vars
+ `((now . ,(lambda () (format-time-string "%FT%T.%3NZ" nil t)))))
+ (dumb-server (erc-d-run "localhost" t 'fuzzy))
+ (dumb-server-buffer (get-buffer "*erc-d-server*"))
+ (client-buffer (get-buffer-create "*erc-d-client*"))
+ client)
+ (with-current-buffer "*erc-d-server*" (erc-d-t-search-for 4 "Starting"))
+ (setq client (make-network-process
+ :buffer client-buffer
+ :name "erc-d-client"
+ :family 'ipv4
+ :noquery t
+ :coding 'binary
+ :service (process-contact dumb-server :service)
+ :host "localhost"))
+ ;; We could also just send this as a single fatty
+ (process-send-string client "PASS :changeme\r\n")
+ (sleep-for 0.01)
+ (process-send-string client "NICK tester\r\n")
+ (sleep-for 0.01)
+ (process-send-string client "USER user 0 * :tester\r\n")
+ (sleep-for 0.01)
+ (process-send-string client "MODE tester +i\r\n")
+ (sleep-for 0.01)
+ (process-send-string client "JOIN #bar\r\n")
+ (sleep-for 0.01)
+ (process-send-string client "JOIN #foo\r\n")
+ (sleep-for 0.01)
+ (process-send-string client "MODE #bar\r\n")
+ (sleep-for 0.01)
+ (process-send-string client "MODE #foo\r\n")
+ (sleep-for 0.01)
+ (erc-d-t-wait-for 1 "dumb-server death"
+ (not (process-live-p dumb-server)))
+ (when noninteractive
+ (kill-buffer client-buffer)
+ (kill-buffer dumb-server-buffer))))
+
+;; Without adjusting penalty, takes ~15 secs. With is comprable to direct ^.
+(ert-deftest erc-d-run-fuzzy ()
+ :tags '(:expensive-test)
+ (let ((erc-server-flood-penalty 1.2) ; penalty < margin/sends is basically 0
+ (erc-d-linger-secs 0.1)
+ (erc-d-tmpl-vars
+ `((now . ,(lambda () (format-time-string "%FT%T.%3NZ" nil t)))))
+ erc-server-auto-reconnect)
+ (erc-d-tests-with-server (_ erc-server-buffer) fuzzy
+ (with-current-buffer erc-server-buffer
+ (erc-d-t-search-for 2 "away")
+ (goto-char erc-input-marker)
+ (erc-cmd-JOIN "#bar"))
+ (erc-d-t-wait-for 2 (get-buffer "#bar"))
+ (with-current-buffer erc-server-buffer
+ (erc-cmd-JOIN "#foo"))
+ (erc-d-t-wait-for 20 (get-buffer "#foo"))
+ (with-current-buffer "#bar"
+ (erc-d-t-search-for 1 "was created on"))
+ (with-current-buffer "#foo"
+ (erc-d-t-search-for 5 "was created on")))))
+
+(ert-deftest erc-d-run-no-block ()
+ :tags '(:expensive-test)
+ (let ((erc-server-flood-penalty 1)
+ (erc-d-linger-secs 1.2)
+ (expect (erc-d-t-make-expecter))
+ erc-server-auto-reconnect)
+ (erc-d-tests-with-server (_ erc-server-buffer) no-block
+ (with-current-buffer erc-server-buffer
+ (funcall expect 2 "away")
+ (funcall expect 1 erc-prompt)
+ (with-current-buffer erc-server-buffer (erc-cmd-JOIN "#foo")))
+ (with-current-buffer (erc-d-t-wait-for 2 (get-buffer "#foo"))
+ (funcall expect 2 "was created on"))
+
+ (ert-info ("Join #bar")
+ (with-current-buffer erc-server-buffer (erc-cmd-JOIN "#bar"))
+ (erc-d-t-wait-for 2 (get-buffer "#bar")))
+
+ (with-current-buffer "#bar" (funcall expect 1 "was created on"))
+
+ (ert-info ("Server expects next pattern but keeps sending")
+ (with-current-buffer "#foo" (funcall expect 2 "Rosalind, I will "))
+ (with-current-buffer "#bar" (funcall expect 1 "hi 123"))
+ (with-current-buffer "#foo"
+ (should-not (search-forward "<bob> I am heard" nil t))
+ (funcall expect 1.5 "<bob> I am heard"))))))
+
+(defun erc-d-tests--run-proxy-direct (dumb-server dumb-server-buffer port)
+ "Start DUMB-SERVER with DUMB-SERVER-BUFFER and PORT.
+These are steps shared by in-proc and subproc variants testing a
+bouncer-like setup."
+ (when (version< emacs-version "28") (ert-skip "TODO connection refused"))
+ (let ((client-buffer-foo (get-buffer-create "*erc-d-client-foo*"))
+ (client-buffer-bar (get-buffer-create "*erc-d-client-bar*"))
+ (expect (erc-d-t-make-expecter))
+ client-foo
+ client-bar)
+ (setq client-foo (make-network-process
+ :buffer client-buffer-foo
+ :name "erc-d-client-foo"
+ :family 'ipv4
+ :noquery t
+ :coding 'binary
+ :service port
+ :host "localhost")
+ client-bar (make-network-process
+ :buffer client-buffer-bar
+ :name "erc-d-client-bar"
+ :family 'ipv4
+ :noquery t
+ :coding 'binary
+ :service port
+ :host "localhost"))
+ (with-current-buffer dumb-server-buffer
+ (funcall expect 3 "open from"))
+ (process-send-string client-foo "PASS :foo:changeme\r\n")
+ (process-send-string client-bar "PASS :bar:changeme\r\n")
+ (sleep-for 0.01)
+ (process-send-string client-foo "NICK tester\r\n")
+ (process-send-string client-bar "NICK tester\r\n")
+ (sleep-for 0.01)
+ (process-send-string client-foo "USER user 0 * :tester\r\n")
+ (process-send-string client-bar "USER user 0 * :tester\r\n")
+ (sleep-for 0.01)
+ (process-send-string client-foo "MODE tester +i\r\n")
+ (process-send-string client-bar "MODE tester +i\r\n")
+ (sleep-for 0.01)
+ (with-current-buffer client-buffer-foo
+ (funcall expect 3 "FooNet")
+ (funcall expect 3 "irc.foo.net")
+ (funcall expect 3 "marked as being away")
+ (goto-char (point-min))
+ (should-not (search-forward "bar" nil t)))
+ (with-current-buffer client-buffer-bar
+ (funcall expect 3 "BarNet")
+ (funcall expect 3 "irc.bar.net")
+ (funcall expect 3 "marked as being away")
+ (goto-char (point-min))
+ (should-not (search-forward "foo" nil t)))
+ (erc-d-t-wait-for 2 "dumb-server death"
+ (not (process-live-p dumb-server)))
+ (delete-process client-foo)
+ (delete-process client-bar)
+ (when noninteractive
+ (kill-buffer client-buffer-foo)
+ (kill-buffer client-buffer-bar)
+ (kill-buffer dumb-server-buffer))))
+
+;; This test shows the simplest way to set up template variables: put
+;; everything needed for the whole session in `erc-d-tmpl-vars' before
+;; starting the server.
+
+(ert-deftest erc-d-run-proxy-direct-spec-vars ()
+ :tags '(:expensive-test)
+ (let* ((dumb-server-buffer (get-buffer-create "*erc-d-server*"))
+ (erc-d-linger-secs 0.5)
+ (erc-d-tmpl-vars
+ `((network . (group (+ alpha)))
+ (fqdn . ,(lambda (a)
+ (let ((network (funcall a :match 1 'pass)))
+ (should (member network '("foo" "bar")))
+ (funcall a :set (concat "irc." network ".net")))))
+ (net . ,(lambda (a)
+ (let ((network (funcall a :match 1 'pass)))
+ (should (member network '("foo" "bar")))
+ (concat (capitalize network) "Net"))))))
+ (dumb-server (erc-d-run "localhost" t 'proxy-foonet 'proxy-barnet))
+ (port (process-contact dumb-server :service)))
+ (with-current-buffer dumb-server-buffer
+ (erc-d-t-search-for 3 "Starting"))
+ (erc-d-tests--run-proxy-direct dumb-server dumb-server-buffer port)))
+
+(cl-defun erc-d-tests--start-server (&key dialogs buffer linger program libs)
+ "Start and return a server in a subprocess using BUFFER and PORT.
+DIALOGS are symbols representing the base names of dialog files in
+`erc-d-u-canned-dialog-dir'. LIBS are extra files to load."
+ (push (locate-library "erc-d" nil (list erc-d-u--library-directory)) libs)
+ (cl-assert (car libs))
+ (let* ((args `("erc-d-server" ,buffer
+ ,(concat invocation-directory invocation-name)
+ "-Q" "-batch" "-L" ,erc-d-u--library-directory
+ ,@(let (o) (while libs (push (pop libs) o) (push "-l" o)) o)
+ "-eval" ,(format "%S" program) "-f" "erc-d-serve"
+ ,@(when linger (list "--linger" (number-to-string linger)))
+ ,@(mapcar #'erc-d-u--expand-dialog-symbol dialogs)))
+ (proc (apply #'start-process args)))
+ (set-process-query-on-exit-flag proc nil)
+ (with-current-buffer buffer
+ (erc-d-t-search-for 5 "Starting")
+ (search-forward " (")
+ (backward-char))
+ (let ((pair (read buffer)))
+ (cons proc (cdr pair)))))
+
+(ert-deftest erc-d-run-proxy-direct-subprocess ()
+ :tags '(:expensive-test)
+ (let* ((buffer (get-buffer-create "*erc-d-server*"))
+ ;; These are quoted because they're passed as printed forms to subproc
+ (fqdn '(lambda (a e)
+ (let* ((d (erc-d-exchange-dialog e))
+ (name (erc-d-dialog-name d)))
+ (funcall a :set (if (eq name 'proxy-foonet)
+ "irc.foo.net"
+ "irc.bar.net")))))
+ (net '(lambda (a)
+ (funcall a :rebind 'net
+ (if (eq (funcall a :dialog-name) 'proxy-foonet)
+ "FooNet"
+ "BarNet"))))
+ (program `(setq erc-d-tmpl-vars '((fqdn . ,fqdn)
+ (net . ,net)
+ (network . (group (+ alpha))))))
+ (port (erc-d-tests--start-server
+ :linger 0.3
+ :program program
+ :buffer buffer
+ :dialogs '(proxy-foonet proxy-barnet)))
+ (server (pop port)))
+ (erc-d-tests--run-proxy-direct server buffer port)))
+
+(ert-deftest erc-d-run-proxy-direct-subprocess-lib ()
+ :tags '(:expensive-test)
+ (let* ((buffer (get-buffer-create "*erc-d-server*"))
+ (lib (expand-file-name "proxy-subprocess.el"
+ (ert-resource-directory)))
+ (port (erc-d-tests--start-server :linger 0.3
+ :buffer buffer
+ :dialogs '(proxy-foonet proxy-barnet)
+ :libs (list lib)))
+ (server (pop port)))
+ (erc-d-tests--run-proxy-direct server buffer port)))
+
+(ert-deftest erc-d-run-no-pong ()
+ :tags '(:expensive-test)
+ (let* (erc-d-auto-pong
+ ;;
+ (erc-d-tmpl-vars
+ `((nonce . (group (: digit digit)))
+ (echo . ,(lambda (a)
+ (should (string= (funcall a :match 1) "42")) "42"))))
+ (dumb-server-buffer (get-buffer-create "*erc-d-server*"))
+ (dumb-server (erc-d-run "localhost" t 'no-pong))
+ (expect (erc-d-t-make-expecter))
+ (client-buf (get-buffer-create "*erc-d-client*"))
+ client-proc)
+ (with-current-buffer dumb-server-buffer
+ (erc-d-t-search-for 3 "Starting"))
+ (setq client-proc (make-network-process
+ :buffer client-buf
+ :name "erc-d-client"
+ :family 'ipv4
+ :noquery t
+ :coding 'binary
+ :service (process-contact dumb-server :service)
+ :host "localhost"))
+ (with-current-buffer dumb-server-buffer
+ (funcall expect 3 "open from"))
+ (process-send-string client-proc "PASS :changeme\r\nNICK tester\r\n")
+ (sleep-for 0.01)
+ (process-send-string client-proc "USER user 0 * :tester\r\n")
+ (sleep-for 0.01)
+ (process-send-string client-proc "MODE tester +i\r\n")
+ (sleep-for 0.01)
+ (with-current-buffer client-buf
+ (funcall expect 3 "ExampleOrg")
+ (funcall expect 3 "irc.example.org")
+ (funcall expect 3 "marked as being away"))
+ (ert-info ("PING is not intercepted by specialized method")
+ (process-send-string client-proc "PING 42\r\n")
+ (with-current-buffer client-buf
+ (funcall expect 3 "PONG")))
+ (erc-d-t-wait-for 2 "dumb-server death"
+ (not (process-live-p dumb-server)))
+ (delete-process client-proc)
+ (when noninteractive
+ (kill-buffer client-buf)
+ (kill-buffer dumb-server-buffer))))
+
+;; Inspect replies as they arrive within a single exchange, i.e., ensure we
+;; don't regress to prior buggy version in which inspection wasn't possible
+;; until all replies had been sent by the server.
+(ert-deftest erc-d-run-incremental ()
+ :tags '(:expensive-test)
+ (let ((erc-server-flood-penalty 0)
+ (expect (erc-d-t-make-expecter))
+ erc-d-linger-secs)
+ (erc-d-tests-with-server (_ erc-server-buffer) incremental
+ (with-current-buffer erc-server-buffer
+ (funcall expect 3 "marked as being away"))
+ (with-current-buffer erc-server-buffer
+ (erc-cmd-JOIN "#foo"))
+ (with-current-buffer (erc-d-t-wait-for 1 (get-buffer "#foo"))
+ (funcall expect 1 "Users on #foo")
+ (funcall expect 1 "Look for me")
+ (not (search-forward "Done" nil t))
+ (funcall expect 10 "Done")
+ (erc-send-message "Hi")))))
+
+(ert-deftest erc-d-unix-socket-direct ()
+ :tags '(:expensive-test)
+ (skip-unless (featurep 'make-network-process '(:family local)))
+ (let* ((erc-d-linger-secs 0.1)
+ (sock (expand-file-name "erc-d.sock" temporary-file-directory))
+ (dumb-server (erc-d-run nil sock 'basic))
+ (dumb-server-buffer (get-buffer "*erc-d-server*"))
+ (client-buffer (get-buffer-create "*erc-d-client*"))
+ client)
+ (with-current-buffer "*erc-d-server*"
+ (erc-d-t-search-for 4 "Starting"))
+ (unwind-protect
+ (progn
+ (setq client (make-network-process
+ :buffer client-buffer
+ :name "erc-d-client"
+ :family 'local
+ :noquery t
+ :coding 'binary
+ :service sock))
+ (process-send-string client "PASS :changeme\r\n")
+ (sleep-for 0.01)
+ (process-send-string client "NICK tester\r\n")
+ (sleep-for 0.01)
+ (process-send-string client "USER user 0 * :tester\r\n")
+ (sleep-for 0.1)
+ (process-send-string client "MODE tester +i\r\n")
+ (sleep-for 0.01)
+ (process-send-string client "MODE #chan\r\n")
+ (sleep-for 0.01)
+ (erc-d-t-wait-for 1 "dumb-server death"
+ (not (process-live-p dumb-server)))
+ (when noninteractive
+ (kill-buffer client-buffer)
+ (kill-buffer dumb-server-buffer)))
+ (delete-file sock))))
+
+;;; erc-d-tests.el ends here
diff --git a/test/lisp/erc/resources/erc-d/erc-d-u.el b/test/lisp/erc/resources/erc-d/erc-d-u.el
new file mode 100644
index 00000000000..ce13efef624
--- /dev/null
+++ b/test/lisp/erc/resources/erc-d/erc-d-u.el
@@ -0,0 +1,213 @@
+;;; erc-d-u.el --- Helpers for ERC test server -*- lexical-binding: t -*-
+
+;; Copyright (C) 2020-2022 Free Software Foundation, Inc.
+;;
+;; This file is part of GNU Emacs.
+;;
+;; This program is free software: you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation, either version 3 of the
+;; License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see
+;; <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; The utilities here are kept separate from those in `erc-d' so that
+;; tests running the server in a subprocess can use them without
+;; having to require the main lib. If migrating outside of test/lisp,
+;; there may be no reason to continue this.
+;;
+;; Another (perhaps misguided) goal here is to avoid having ERC itself
+;; as a dependency.
+;;
+;; FIXME this ^ is no longer the case (ERC is not a dependency)
+
+;;; Code:
+(require 'rx)
+(require 'subr-x)
+(eval-when-compile (require 'ert))
+
+(defvar erc-d-u--canned-buffers nil
+ "List of canned dialog buffers currently open for reading.")
+
+(cl-defstruct (erc-d-u-scan-d) ; dialog scanner
+ (buf nil :type buffer)
+ (done nil :type boolean)
+ (last nil :type integer)
+ (hunks nil :type (list-of marker))
+ (f #'erc-d-u--read-exchange-default :type function))
+
+(cl-defstruct (erc-d-u-scan-e) ; exchange scanner
+ (sd nil :type erc-d-u-scan-d)
+ (pos nil :type marker))
+
+(defun erc-d-u--read-dialog (info)
+ "Read dialog file and stash relevant state in `erc-d-u-scan-d' INFO."
+ (if (and (buffer-live-p (erc-d-u-scan-d-buf info))
+ (with-current-buffer (erc-d-u-scan-d-buf info)
+ (condition-case _err
+ (progn
+ (when (erc-d-u-scan-d-last info)
+ (goto-char (erc-d-u-scan-d-last info))
+ (forward-list))
+ (setf (erc-d-u-scan-d-last info) (point))
+ (down-list)
+ (push (set-marker (make-marker) (point))
+ (erc-d-u-scan-d-hunks info)))
+ ((end-of-buffer scan-error)
+ (setf (erc-d-u-scan-d-done info) t)
+ nil))))
+ (make-erc-d-u-scan-e :sd info :pos (car (erc-d-u-scan-d-hunks info)))
+ (unless (erc-d-u-scan-d-hunks info)
+ (kill-buffer (erc-d-u-scan-d-buf info))
+ nil)))
+
+(defun erc-d-u--read-exchange-default (info)
+ "Read from marker in exchange `erc-d-u-scan-e' object INFO."
+ (let ((hunks (erc-d-u-scan-e-sd info))
+ (pos (erc-d-u-scan-e-pos info)))
+ (or (and (erc-d-u-scan-d-hunks hunks)
+ (with-current-buffer (erc-d-u-scan-d-buf hunks)
+ (goto-char pos)
+ (condition-case _err
+ (read pos)
+ ;; Raised unless malformed
+ (invalid-read-syntax
+ nil))))
+ (unless (or (cl-callf (lambda (s) (delq pos s)) ; flip
+ (erc-d-u-scan-d-hunks hunks))
+ (not (erc-d-u-scan-d-done hunks)))
+ (kill-buffer (erc-d-u-scan-d-buf hunks))
+ nil))))
+
+(defun erc-d-u--read-exchange (info)
+ "Call exchange reader assigned in `erc-d-u-scan-e' object INFO."
+ (funcall (erc-d-u-scan-d-f (erc-d-u-scan-e-sd info)) info))
+
+(defun erc-d-u--canned-read (file)
+ "Dispense a reader for each exchange in dialog FILE."
+ (let ((buf (generate-new-buffer (file-name-nondirectory file))))
+ (push buf erc-d-u--canned-buffers)
+ (with-current-buffer buf
+ (setq-local parse-sexp-ignore-comments t
+ coding-system-for-read 'utf-8)
+ (add-hook 'kill-buffer-hook
+ (lambda () (setq erc-d-u--canned-buffers
+ (delq buf erc-d-u--canned-buffers)))
+ nil 'local)
+ (insert-file-contents-literally file)
+ (lisp-data-mode))
+ (make-erc-d-u-scan-d :buf buf)))
+
+(defvar erc-d-u--library-directory (file-name-directory load-file-name))
+(defvar erc-d-u-canned-dialog-dir
+ (file-name-as-directory (expand-file-name "resources"
+ erc-d-u--library-directory)))
+
+(defun erc-d-u--normalize-canned-name (dialog)
+ "Return DIALOG name as a symbol without validating it."
+ (if (symbolp dialog)
+ dialog
+ (intern (file-name-base dialog))))
+
+(defvar erc-d-u-canned-file-name-extension ".eld")
+
+(defun erc-d-u--expand-dialog-symbol (dialog)
+ "Return filename based on symbol DIALOG."
+ (let ((name (symbol-name dialog)))
+ (unless (equal (file-name-extension name)
+ erc-d-u-canned-file-name-extension)
+ (setq name (concat name erc-d-u-canned-file-name-extension)))
+ (expand-file-name name erc-d-u-canned-dialog-dir)))
+
+(defun erc-d-u--massage-canned-name (dialog)
+ "Return DIALOG in a form acceptable to `erc-d-run'."
+ (if (or (symbolp dialog) (file-exists-p dialog))
+ dialog
+ (erc-d-u--expand-dialog-symbol (intern dialog))))
+
+(defun erc-d-u--canned-load-dialog (dialog)
+ "Load dispensing exchanges from DIALOG.
+If DIALOG is a string, consider it a filename. Otherwise find a file
+in `erc-d-u-canned-dialog-dir' with a base name matching the symbol's
+name.
+
+Return an iterator that yields exchanges, each one an iterator of spec
+forms. The first is a so-called request spec and the rest are composed
+of zero or more response specs."
+ (when (symbolp dialog)
+ (setq dialog (erc-d-u--expand-dialog-symbol dialog)))
+ (unless (file-exists-p dialog)
+ (error "File not found: %s" dialog))
+ (erc-d-u--canned-read dialog))
+
+(defun erc-d-u--read-exchange-slowly (num orig info)
+ (when-let ((spec (funcall orig info)))
+ (when (symbolp (car spec))
+ (setf spec (copy-sequence spec)
+ (nth 1 spec) (cond ((functionp num) (funcall num (nth 1 spec)))
+ ((< num 0) (max (nth 1 spec) (- num)))
+ (t (+ (nth 1 spec) num)))))
+ spec))
+
+(defun erc-d-u--rewrite-for-slow-mo (num read-info)
+ "Return READ-INFO with a modified reader.
+When NUM is a positive number, delay incoming requests by NUM more
+seconds. If NUM is negative, raise insufficient incoming delays to at
+least -NUM seconds. If NUM is a function, set each delay to whatever it
+returns when called with the existing value."
+ (let ((orig (erc-d-u-scan-d-f read-info)))
+ (setf (erc-d-u-scan-d-f read-info)
+ (apply-partially #'erc-d-u--read-exchange-slowly num orig))
+ read-info))
+
+(defun erc-d-u--get-remote-port (process)
+ "Return peer TCP port for client PROCESS.
+When absent, just generate an id."
+ (let ((remote (plist-get (process-contact process t) :remote)))
+ (if (vectorp remote)
+ (aref remote (1- (length remote)))
+ (format "%s:%d" (process-contact process :local)
+ (logand 1023 (time-convert nil 'integer))))))
+
+(defun erc-d-u--format-bind-address (process)
+ "Return string or (STRING . INT) for bind address of network PROCESS."
+ (let ((local (process-contact process :local)))
+ (if (vectorp local) ; inet
+ (cons (mapconcat #'number-to-string (seq-subseq local 0 -1) ".")
+ (aref local (1- (length local))))
+ local)))
+
+(defun erc-d-u--unkeyword (plist)
+ "Return a copy of PLIST with keywords keys converted to non-keywords."
+ (cl-loop for (key value) on plist by #'cddr
+ when (keywordp key)
+ do (setq key (intern (substring (symbol-name key) 1)))
+ append (list key value)))
+
+(defun erc-d-u--massage-rx-args (key val)
+ " Massage val so it's suitable for an `rx-let' binding.
+Handle cases in which VAL is ([ARGLIST] RX-FORM) rather than just
+RX-FORM. KEY becomes the binding name."
+ (if (and (listp val)
+ (cdr val)
+ (not (cddr val))
+ (consp (car val)))
+ (cons key val)
+ (list key val)))
+
+(defvar-local erc-d-u--process-buffer nil
+ "Beacon for erc-d process buffers.
+The server process is usually deleted first, but we may want to examine
+the buffer afterward.")
+
+(provide 'erc-d-u)
+;;; erc-d-u.el ends here
diff --git a/test/lisp/erc/resources/erc-d/erc-d.el b/test/lisp/erc/resources/erc-d/erc-d.el
new file mode 100644
index 00000000000..ee9b6a7fec9
--- /dev/null
+++ b/test/lisp/erc/resources/erc-d/erc-d.el
@@ -0,0 +1,997 @@
+;;; erc-d.el --- A dumb test server for ERC -*- lexical-binding: t -*-
+
+;; Copyright (C) 2020-2022 Free Software Foundation, Inc.
+;;
+;; This file is part of GNU Emacs.
+;;
+;; This program is free software: you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation, either version 3 of the
+;; License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see
+;; <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This is a netcat style server for testing ERC. The "d" in the name
+;; stands for "daemon" as well as for "dialog" (as well as for "dumb"
+;; because this server isn't very smart). It either spits out a
+;; canned reply when an incoming request matches the expected regexp
+;; or signals an error and dies. The entry point function is
+;; `erc-d-run'.
+;;
+;; Canned scripts, or "dialogs," should be Lisp-Data files containing
+;; one or more request/reply forms like this:
+;;
+;; | ((mode-chan 1.5 "MODE #chan") ; request: tag, expr, regex
+;; | (0.1 ":irc.org 324 bob #chan +Cint") ; reply: delay, content
+;; | (0.0 ":irc.org 329 bob #chan 12345")) ; reply: ...
+;;
+;; These are referred to as "exchanges." The first element is a list
+;; whose CAR is a descriptive "tag" and whose CDR is an incoming
+;; "spec" representing an inbound message from the client. The rest
+;; of the exchange is composed of outgoing specs representing
+;; server-to-client messages. A tag can be any symbol (ideally unique
+;; in the dialog), but a leading tilde means the request should be
+;; allowed to arrive out of order (within the allotted time).
+;;
+;; The first element in an incoming spec is a number indicating the
+;; maximum number of seconds to wait for a match before raising an
+;; error. The CDR is interpreted as the collective arguments of an
+;; `rx' form to be matched against the raw request (stripped of its
+;; CRLF line ending). A "string-start" backslash assertion, "\\`", is
+;; prepended to all patterns.
+;;
+;; Similarly, the leading number in an *outgoing* spec indicates how
+;; many seconds to wait before sending the line, which is rendered by
+;; concatenating the other members after evaluating each in place.
+;; CRLF line endings are appended on the way out and should be absent.
+;;
+;; Recall that IRC is "asynchronous," meaning some flow intervals
+;; don't jibe with lockstep request-reply semantics. However, for our
+;; purposes, grouping things as [input, output1, ..., outputN] makes
+;; sense, even though input and output may be completely unrelated.
+;;
+;; Template interpolation:
+;;
+;; A rudimentary templating facility is provided for additional
+;; flexibility. However, it's best to keep things simple (even if
+;; overly verbose), so others can easily tell what's going on at a
+;; glance. If necessary, consult existing tests for examples (grep
+;; for the variables `erc-d-tmpl-vars' and `erc-d-match-handlers').
+;;
+;; Subprocess or in-process?:
+;;
+;; Running in-process confers better visibility and easier setup at
+;; the cost of additional cleanup and resource wrangling. With a
+;; subprocess, cleanup happens by pulling the plug, but configuration
+;; means loading a separate file or passing -eval "(forms...)" during
+;; invocation. In some cases, a subprocess may be the only option,
+;; like when trying to avoid `require'ing this file.
+;;
+;; Dialog objects:
+;;
+;; For a given exchange, the first argument passed to a request
+;; handler is the `erc-d-dialog' object representing the overall
+;; conversation with the connecting peer. It can be used to pass
+;; information between handlers during a session. Some important
+;; items are:
+;;
+;; * name (symbol); name of the current dialog
+;;
+;; * queue (ring); a backlog of unhandled raw requests, minus CRLF
+;; endings.
+;;
+;; * timers (list of timers); when run, these send messages originally
+;; deferred as per the most recently matched exchange's delay info.
+;; Normally, all outgoing messages must be sent before another request
+;; is considered. (See `erc-d--send-outgoing' for an escape hatch.)
+;;
+;; * hunks (iterator of iterators); unconsumed exchanges as read from
+;; a Lisp-Data dialog file. The exchange iterators being dispensed
+;; themselves yield portions of member forms as a 2- or 3-part
+;; sequence: [tag] spec. (Here, "hunk" just means "list of raw,
+;; unrendered exchange elements")
+;;
+;; * vars (alist of cons pairs); for sharing state among template
+;; functions during the lifetime of an exchange. Initially populated
+;; by `erc-d-tmpl-vars', these KEY/VALUE pairs are expanded in the
+;; templates and optionally updated by "exchange handlers" (see
+;; `erc-d-match-handlers'). When VALUE is a function, occurrences of
+;; KEY in an outgoing spec are replaced with the result of calling
+;; VALUE with match data set appropriately. See
+;; `erc-d--render-entries' for details.
+;;
+;; * exchanges (ring of erc-d-exchange objects); activated hunks
+;; allowed to match out of order, plus the current active exchange
+;; being yielded from, if any. See `erc-d-exchange'.
+;;
+;; TODO
+;;
+;; - Remove un(der)used functionality and simplify API
+;; - Maybe migrate d-u and d-i dependencies here
+
+;;; Code:
+(eval-and-compile
+ (let* ((d (file-name-directory (or (macroexp-file-name) buffer-file-name)))
+ (load-path (cons (directory-file-name d) load-path)))
+ (require 'erc-d-i)
+ (require 'erc-d-u)))
+
+(require 'ring)
+
+(defvar erc-d-server-name "erc-d-server"
+ "Default name of a server process and basis for its buffer name.
+Only relevant when starting a server with `erc-d-run'.")
+
+(defvar erc-d-server-fqdn "irc.example.org"
+ "Usually the same as the server's RPL_MYINFO \"announced name\".
+Possibly used by overriding handlers, like the one for PING, and/or
+dialog templates for the sender portion of a reply message.")
+
+(defvar erc-d-linger-secs nil
+ "Seconds to wait before quitting for all dialogs.
+For more granular control, use the provided LINGER `rx' variable (alone)
+as the incoming template spec of a dialog's last exchange.")
+
+(defvar erc-d-tmpl-vars nil
+ "An alist of template bindings available to client dialogs.
+Populate it when calling `erc-d-run', and the contents will be made
+available to all client dialogs through the `erc-d-dialog' \"vars\"
+field and (therefore) to all templates as variables when rendering. For
+example, a key/value pair like (network . \"oftc\") will cause instances
+of the (unquoted) symbol `network' to be replaced with \"oftc\" in the
+rendered template string.
+
+This list provides default template bindings common to all dialogs.
+Each new client-connection process makes a shallow copy on init, but the
+usual precautions apply when mutating member items. Within the span of
+a dialog, updates not applicable to all exchanges should die with their
+exchange. See `erc-d--render-entries' for details. In the unlikely
+event that an exchange-specific handler is needed, see
+`erc-d-match-handlers'.")
+
+(defvar erc-d-match-handlers nil
+ "A plist of exchange-tag symbols mapped to request-handler functions.
+This is meant to address edge cases for which `erc-d-tmpl-vars' comes up
+short. These may include (1) needing access to the client process
+itself and/or (2) adding or altering outgoing response templates before
+rendering. Note that (2) requires using `erc-d-exchange-rebind' instead
+of manipulating exchange bindings directly.
+
+The hook-like function `erc-d-on-match' calls any handler whose key is
+`eq' to the tag of the currently matched exchange (passing the client
+`erc-d-dialog' as the first argument and the current `erc-d-exchange'
+object as the second). The handler runs just prior to sending the first
+response.")
+
+(defvar erc-d-auto-pong t
+ "Handle PING requests automatically.")
+
+(defvar erc-d--in-process t
+ "Whether the server is running in the same Emacs as ERT.")
+
+(defvar erc-d--slow-mo nil
+ "Adjustment for all incoming timeouts.
+This is to allow for human interaction or a slow Emacs or CI runner.
+The value is the number of seconds to extend all incoming spec timeouts
+by on init. If the value is a negative number, it's negated and
+interpreted as a lower bound to raise all incoming timeouts to. If the
+value is a function, it should take an existing timeout in seconds and
+return a replacement.")
+
+(defconst erc-d--eof-sentinel "__EOF__")
+(defconst erc-d--linger-sentinel "__LINGER__")
+(defconst erc-d--drop-sentinel "__DROP__")
+
+(defvar erc-d--clients nil
+ "List containing all clients for this server session.")
+
+;; Some :type names may just be made up (not actual CL types)
+
+(cl-defstruct (erc-d-spec) ; see `erc-d--render-entries'
+ (head nil :type symbol) ; or number?
+ (entry nil :type list)
+ (state 0 :type integer))
+
+(cl-defstruct (erc-d-exchange)
+ "Object representing a request/response unit from a canned dialog."
+ (dialog nil :type erc-d-dialog) ; owning dialog
+ (tag nil :type symbol) ; a.k.a. tag, the caar
+ (pattern nil :type string) ; regexp to match requests against
+ (inspec nil :type list) ; original unrendered incoming spec
+ (hunk nil :type erc-d-u-scan-e) ; active raw exchange hunk being yielded
+ (spec nil :type erc-d-spec) ; active spec, see `erc-d--render-entries'
+ (timeout nil :type number) ; time allotted for current request
+ (timer nil :type timer) ; match timer fires when timeout expires
+ (bindings nil :type list) ; `eval'-style env pairs (KEY . VAL) ...
+ (rx-bindings nil :type list) ; rx-let bindings
+ (deferred nil :type boolean) ; whether sender is paused
+ ;; Post-match
+ (match-data nil :type match-data) ; from the latest matched request
+ (request nil :type string)) ; the original request sans CRLF
+
+(cl-defstruct (erc-d-dialog)
+ "Session state for managing a client conversation."
+ (process nil :type process) ; client-connection process
+ (name nil :type symbol) ; likely the interned stem of the file
+ (queue nil :type ring) ; backlog of incoming lines to process
+ (hunks nil :type erc-d-u-scan-d) ; nil when done; info on raw exchange hunks
+ (timers nil :type list) ; unsent replies
+ (vars nil :type list) ; template bindings for rendering
+ (exchanges nil :type ring) ; ring of erc-d-exchange objects
+ (state nil :type symbol) ; handler's last recorded control state
+ (matched nil :type erc-d-exchange) ; currently matched exchange
+ (message nil :type erc-d-i-message) ; `erc-d-i-message'
+ (match-handlers nil :type list) ; copy of `erc-d-match-handlers'
+ (server-fqdn nil :type string) ; copy of `erc-d-server-fqdn'
+ (finalizer nil :type function) ; custom teardown, passed dialog and exchange
+ ;; Post-match history is a plist whose keys are exchange tags
+ ;; (symbols) and whose values are a cons of match-data and request
+ ;; values from prior matches.
+ (history nil :type list))
+
+(defun erc-d--initialize-client (process)
+ "Initialize state variables used by a client PROCESS."
+ ;; Discard server-only/owned props
+ (process-put process :dialog-dialogs nil)
+ (let* ((server (process-get process :server))
+ (reader (pop (process-get server :dialog-dialogs)))
+ (name (pop reader))
+ ;; Copy handlers so they can self-mutate per process
+ (mat-h (copy-sequence (process-get process :dialog-match-handlers)))
+ (fqdn (copy-sequence (process-get process :dialog-server-fqdn)))
+ (vars (copy-sequence (process-get process :dialog-vars)))
+ (dialog (make-erc-d-dialog :name name
+ :process process
+ :queue (make-ring 5)
+ :exchanges (make-ring 10)
+ :match-handlers mat-h
+ :server-fqdn fqdn)))
+ ;; Add items expected by convenience commands like `erc-d-exchange-reload'.
+ (setf (alist-get 'EOF vars) `(: ,erc-d--eof-sentinel eot)
+ (alist-get 'LINGER vars) `(: ,erc-d--linger-sentinel eot)
+ (alist-get 'DROP vars) `(: ,erc-d--drop-sentinel eot)
+ (erc-d-dialog-vars dialog) vars
+ (erc-d-dialog-hunks dialog) reader)
+ ;; Add reverse link, register client, launch
+ (process-put process :dialog dialog)
+ (push process erc-d--clients)
+ (erc-d--command-refresh dialog nil)
+ (erc-d--on-request process)))
+
+(defun erc-d-load-replacement-dialog (dialog replacement &optional skip)
+ "Find REPLACEMENT among backlog and swap out current DIALOG's iterator.
+With int SKIP, advance past that many exchanges."
+ (let* ((process (erc-d-dialog-process dialog))
+ (server (process-get process :server))
+ (reader (assoc-default replacement
+ (process-get server :dialog-dialogs)
+ #'eq)))
+ (when skip (while (not (zerop skip))
+ (erc-d-u--read-dialog reader)
+ (cl-decf skip)))
+ (dolist (timer (erc-d-dialog-timers dialog))
+ (cancel-timer timer))
+ (dolist (exchange (ring-elements (erc-d-dialog-exchanges dialog)))
+ (cancel-timer (erc-d-exchange-timer exchange)))
+ (setf (erc-d-dialog-hunks dialog) reader)
+ (erc-d--command-refresh dialog nil)))
+
+(defvar erc-d--m-debug (getenv "ERC_D_DEBUG"))
+
+(defmacro erc-d--m (process format-string &rest args)
+ "Output ARGS using FORMAT-STRING somewhere depending on context.
+PROCESS should be a client connection or a server network process."
+ `(let ((format-string (if erc-d--m-debug
+ (concat (format-time-string "%s.%N: ")
+ ,format-string)
+ ,format-string))
+ (want-insert (and ,process erc-d--in-process)))
+ (when want-insert
+ (with-current-buffer (process-buffer (process-get ,process :server))
+ (goto-char (point-max))
+ (insert (concat (format ,format-string ,@args) "\n"))))
+ (when (or erc-d--m-debug (not want-insert))
+ (message format-string ,@args))))
+
+(defmacro erc-d--log (process string &optional outbound)
+ "Log STRING sent to (OUTBOUND) or received from PROCESS peer."
+ `(let ((id (or (process-get ,process :log-id)
+ (let ((port (erc-d-u--get-remote-port ,process)))
+ (process-put ,process :log-id port)
+ port)))
+ (name (erc-d-dialog-name (process-get ,process :dialog))))
+ (if ,outbound
+ (erc-d--m process "-> %s:%s %s" name id ,string)
+ (dolist (line (split-string ,string "\r\n"))
+ (erc-d--m process "<- %s:%s %s" name id line)))))
+
+(defun erc-d--log-process-event (server process msg)
+ (erc-d--m server "%s: %s" process (string-trim-right msg)))
+
+(defun erc-d--send (process string)
+ "Send STRING to PROCESS peer."
+ (erc-d--log process string 'outbound)
+ (process-send-string process (concat string "\r\n")))
+
+(define-inline erc-d--fuzzy-p (exchange)
+ (inline-letevals (exchange)
+ (inline-quote
+ (let ((tag (symbol-name (erc-d-exchange-tag ,exchange))))
+ (eq ?~ (aref tag 0))))))
+
+(define-error 'erc-d-timeout "Timed out awaiting expected request")
+
+(defun erc-d--finalize-dialog (dialog)
+ "Delete client-connection and finalize DIALOG.
+Return associated server."
+ (let ((process (erc-d-dialog-process dialog)))
+ (setq erc-d--clients (delq process erc-d--clients))
+ (dolist (timer (erc-d-dialog-timers dialog))
+ (cancel-timer timer))
+ (dolist (exchange (ring-elements (erc-d-dialog-exchanges dialog)))
+ (cancel-timer (erc-d-exchange-timer exchange)))
+ (prog1 (process-get process :server)
+ (delete-process process))))
+
+(defun erc-d--teardown (&optional sig &rest msg)
+ "Clean up processes and maybe send signal SIG using MSG."
+ (unless erc-d--in-process
+ (when sig
+ (erc-d--m nil "%s %s" sig (apply #'format-message msg)))
+ (kill-emacs (if msg 1 0)))
+ (let (process servers)
+ (while (setq process (pop erc-d--clients))
+ (push (erc-d--finalize-dialog (process-get process :dialog)) servers))
+ (dolist (server servers)
+ (delete-process server)))
+ (dolist (timer timer-list)
+ (when (memq (timer--function timer)
+ '(erc-d--send erc-d--command-handle-all))
+ (erc-d--m nil "Stray timer found: %S" (timer--function timer))
+ (cancel-timer timer)))
+ (when sig
+ (dolist (buf erc-d-u--canned-buffers)
+ (kill-buffer buf))
+ (setq erc-d-u--canned-buffers nil)
+ (signal sig (list (apply #'format-message msg)))))
+
+(defun erc-d--teardown-this-dialog-at-least (dialog)
+ "Run `erc-d--teardown' after destroying DIALOG if it's the last one."
+ (let ((server (process-get (erc-d-dialog-process dialog) :server))
+ (us (erc-d-dialog-process dialog)))
+ (erc-d--finalize-dialog dialog)
+ (cl-assert (not (memq us erc-d--clients)))
+ (unless (or (process-get server :dialog-dialogs)
+ (catch 'other
+ (dolist (process erc-d--clients)
+ (when (eq (process-get process :server) server)
+ (throw 'other process)))))
+ (push us erc-d--clients)
+ (erc-d--teardown))))
+
+(defun erc-d--expire (dialog exchange)
+ "Raise timeout error for EXCHANGE.
+This will start the teardown for DIALOG."
+ (setf (erc-d-exchange-spec exchange) nil)
+ (if-let ((finalizer (erc-d-dialog-finalizer dialog)))
+ (funcall finalizer dialog exchange)
+ (erc-d--teardown 'erc-d-timeout "Timed out awaiting request: %s"
+ (list :name (erc-d-exchange-tag exchange)
+ :pattern (erc-d-exchange-pattern exchange)
+ :timeout (erc-d-exchange-timeout exchange)
+ :dialog (erc-d-dialog-name dialog)))))
+
+;; Using `run-at-time' here allows test cases to examine replies as
+;; they arrive instead of forcing tests to wait until an exchange
+;; completes. The `run-at-time' in `erc-d--command-meter-replies'
+;; does the same. When running as a subprocess, a normal while loop
+;; with a `sleep-for' works fine (including with multiple dialogs).
+;; FYI, this issue was still present in older versions that called
+;; this directly from `erc-d--filter'.
+
+(defun erc-d--on-request (process)
+ "Handle one request for client-connection PROCESS."
+ (when (process-live-p process)
+ (let* ((dialog (process-get process :dialog))
+ (queue (erc-d-dialog-queue dialog)))
+ (unless (ring-empty-p queue)
+ (let* ((parsed (ring-remove queue))
+ (cmd (intern (erc-d-i-message.command parsed))))
+ (setf (erc-d-dialog-message dialog) parsed)
+ (erc-d-command dialog cmd)))
+ (run-at-time nil nil #'erc-d--on-request process))))
+
+(defun erc-d--drop-p (exchange)
+ (memq 'DROP (erc-d-exchange-inspec exchange)))
+
+(defun erc-d--linger-p (exchange)
+ (memq 'LINGER (erc-d-exchange-inspec exchange)))
+
+(defun erc-d--fake-eof (dialog)
+ "Simulate receiving a fictitious \"EOF\" message from peer."
+ (setf (erc-d-dialog-message dialog) ; use downcase for internal cmds
+ (make-erc-d-i-message :command "eof" :unparsed erc-d--eof-sentinel))
+ (run-at-time nil nil #'erc-d-command dialog 'eof))
+
+(defun erc-d--process-sentinel (process event)
+ "Set up or tear down client-connection PROCESS depending on EVENT."
+ (erc-d--log-process-event process process event)
+ (if (eq 'open (process-status process))
+ (erc-d--initialize-client process)
+ (let* ((dialog (process-get process :dialog))
+ (exes (and dialog (erc-d-dialog-exchanges dialog))))
+ (if (and exes (not (ring-empty-p exes)))
+ (cond ((string-prefix-p "connection broken" event)
+ (erc-d--fake-eof dialog))
+ ;; Ignore disconnecting peer when pattern is DROP
+ ((and (string-prefix-p "deleted" event)
+ (erc-d--drop-p (ring-ref exes -1))))
+ (t (erc-d--teardown)))
+ (erc-d--teardown)))))
+
+(defun erc-d--filter (process string)
+ "Handle input received from peer.
+PROCESS represents a client peer connection and STRING is a raw request
+including line delimiters."
+ (let ((queue (erc-d-dialog-queue (process-get process :dialog))))
+ (setq string (concat (process-get process :stashed-input) string))
+ (while (and string (string-match (rx (+ "\r\n")) string))
+ (let ((line (substring string 0 (match-beginning 0))))
+ (setq string (unless (= (match-end 0) (length string))
+ (substring string (match-end 0))))
+ (erc-d--log process line nil)
+ (ring-insert queue (erc-d-i--parse-message line 'decode))))
+ (when string
+ (setf (process-get process :stashed-input) string))))
+
+;; Misc process properties:
+;;
+;; The server property `:dialog-dialogs' is an alist of (symbol
+;; . erc-d-u-scan-d) conses, each of which pairs a dialogs name with
+;; info on its read progress (described above in the Commentary).
+;; This list is populated by `erc-d-run' at the start of each session.
+;;
+;; Client-connection processes keep a reference to their server via a
+;; `:server' property, which can be used to share info with other
+;; clients. There is currently no built-in way to do the same with
+;; clients of other servers. Clients also keep references to their
+;; dialogs and raw messages via `:dialog' and `:stashed-input'.
+;;
+;; The logger stores a unique, human-friendly process name in the
+;; client-process property `:log-id'.
+
+(defun erc-d--start (host service name &rest plist)
+ "Serve canned replies on HOST at SERVICE.
+Return the new server process immediately when `erc-d--in-process' is
+non-nil. Otherwise, serve forever. PLIST becomes the plist of the
+server process and is used to initialize the plists of connection
+processes. NAME is used for the process and the buffer."
+ (let* ((buf (get-buffer-create (concat "*" name "*")))
+ (proc (make-network-process :server t
+ :buffer buf
+ :noquery t
+ :filter #'erc-d--filter
+ :log #'erc-d--log-process-event
+ :sentinel #'erc-d--process-sentinel
+ :name name
+ :family (if host 'ipv4 'local)
+ :coding 'binary
+ :service (or service t)
+ :host host
+ :plist plist)))
+ (process-put proc :server proc)
+ ;; We don't have a minor mode, so use an arbitrary variable to mark
+ ;; buffers owned by us instead
+ (with-current-buffer buf (setq erc-d-u--process-buffer t))
+ (erc-d--m proc "Starting network process: %S %S"
+ proc (erc-d-u--format-bind-address proc))
+ (if erc-d--in-process
+ proc
+ (while (process-live-p proc)
+ (accept-process-output nil 0.01)))))
+
+(defun erc-d--wrap-func-val (dialog exchange key func)
+ "Return a form invoking FUNC when evaluated.
+Arrange for FUNC to be called with the args it expects based on
+the description in `erc-d--render-entries'."
+ (let (args)
+ ;; Ignore &rest or &optional
+ (pcase-let ((`(,n . ,_) (func-arity func)))
+ (pcase n
+ (0)
+ (1 (push (apply-partially #'erc-d-exchange-multi dialog exchange key)
+ args))
+ (2 (push exchange args)
+ (push (apply-partially #'erc-d-exchange-multi dialog exchange key)
+ args))
+ (_ (error "Incompatible function: %s" func))))
+ (lambda () (apply func args))))
+
+(defun erc-d-exchange-reload (dialog exchange)
+ "Rebuild all bindings for EXCHANGE from those in DIALOG."
+ (cl-loop for (key . val) in (erc-d-dialog-vars dialog)
+ unless (keywordp key)
+ do (push (erc-d-u--massage-rx-args key val)
+ (erc-d-exchange-rx-bindings exchange))
+ when (functionp val) do
+ (setq val (erc-d--wrap-func-val dialog exchange key val))
+ do (push (cons key val) (erc-d-exchange-bindings exchange))))
+
+(defun erc-d-exchange-rebind (dialog exchange key val &optional export)
+ "Modify a binding between renders.
+
+Bind symbol KEY to VAL, replacing whatever existed before, which may
+have been a function. A third, optional argument, if present and
+non-nil, results in the DIALOG's bindings for all EXCHANGEs adopting
+this binding. VAL can either be a function of the type described in
+`erc-d--render-entries' or any value acceptable as an argument to the
+function `concat'.
+
+DIALOG and EXCHANGE are the current `erc-d-dialog' and `erc-d-exchange'
+objects for the request context."
+ (when export
+ (setf (alist-get key (erc-d-dialog-vars dialog)) val))
+ (if (functionp val)
+ (setf (alist-get key (erc-d-exchange-bindings exchange))
+ (erc-d--wrap-func-val dialog exchange key val))
+ (setf (alist-get key (erc-d-exchange-rx-bindings exchange)) (list val)
+ (alist-get key (erc-d-exchange-bindings exchange)) val))
+ val)
+
+(defun erc-d-exchange-match (exchange match-number &optional tag)
+ "Return match portion of current or previous request.
+MATCH-NUMBER is the match group number. TAG, if provided, means the
+exchange tag (name) from some previously matched request."
+ (if tag
+ (pcase-let* ((dialog (erc-d-exchange-dialog exchange))
+ (`(,m-d . ,req) (plist-get (erc-d-dialog-history dialog)
+ tag)))
+ (set-match-data m-d)
+ (match-string match-number req))
+ (match-string match-number (erc-d-exchange-request exchange))))
+
+(defun erc-d-exchange-multi (dialog exchange key cmd &rest args)
+ "Call CMD with ARGS.
+This is a utility passed as the first argument to all template
+functions. DIALOG and EXCHANGE are pre-applied. A few pseudo
+commands, like `:request', are provided for convenience so that
+the caller's definition doesn't have to include this file. The
+rest are access and mutation utilities, such as `:set', which
+assigns KEY a new value, `:get-binding', which looks up KEY in
+`erc-d-exchange-bindings', and `:get-var', which looks up KEY in
+`erc-d-dialog-vars'."
+ (pcase cmd
+ (:set (apply #'erc-d-exchange-rebind dialog exchange key args))
+ (:reload (apply #'erc-d-exchange-reload dialog exchange args))
+ (:rebind (apply #'erc-d-exchange-rebind dialog exchange args))
+ (:match (apply #'erc-d-exchange-match exchange args))
+ (:request (erc-d-exchange-request exchange))
+ (:match-data (erc-d-exchange-match-data exchange))
+ (:dialog-name (erc-d-dialog-name dialog))
+ (:get-binding (cdr (assq (car args) (erc-d-exchange-bindings exchange))))
+ (:get-var (alist-get (car args) (erc-d-dialog-vars dialog)))))
+
+(defun erc-d--render-incoming-entry (exchange spec)
+ (let ((rx--local-definitions (rx--extend-local-defs
+ (erc-d-exchange-rx-bindings exchange))))
+ (rx-to-string `(: bos ,@(erc-d-spec-entry spec)) 'no-group)))
+
+(defun erc-d--render-outgoing-entry (exchange entry)
+ (let (out this)
+ (while (setq this (pop entry))
+ (set-match-data (erc-d-exchange-match-data exchange))
+ (unless (stringp this)
+ (cl-assert (symbolp this))
+ (setq this (or (alist-get this (erc-d-exchange-bindings exchange))
+ (symbol-value this)))
+ ;; Allow reference to overlong var name unbecoming of a template
+ (when this
+ (when (symbolp this) (setq this (symbol-value this)))
+ (when (functionp this) (setq this (save-match-data (funcall this))))
+ (unless (stringp this) (error "Unexpected token %S" this))))
+ (push this out))
+ (apply #'concat (nreverse out))))
+
+(defun erc-d--render-entries (exchange &optional yield-result)
+ "Act as an iterator producing rendered strings from EXCHANGE hunks.
+When an entry's CAR is an arbitrary symbol, yield that back first, and
+consider the entry an \"incoming\" entry. Then, regardless of the
+entry's type (incoming or outgoing), yield back the next element, which
+should be a number representing either a timeout (incoming) or a
+delay (outgoing). After that, yield a rendered template (outgoing) or a
+regular expression (incoming); both should be treated as immutable.
+
+When evaluating a template, bind the keys in the alist stored in the
+dialog's `vars' field to its values, but skip any self-quoters, like
+:foo. When an entry is incoming, replace occurrences of a key with its
+value, which can be any valid `rx' form (see Info node `(elisp)
+Extending Rx'). Do the same when an entry is outgoing, but expect a
+value's form to be (anything that evaluates to) something acceptable by
+`concat' or, alternatively, a function that returns a string or nil.
+
+Repeat the last two steps for the remaining entries, all of which are
+assumed to be outgoing. That is, continue yielding a timeout/delay and
+a rendered string for each entry, and yield nil when exhausted.
+
+Once again, for an incoming entry, the yielded string is a regexp to be
+matched against the raw request. For outgoing, it's the final response,
+ready to be sent out (after adding the appropriate line ending).
+
+To help with testing, bindings are not automatically created from
+DIALOG's \"vars\" alist when this function is invoked. But this can be
+forced by sending a non-nil YIELD-RESULT into the generator on the
+second \"next\" invocation of a given iteration. This clobbers any
+temporary bindings that don't exist in the DIALOG's `vars' alist, such
+as those added via `erc-d-exchange-rebind' (unless \"exported\").
+
+As noted earlier, template symbols can be bound to functions. When
+called during rendering, the match data from the current (matched)
+request is accessible by calling the function `match-data'.
+
+A function may ask for up to two required args, which are provided as
+needed. When applicable, the first required arg is a `funcall'-able
+helper that accepts various keyword-based commands, like :rebind, and a
+variable number of args. See `erc-d-exchange-multi' for details. When
+specified, the second required arg is the current `erc-d-exchange'
+object, which has among its members its owning `erc-d-dialog' object.
+This should suffice as a safety valve for any corner-case needs.
+Non-required args are ignored."
+ (let ((spec (erc-d-exchange-spec exchange))
+ (dialog (erc-d-exchange-dialog exchange))
+ (entries (erc-d-exchange-hunk exchange)))
+ (unless (erc-d-spec-entry spec)
+ (setf (erc-d-spec-entry spec) (erc-d-u--read-exchange entries)))
+ (catch 'yield
+ (while (erc-d-spec-entry spec)
+ (pcase (erc-d-spec-state spec)
+ (0 (cl-incf (erc-d-spec-state spec))
+ (throw 'yield (setf (erc-d-spec-head spec)
+ (pop (erc-d-spec-entry spec)))))
+ (1 (cl-incf (erc-d-spec-state spec))
+ (when yield-result
+ (erc-d-exchange-reload dialog exchange))
+ (unless (numberp (erc-d-spec-head spec))
+ (setf (erc-d-exchange-inspec exchange) (erc-d-spec-entry spec))
+ (throw 'yield
+ (prog1 (pop (erc-d-spec-entry spec))
+ (setf (erc-d-spec-entry spec)
+ (erc-d--render-incoming-entry exchange spec))))))
+ (2 (setf (erc-d-spec-state spec) 0)
+ (throw 'yield
+ (let ((entry (erc-d-spec-entry spec)))
+ (setf (erc-d-spec-entry spec) nil)
+ (if (stringp entry)
+ entry
+ (erc-d--render-outgoing-entry exchange entry))))))))))
+
+(defun erc-d--iter (exchange)
+ (apply-partially #'erc-d--render-entries exchange))
+
+(defun erc-d-on-match (dialog exchange)
+ "Handle matched exchange request.
+Allow the first handler in `erc-d-match-handlers' whose key matches TAG
+to manipulate replies before they're sent to the DIALOG peer."
+ (when-let* ((tag (erc-d-exchange-tag exchange))
+ (handler (plist-get (erc-d-dialog-match-handlers dialog) tag)))
+ (let ((md (erc-d-exchange-match-data exchange)))
+ (set-match-data md)
+ (funcall handler dialog exchange))))
+
+(defun erc-d--send-outgoing (dialog exchange)
+ "Send outgoing lines for EXCHANGE to DIALOG peer.
+Assume the next spec is outgoing. If its delay value is zero, render
+the template and send the resulting message straight away. Do the same
+when DELAY is negative, only arrange for its message to be sent (abs
+DELAY) seconds later, and then keep on processing. If DELAY is
+positive, pause processing and yield DELAY."
+ (let ((specs (erc-d--iter exchange))
+ (process (erc-d-dialog-process dialog))
+ (deferred (erc-d-exchange-deferred exchange))
+ delay)
+ ;; Could stash/pass thunk instead to ensure specs can't be mutated
+ ;; between calls (by temporarily replacing dialog member with a fugazi)
+ (when deferred
+ (erc-d--send process (funcall specs))
+ (setf deferred nil (erc-d-exchange-deferred exchange) deferred))
+ (while (and (not deferred) (setq delay (funcall specs)))
+ (cond ((zerop delay) (erc-d--send process (funcall specs)))
+ ((< delay 0) (push (run-at-time (- delay) nil #'erc-d--send
+ process (funcall specs))
+ (erc-d-dialog-timers dialog)))
+ ((setf deferred t (erc-d-exchange-deferred exchange) deferred))))
+ delay))
+
+(defun erc-d--add-dialog-linger (dialog exchange)
+ "Add finalizer for EXCHANGE in DIALOG."
+ (erc-d--m (erc-d-dialog-process dialog)
+ "Lingering for %.2f seconds" (erc-d-exchange-timeout exchange))
+ (let ((start (current-time)))
+ (setf (erc-d-dialog-finalizer dialog)
+ (lambda (&rest _)
+ (erc-d--m (erc-d-dialog-process dialog)
+ "Lingered for %.2f seconds"
+ (float-time (time-subtract (current-time) start)))
+ (erc-d--teardown-this-dialog-at-least dialog)))))
+
+(defun erc-d--add-dialog-drop (dialog exchange)
+ "Add finalizer for EXCHANGE in DIALOG."
+ (erc-d--m (erc-d-dialog-process dialog)
+ "Dropping in %.2f seconds" (erc-d-exchange-timeout exchange))
+ (setf (erc-d-dialog-finalizer dialog)
+ (lambda (&rest _)
+ (erc-d--m (erc-d-dialog-process dialog)
+ "Dropping %S" (erc-d-dialog-name dialog))
+ (erc-d--finalize-dialog dialog))))
+
+(defun erc-d--create-exchange (dialog hunk)
+ "Initialize next exchange HUNK for DIALOG."
+ (let* ((spec (make-erc-d-spec))
+ (exchange (make-erc-d-exchange :dialog dialog :hunk hunk :spec spec))
+ (specs (erc-d--iter exchange)))
+ (setf (erc-d-exchange-tag exchange) (funcall specs)
+ (erc-d-exchange-timeout exchange) (funcall specs t)
+ (erc-d-exchange-pattern exchange) (funcall specs))
+ (cond ((erc-d--linger-p exchange)
+ (erc-d--add-dialog-linger dialog exchange))
+ ((erc-d--drop-p exchange)
+ (erc-d--add-dialog-drop dialog exchange)))
+ (setf (erc-d-exchange-timer exchange)
+ (run-at-time (erc-d-exchange-timeout exchange)
+ nil #'erc-d--expire dialog exchange))
+ exchange))
+
+(defun erc-d--command-consider-prep-fail (dialog line exes)
+ (list 'error "Match failed: %S %S" line
+ (list :exes (mapcar #'erc-d-exchange-pattern
+ (ring-elements exes))
+ :dialog (erc-d-dialog-name dialog))))
+
+(defun erc-d--command-consider-prep-success (dialog line exes matched)
+ (setf (erc-d-exchange-request matched) line
+ (erc-d-exchange-match-data matched) (match-data)
+ ;; Also add current to match history, indexed by exchange tag
+ (plist-get (erc-d-dialog-history dialog)
+ (erc-d-exchange-tag matched))
+ (cons (match-data) line)) ; do we need to make a copy of this?
+ (cancel-timer (erc-d-exchange-timer matched))
+ (ring-remove exes (ring-member exes matched)))
+
+(cl-defun erc-d--command-consider (dialog)
+ "Maybe return next matched exchange for DIALOG.
+Upon encountering a mismatch, return an error of the form (ERROR-SYMBOL
+DATA). But when only fuzzies remain in the exchange pool, return nil."
+ (let* ((parsed (erc-d-dialog-message dialog))
+ (line (erc-d-i-message.unparsed parsed))
+ (exes (erc-d-dialog-exchanges dialog))
+ ;;
+ matched)
+ (let ((elts (ring-elements exes)))
+ (while (and (setq matched (pop elts))
+ (not (string-match (erc-d-exchange-pattern matched) line)))
+ (if (and (not elts) (erc-d--fuzzy-p matched))
+ ;; Nothing to do, so advance
+ (cl-return-from erc-d--command-consider nil)
+ (cl-assert (or (not elts) (erc-d--fuzzy-p matched))))))
+ (if matched
+ (erc-d--command-consider-prep-success dialog line exes matched)
+ (erc-d--command-consider-prep-fail dialog line exes))))
+
+(defun erc-d--active-ex-p (ring)
+ "Return non-nil when RING has a non-fuzzy exchange.
+That is, return nil when RING is empty or when it only has exchanges
+with leading-tilde tags."
+ (let ((i 0)
+ (len (ring-length ring))
+ ex found)
+ (while (and (not found) (< i len))
+ (unless (erc-d--fuzzy-p (setq ex (ring-ref ring i)))
+ (setq found ex))
+ (cl-incf i))
+ found))
+
+(defun erc-d--finalize-done (dialog)
+ ;; Linger logic for individual dialogs is handled elsewhere
+ (if-let ((finalizer (erc-d-dialog-finalizer dialog)))
+ (funcall finalizer dialog)
+ (let ((d (process-get (erc-d-dialog-process dialog) :dialog-linger-secs)))
+ (push (run-at-time d nil #'erc-d--teardown)
+ (erc-d-dialog-timers dialog)))))
+
+(defun erc-d--advance-or-die (dialog)
+ "Govern the lifetime of DIALOG.
+Replenish exchanges from reader and insert them into the pool of
+expected matches, as produced. Return a symbol indicating session
+status: deferring, matching, depleted, or done."
+ (let ((exes (erc-d-dialog-exchanges dialog))
+ hunk)
+ (cond ((erc-d--active-ex-p exes) 'deferring)
+ ((setq hunk (erc-d-u--read-dialog (erc-d-dialog-hunks dialog)))
+ (let ((exchange (erc-d--create-exchange dialog hunk)))
+ (if (erc-d--fuzzy-p exchange)
+ (ring-insert exes exchange)
+ (ring-insert-at-beginning exes exchange)))
+ 'matching)
+ ((not (ring-empty-p exes)) 'depleted)
+ (t 'done))))
+
+(defun erc-d--command-meter-replies (dialog exchange &optional cmd)
+ "Ignore requests until all replies have been sent.
+Do this for some previously matched EXCHANGE in DIALOG based on CMD, a
+symbol. As a side effect, maybe schedule the resumption of the main
+loop after some delay."
+ (let (delay)
+ (if (or (not cmd) (eq 'resume cmd))
+ (when (setq delay (erc-d--send-outgoing dialog exchange))
+ (push (run-at-time delay nil #'erc-d--command-handle-all
+ dialog 'resume)
+ (erc-d-dialog-timers dialog))
+ (erc-d-dialog-state dialog))
+ (setf (erc-d-dialog-state dialog) 'sending))))
+
+(defun erc-d--die-unexpected (dialog)
+ (erc-d--teardown 'error "Received unexpected input: %S"
+ (erc-d-i-message.unparsed (erc-d-dialog-message dialog))))
+
+(defun erc-d--command-refresh (dialog matched)
+ (let ((state (erc-d--advance-or-die dialog)))
+ (when (eq state 'done)
+ (erc-d--finalize-done dialog))
+ (unless matched
+ (when (eq state 'depleted)
+ (erc-d--die-unexpected dialog))
+ (cl-assert (memq state '(matching depleted)) t))
+ (setf (erc-d-dialog-state dialog) state)))
+
+(defun erc-d--command-handle-all (dialog cmd)
+ "Create handler to act as control agent and process DIALOG requests.
+Have it ingest internal control commands (lowercase symbols) and yield
+back others indicating the lifecycle stage of the current dialog."
+ (let ((matched (erc-d-dialog-matched dialog)))
+ (cond
+ (matched
+ (or (erc-d--command-meter-replies dialog matched cmd)
+ (setf (erc-d-dialog-matched dialog) nil)
+ (erc-d--command-refresh dialog t)))
+ ((pcase cmd ; FIXME remove command facility or make extensible
+ ('resume nil)
+ ('eof (erc-d--m (erc-d-dialog-process dialog) "Received an EOF") nil)))
+ (t ; matching
+ (setq matched nil)
+ (catch 'yield
+ (while (not matched)
+ (when (ring-empty-p (erc-d-dialog-exchanges dialog))
+ (erc-d--die-unexpected dialog))
+ (when (setq matched (erc-d--command-consider dialog))
+ (if (eq (car-safe matched) 'error)
+ (apply #'erc-d--teardown matched)
+ (erc-d-on-match dialog matched)
+ (setf (erc-d-dialog-matched dialog) matched)
+ (if-let ((s (erc-d--command-meter-replies dialog matched nil)))
+ (throw 'yield s)
+ (setf (erc-d-dialog-matched dialog) nil))))
+ (erc-d--command-refresh dialog matched)))))))
+
+;;;; Handlers for IRC commands
+
+(cl-defgeneric erc-d-command (dialog cmd)
+ "Handle new CMD from client for DIALOG.
+By default, defer to this dialog's `erc-d--command-handle-all' instance,
+which is stored in its `handler' field.")
+
+(cl-defmethod erc-d-command ((dialog erc-d-dialog) cmd)
+ (when (eq 'sending (erc-d--command-handle-all dialog cmd))
+ (ring-insert-at-beginning (erc-d-dialog-queue dialog)
+ (erc-d-dialog-message dialog))))
+
+;; A similar PONG handler would be useless because we know when to
+;; expect them
+
+(cl-defmethod erc-d-command ((dialog erc-d-dialog) (_cmd (eql PING))
+ &context (erc-d-auto-pong (eql t)))
+ "Respond to PING request from DIALOG peer when ERC-D-AUTO-PONG is t."
+ (let* ((parsed (erc-d-dialog-message dialog))
+ (process (erc-d-dialog-process dialog))
+ (nonce (car (erc-d-i-message.command-args parsed)))
+ (fqdn (erc-d-dialog-server-fqdn dialog)))
+ (erc-d--send process (format ":%s PONG %s :%s" fqdn fqdn nonce))))
+
+
+;;;; Entry points
+
+(defun erc-d-run (host service &optional server-name &rest dialogs)
+ "Start serving DIALOGS on HOST at SERVICE.
+Pass HOST and SERVICE directly to `make-network-process'. When present,
+use string SERVER-NAME for the server-process name as well as that of
+its buffer (w. surrounding asterisks). When absent, do the same with
+`erc-d-server-name'. When running \"in process,\" return the server
+process, otherwise sleep for the duration of the server process.
+
+A dialog must be a symbol matching the base name of a dialog file in
+`erc-d-u-canned-dialog-dir'.
+
+The variable `erc-d-tmpl-vars' determines the common members of the
+`erc-d--render-entries' ENTRIES param. Variables `erc-d-server-fqdn'
+and `erc-d-linger-secs' determine the `erc-d-dialog' items
+`:server-fqdn' and `:linger-secs' for all client processes.
+
+The variable `erc-d-tmpl-vars' can be used to initialize the
+process's `erc-d-dialog' vars item."
+ (when (and server-name (symbolp server-name))
+ (push server-name dialogs)
+ (setq server-name nil))
+ (let (loaded)
+ (dolist (dialog (nreverse dialogs))
+ (let ((reader (erc-d-u--canned-load-dialog dialog)))
+ (when erc-d--slow-mo
+ (setq reader (erc-d-u--rewrite-for-slow-mo erc-d--slow-mo reader)))
+ (push (cons (erc-d-u--normalize-canned-name dialog) reader) loaded)))
+ (setq dialogs loaded))
+ (erc-d--start host service (or server-name erc-d-server-name)
+ :dialog-dialogs dialogs
+ :dialog-vars erc-d-tmpl-vars
+ :dialog-linger-secs erc-d-linger-secs
+ :dialog-server-fqdn erc-d-server-fqdn
+ :dialog-match-handlers (erc-d-u--unkeyword
+ erc-d-match-handlers)))
+
+(defun erc-d-serve ()
+ "Start serving canned dialogs from the command line.
+Although not autoloaded, this function is meant to be summoned via the
+Emacs -f flag while starting a batch session. It prints incoming and
+outgoing messages to standard out.
+
+The main options are --host HOST and --port PORT, which default to
+localhost and auto, respectively. The args are the dialogs to run.
+Unlike with `erc-d-run', dialogs here *must* be files, meaning Lisp-Data
+files adhering to the required format. (These consist of \"specs\"
+detailing timing and template info; see commentary for specifics.)
+
+An optional --add-time N option can also be passed to hike up timeouts
+by some number of seconds N. For example, you might run:
+
+ $ emacs -Q -batch -L . \\
+ > -l erc-d.el \\
+ > -f erc-d-serve \\
+ > --host 192.168.124.1 \\
+ > --port 16667 \\
+ > --add-time 10 \\
+ > ./my-dialog.eld
+
+from a Makefile or manually with \\<global-map>\\[compile]. And then in
+another terminal, do:
+
+ $ nc -C 192.168.124.1 16667 ; or telnet if your nc doesn't have -C
+ > PASS changeme
+ ...
+
+Use `erc-d-run' instead to start the server from within Emacs."
+ (unless noninteractive
+ (error "Command-line func erc-d-serve not run in -batch session"))
+ (setq erc-d--in-process nil)
+ (let (port host dialogs erc-d--slow-mo)
+ (while command-line-args-left
+ (pcase (pop command-line-args-left)
+ ("--add-time" (setq erc-d--slow-mo
+ (string-to-number (pop command-line-args-left))))
+ ("--linger" (setq erc-d-linger-secs
+ (string-to-number (pop command-line-args-left))))
+ ("--host" (setq host (pop command-line-args-left)))
+ ("--port" (setq port (string-to-number (pop command-line-args-left))))
+ (dialog (push dialog dialogs))))
+ (setq dialogs (mapcar #'erc-d-u--massage-canned-name dialogs))
+ (when erc-d--slow-mo
+ (message "Slow mo is ON"))
+ (apply #'erc-d-run (or host "localhost") port nil (nreverse dialogs))))
+
+(provide 'erc-d)
+
+;;; erc-d.el ends here
diff --git a/test/lisp/erc/resources/erc-d/resources/basic.eld b/test/lisp/erc/resources/erc-d/resources/basic.eld
new file mode 100644
index 00000000000..a020eec3fff
--- /dev/null
+++ b/test/lisp/erc/resources/erc-d/resources/basic.eld
@@ -0,0 +1,32 @@
+;;; -*- mode: lisp-data -*-
+
+((pass 10.0 "PASS " (? ?:) "changeme"))
+((nick 0.2 "NICK tester"))
+
+((user 0.2 "USER user 0 * :tester")
+ (0 ":irc.example.org 001 tester :Welcome to the Internet Relay Network tester")
+ (0 ":irc.example.org 002 tester :Your host is irc.example.org")
+ (0 ":irc.example.org 003 tester :This server was created just now")
+ (0 ":irc.example.org 004 tester irc.example.org BERios CEIRabehiklmnoqstv Iabehkloqv")
+ (0 ":irc.example.org 005 tester MODES NETWORK=ExampleOrg NICKLEN=32 PREFIX=(qaohv)~&@%+"
+ " :are supported by this server")
+ (0 ":irc.example.org 251 tester :There are 3 users and 0 invisible on 1 server(s)")
+ ;; Just to mix thing's up (force handler to schedule timer)
+ (0.1 ":irc.example.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.example.org 253 tester 0 :unregistered connections")
+ (0 ":irc.example.org 254 tester 1 :channels formed")
+ (0 ":irc.example.org 255 tester :I have 3 clients and 0 servers")
+ (0.1 ":irc.example.org 265 tester 3 3 :Current local users 3, max 3")
+ (0 ":irc.example.org 266 tester 3 3 :Current global users 3, max 3")
+ (0 ":irc.example.org 422 tester :MOTD File is missing"))
+
+((mode-user 5 "MODE tester +i")
+ (0 ":irc.example.org 221 tester +Zi")
+ (0 ":irc.example.org 306 tester :You have been marked as being away")
+ (0 ":tester!~tester@localhost JOIN #chan")
+ (0 ":irc.example.org 353 alice = #chan :+alice!~alice@example.com @%+bob!~bob@example.org")
+ (0 ":irc.example.org 366 alice #chan :End of NAMES list"))
+
+;; Some comment (to prevent regression)
+((mode-chan 1.2 "MODE #chan")
+ (0.1 ":bob!~bob@example.org PRIVMSG #chan :hey"))
diff --git a/test/lisp/erc/resources/erc-d/resources/depleted.eld b/test/lisp/erc/resources/erc-d/resources/depleted.eld
new file mode 100644
index 00000000000..e5a7f03efb7
--- /dev/null
+++ b/test/lisp/erc/resources/erc-d/resources/depleted.eld
@@ -0,0 +1,12 @@
+;;; -*- mode: lisp-data -*-
+
+((pass 10.0 "PASS :changeme"))
+
+((~fake 3.2 "FAKE ")
+ (0.1 ":irc.example.org FAKE irc.example.com :ok"))
+
+((nick 0.2 "NICK tester"))
+
+((user 0.2 "USER user 0 * :tester")
+ (0 ":irc.example.org 001 tester :Welcome to the Internet tester")
+ (0 ":irc.example.org 422 tester :MOTD File is missing"))
diff --git a/test/lisp/erc/resources/erc-d/resources/drop-a.eld b/test/lisp/erc/resources/erc-d/resources/drop-a.eld
new file mode 100644
index 00000000000..2e23eeb20ff
--- /dev/null
+++ b/test/lisp/erc/resources/erc-d/resources/drop-a.eld
@@ -0,0 +1,4 @@
+;; -*- mode: lisp-data; -*-
+((pass 1 "PASS " (? ?:) "a")
+ (0 "hi"))
+((drop 0.01 DROP))
diff --git a/test/lisp/erc/resources/erc-d/resources/drop-b.eld b/test/lisp/erc/resources/erc-d/resources/drop-b.eld
new file mode 100644
index 00000000000..facecd5e812
--- /dev/null
+++ b/test/lisp/erc/resources/erc-d/resources/drop-b.eld
@@ -0,0 +1,4 @@
+;; -*- mode: lisp-data; -*-
+((pass 1 "PASS " (? ?:) "b")
+ (0 "hi"))
+((linger 1 LINGER))
diff --git a/test/lisp/erc/resources/erc-d/resources/dynamic-barnet.eld b/test/lisp/erc/resources/erc-d/resources/dynamic-barnet.eld
new file mode 100644
index 00000000000..36b1cc23081
--- /dev/null
+++ b/test/lisp/erc/resources/erc-d/resources/dynamic-barnet.eld
@@ -0,0 +1,33 @@
+;;; -*- mode: lisp-data -*-
+((fake 0 "FAKE noop"))
+
+((nick 1.2 "NICK tester"))
+
+((user 2.2 "USER user 0 * :tester")
+ (0. ":irc.barnet.org 001 tester :Welcome to the BAR Network tester")
+ (0. ":irc.barnet.org 002 tester :Your host is irc.barnet.org")
+ (0. ":irc.barnet.org 003 tester :This server was created just now")
+ (0. ":irc.barnet.org 004 tester irc.barnet.org BERios CEIRabehiklmnoqstv Iabehkloqv")
+ (0. ":irc.barnet.org 005 tester MODES NETWORK=BarNet NICKLEN=32 PREFIX=(qaohv)~&@%+ :are supported by this server")
+ (0. ":irc.barnet.org 251 tester :There are 3 users and 0 invisible on 1 server(s)")
+ (0. ":irc.barnet.org 252 tester 0 :IRC Operators online")
+ (0. ":irc.barnet.org 253 tester 0 :unregistered connections")
+ (0. ":irc.barnet.org 254 tester 1 :channels formed")
+ (0. ":irc.barnet.org 255 tester :I have 3 clients and 0 servers")
+ (0. ":irc.barnet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0. ":irc.barnet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0. ":irc.barnet.org 422 tester :MOTD File is missing"))
+
+((mode-user 1.2 "MODE tester +i")
+ (0. ":irc.barnet.org 221 tester +Zi")
+ (0. ":irc.barnet.org 306 tester :You have been marked as being away")
+ (0 ":tester!~u@awyxgybtkx7uq.irc JOIN #chan")
+ (0 ":irc.barnet.org 353 joe = #chan :+joe!~joe@example.com @%+mike!~mike@example.org")
+ (0 ":irc.barnet.org 366 joe #chan :End of NAMES list"))
+
+((mode 1 "MODE #chan")
+ (0 ":irc.barnet.org 324 tester #chan +nt")
+ (0 ":irc.barnet.org 329 tester #chan 1620805269")
+ (0.1 ":joe!~u@awyxgybtkx7uq.irc PRIVMSG #chan :mike: Yes, a dozen; and as many to the vantage, as would store the world they played for.")
+ (0.05 ":mike!~u@awyxgybtkx7uq.irc PRIVMSG #chan :joe: As he regards his aged father's life.")
+ (0.05 ":joe!~u@awyxgybtkx7uq.irc PRIVMSG #chan :mike: It is a rupture that you may easily heal; and the cure of it not only saves your brother, but keeps you from dishonour in doing it."))
diff --git a/test/lisp/erc/resources/erc-d/resources/dynamic-foonet.eld b/test/lisp/erc/resources/erc-d/resources/dynamic-foonet.eld
new file mode 100644
index 00000000000..5dbea50f865
--- /dev/null
+++ b/test/lisp/erc/resources/erc-d/resources/dynamic-foonet.eld
@@ -0,0 +1,32 @@
+;;; -*- mode: lisp-data -*-
+
+((nick 1.2 "NICK tester"))
+
+((user 2.2 "USER user 0 * :tester")
+ (0. ":irc.foonet.org 001 tester :Welcome to the FOO Network tester")
+ (0. ":irc.foonet.org 002 tester :Your host is irc.foonet.org")
+ (0. ":irc.foonet.org 003 tester :This server was created just now")
+ (0. ":irc.foonet.org 004 tester irc.foonet.org BERios CEIRabehiklmnoqstv Iabehkloqv")
+ (0. ":irc.foonet.org 005 tester MODES NETWORK=FooNet NICKLEN=32 PREFIX=(qaohv)~&@%+ :are supported by this server")
+ (0. ":irc.foonet.org 251 tester :There are 3 users and 0 invisible on 1 server(s)")
+ (0. ":irc.foonet.org 252 tester 0 :IRC Operators online")
+ (0. ":irc.foonet.org 253 tester 0 :unregistered connections")
+ (0. ":irc.foonet.org 254 tester 1 :channels formed")
+ (0. ":irc.foonet.org 255 tester :I have 3 clients and 0 servers")
+ (0. ":irc.foonet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0. ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0. ":irc.foonet.org 422 tester :MOTD File is missing"))
+
+((mode-user 1.2 "MODE tester +i")
+ (0. ":irc.foonet.org 221 tester +Zi")
+ (0. ":irc.foonet.org 306 tester :You have been marked as being away")
+ (0 ":tester!~u@awyxgybtkx7uq.irc JOIN #chan")
+ (0 ":irc.foonet.org 353 alice = #chan :+alice!~alice@example.com @%+bob!~bob@example.org")
+ (0 ":irc.foonet.org 366 alice #chan :End of NAMES list"))
+
+((mode 2 "MODE #chan")
+ (0 ":irc.foonet.org 324 tester #chan +nt")
+ (0 ":irc.foonet.org 329 tester #chan 1620805269")
+ (0.1 ":alice!~u@awyxgybtkx7uq.irc PRIVMSG #chan :bob: Yes, a dozen; and as many to the vantage, as would store the world they played for.")
+ (0.05 ":bob!~u@awyxgybtkx7uq.irc PRIVMSG #chan :alice: As he regards his aged father's life.")
+ (0.05 ":alice!~u@awyxgybtkx7uq.irc PRIVMSG #chan :bob: It is a rupture that you may easily heal; and the cure of it not only saves your brother, but keeps you from dishonour in doing it."))
diff --git a/test/lisp/erc/resources/erc-d/resources/dynamic-stub.eld b/test/lisp/erc/resources/erc-d/resources/dynamic-stub.eld
new file mode 100644
index 00000000000..d93313023d0
--- /dev/null
+++ b/test/lisp/erc/resources/erc-d/resources/dynamic-stub.eld
@@ -0,0 +1,4 @@
+;;; -*- mode: lisp-data -*-
+((pass 10.0 "PASS " (? ?:) token ":changeme"))
+
+((fake 0 "FAKE"))
diff --git a/test/lisp/erc/resources/erc-d/resources/dynamic.eld b/test/lisp/erc/resources/erc-d/resources/dynamic.eld
new file mode 100644
index 00000000000..459b6e52bfe
--- /dev/null
+++ b/test/lisp/erc/resources/erc-d/resources/dynamic.eld
@@ -0,0 +1,30 @@
+;;; -*- mode: lisp-data -*-
+((pass 10.0 "PASS " (? ?:) "changeme"))
+((nick 2.2 "NICK tester"))
+
+((user 2.2 "USER " user " " (ignored digit "*") " :" realname)
+ (0.0 ":" dom " 001 " nick " :Welcome to the Internet Relay Network tester")
+ (0.0 ":" dom " 002 " nick " :Your host is " dom)
+ (0.0 ":" dom " 003 " nick " :This server was created just now")
+ (0.0 ":" dom " 004 " nick " " dom " BERios CEIRabehiklmnoqstv Iabehkloqv")
+ (0.0 ":" dom " 005 " nick " MODES NETWORK=ExampleOrg NICKLEN=32 PREFIX=(qaohv)~&@%+"
+ " :are supported by this server")
+ (0.0 ":" dom " 251 " nick " :There are 3 users and 0 invisible on 1 server(s)")
+ (0.0 ":" dom " 252 " nick " 0 :IRC Operators online")
+ (0.0 ":" dom " 253 " nick " 0 :unregistered connections")
+ (0.0 ":" dom " 254 " nick " 1 :channels formed")
+ (0.0 ":" dom " 255 " nick " :I have 3 clients and 0 servers")
+ (0.0 ":" dom " 265 " nick " 3 3 :Current local users 3, max 3")
+ (0.0 ":" dom " 266 " nick " 3 3 :Current global users 3, max 3")
+ (0.0 ":" dom " 422 " nick " :MOTD File is missing"))
+
+((mode-user 2.2 "MODE tester +i")
+ (0.0 ":" dom " 221 " nick " +Zi")
+
+ (0.0 ":" dom " 306 " nick " :You have been marked as being away")
+ (0.0 ":" nick "!~" nick "@localhost JOIN #chan")
+ (0.0 ":" dom " 353 alice = #chan :+alice!~alice@example.com @%+bob!~bob@example.org")
+ (0.0 ":" dom " 366 alice #chan :End of NAMES list"))
+
+((mode 2.2 "MODE #chan")
+ (0.1 ":bob!~bob@example.org PRIVMSG #chan :" nick ": hey"))
diff --git a/test/lisp/erc/resources/erc-d/resources/eof.eld b/test/lisp/erc/resources/erc-d/resources/eof.eld
new file mode 100644
index 00000000000..5da84b2e74f
--- /dev/null
+++ b/test/lisp/erc/resources/erc-d/resources/eof.eld
@@ -0,0 +1,33 @@
+;;; -*- mode: lisp-data -*-
+
+((pass 10.0 "PASS " (? ?:) "changeme"))
+((nick 0.2 "NICK tester"))
+
+((user 0.2 "USER user 0 * :tester")
+ (0 ":irc.example.org 001 tester :Welcome to the Internet Relay Network tester")
+ (0 ":irc.example.org 002 tester :Your host is irc.example.org")
+ (0 ":irc.example.org 003 tester :This server was created just now")
+ (0 ":irc.example.org 004 tester irc.example.org BERios CEIRabehiklmnoqstv Iabehkloqv")
+ (0 ":irc.example.org 005 tester MODES NETWORK=ExampleOrg NICKLEN=32 PREFIX=(qaohv)~&@%+"
+ " :are supported by this server")
+ (0 ":irc.example.org 251 tester :There are 3 users and 0 invisible on 1 server(s)")
+ ;; Just to mix thing's up (force handler to schedule timer)
+ (0.1 ":irc.example.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.example.org 253 tester 0 :unregistered connections")
+ (0 ":irc.example.org 254 tester 1 :channels formed")
+ (0 ":irc.example.org 255 tester :I have 3 clients and 0 servers")
+ (0 ":irc.example.org 265 tester 3 3 :Current local users 3, max 3")
+ (0 ":irc.example.org 266 tester 3 3 :Current global users 3, max 3")
+ (0 ":irc.example.org 422 tester :MOTD File is missing"))
+
+((mode-user 1.2 "MODE tester +i")
+ (0 ":irc.example.org 221 tester +Zi")
+ (0 ":irc.example.org 306 tester :You have been marked as being away")
+ (0 ":tester!~tester@localhost JOIN #chan")
+ (0 ":irc.example.org 353 alice = #chan :+alice!~alice@example.com @%+bob!~bob@example.org")
+ (0 ":irc.example.org 366 alice #chan :End of NAMES list"))
+
+((mode-chan 1.2 "MODE #chan")
+ (0.1 ":bob!~bob@example.org PRIVMSG #chan :hey"))
+
+((eof 1.0 EOF))
diff --git a/test/lisp/erc/resources/erc-d/resources/fuzzy.eld b/test/lisp/erc/resources/erc-d/resources/fuzzy.eld
new file mode 100644
index 00000000000..0504b6a6682
--- /dev/null
+++ b/test/lisp/erc/resources/erc-d/resources/fuzzy.eld
@@ -0,0 +1,42 @@
+;;; -*- mode: lisp-data -*-
+((pass 10.0 "PASS " (? ?:) "changeme"))
+((nick 0.2 "NICK tester"))
+
+((user 0.5 "USER user 0 * :tester")
+ (0.0 "@time=" now " :irc.org 001 tester :Welcome to the Internet Relay Network tester")
+ (0.0 "@time=" now " :irc.org 002 tester :Your host is irc.org")
+ (0.0 "@time=" now " :irc.org 003 tester :This server was created just now")
+ (0.0 "@time=" now " :irc.org 004 tester irc.org BERios CEIRabehiklmnoqstv Iabehkloqv")
+ (0.0 "@time=" now " :irc.org 005 tester MODES NETWORK=ExampleOrg NICKLEN=32 PREFIX=(qaohv)~&@%+ :are supported by this server")
+ (0.0 "@time=" now " :irc.org 251 tester :There are 3 users and 0 invisible on 1 server(s)")
+ (0.0 "@time=" now " :irc.org 252 tester 0 :IRC Operators online")
+ (0.0 "@time=" now " :irc.org 253 tester 0 :unregistered connections")
+ (0.0 "@time=" now " :irc.org 254 tester 1 :channels formed")
+ (0.0 "@time=" now " :irc.org 255 tester :I have 3 clients and 0 servers")
+ (0.0 "@time=" now " :irc.org 265 tester 3 3 :Current local users 3, max 3")
+ (0.0 "@time=" now " :irc.org 266 tester 3 3 :Current global users 3, max 3")
+ (0.0 "@time=" now " :irc.org 422 tester :MOTD File is missing"))
+
+((mode-user 1.2 "MODE tester +i")
+ (0.0 "@time=" now " :irc.org 221 tester +Zi")
+ (0.0 "@time=" now " :irc.org 306 tester :You have been marked as being away"))
+
+((~join-foo 3.2 "JOIN #foo")
+ (0 "@time=" now " :tester!~tester@localhost JOIN #foo")
+ (0 "@time=" now " :irc.example.org 353 alice = #foo :+alice!~alice@example.com @%+bob!~bob@example.org")
+ (0 "@time=" now " :irc.example.org 366 alice #foo :End of NAMES list"))
+
+((~join-bar 1.2 "JOIN #bar")
+ (0 "@time=" now " :tester!~tester@localhost JOIN #bar")
+ (0 "@time=" now " :irc.example.org 353 alice = #bar :+alice!~alice@example.com @%+bob!~bob@example.org")
+ (0 "@time=" now " :irc.example.org 366 alice #bar :End of NAMES list"))
+
+((~mode-foo 3.2 "MODE #foo")
+ (0.0 "@time=" now " :irc.example.org 324 tester #foo +Cint")
+ (0.0 "@time=" now " :irc.example.org 329 tester #foo 1519850102")
+ (0.1 "@time=" now " :bob!~bob@example.org PRIVMSG #foo :hey"))
+
+((mode-bar 10.2 "MODE #bar")
+ (0.0 "@time=" now " :irc.example.org 324 tester #bar +HMfnrt 50:5h :10:5")
+ (0.0 "@time=" now " :irc.example.org 329 tester #bar :1602642829")
+ (0.1 "@time=" now " :alice!~alice@example.com PRIVMSG #bar :hi"))
diff --git a/test/lisp/erc/resources/erc-d/resources/incremental.eld b/test/lisp/erc/resources/erc-d/resources/incremental.eld
new file mode 100644
index 00000000000..ab940fe6129
--- /dev/null
+++ b/test/lisp/erc/resources/erc-d/resources/incremental.eld
@@ -0,0 +1,43 @@
+;;; -*- mode: lisp-data -*-
+((pass 10.0 "PASS " (? ?:) "changeme"))
+((nick 0.2 "NICK tester"))
+
+((user 0.2 "USER user 0 * :tester")
+ (0.0 ":irc.foo.net 001 tester :Welcome to the Internet Relay Network tester")
+ (0.0 ":irc.foo.net 002 tester :Your host is irc.foo.net")
+ (0.0 ":irc.foo.net 003 tester :This server was created just now")
+ (0.0 ":irc.foo.net 004 tester irc.foo.net BERios CEIRabehiklmnoqstv Iabehkloqv")
+ (0.0 ":irc.foo.net 005 tester MODES NETWORK=FooNet NICKLEN=32 PREFIX=(qaohv)~&@%+"
+ " :are supported by this server")
+ (0.0 ":irc.foo.net 251 tester :There are 3 users and 0 invisible on 1 server(s)")
+ (0.0 ":irc.foo.net 252 tester 0 :IRC Operators online")
+ (0.0 ":irc.foo.net 253 tester 0 :unregistered connections")
+ (0.0 ":irc.foo.net 254 tester 1 :channels formed")
+ (0.0 ":irc.foo.net 255 tester :I have 3 clients and 0 servers")
+ (0.0 ":irc.foo.net 265 tester 3 3 :Current local users 3, max 3")
+ (0.0 ":irc.foo.net 266 tester 3 3 :Current global users 3, max 3")
+ (0.0 ":irc.foo.net 422 tester :MOTD File is missing"))
+
+((mode-user 1.2 "MODE tester +i")
+ (0.0 ":irc.foo.net 221 tester +Zi")
+ (0.0 ":irc.foo.net 306 tester :You have been marked as being away"))
+
+((join 3 "JOIN #foo")
+ (0 ":tester!~tester@localhost JOIN #foo")
+ (0 ":irc.foo.net 353 alice = #foo :+alice!~alice@example.com @%+bob!~bob@example.org")
+ (0 ":irc.foo.net 366 alice #foo :End of NAMES list"))
+
+((mode 3 "MODE #foo")
+ (0.0 ":irc.foo.net 324 tester #foo +Cint")
+ (0.0 ":irc.foo.net 329 tester #foo 1519850102")
+ (0.1 ":bob!~u@svpn88yjcdj42.irc PRIVMSG #foo :alice: But, in defence, by mercy, 'tis most just.")
+ (0.1 ":alice!~u@svpn88yjcdj42.irc PRIVMSG #foo :bob: Grows, lives, and dies, in single blessedness.")
+ (0.1 ":bob!~u@svpn88yjcdj42.irc PRIVMSG #foo :Look for me.")
+ (0.1 ":alice!~u@svpn88yjcdj42.irc PRIVMSG #foo :bob: By this hand, it will not kill a fly. But come, now I will be your Rosalind in a more coming-on disposition; and ask me what you will, I will grant it.")
+ (0.1 ":bob!~u@svpn88yjcdj42.irc PRIVMSG #foo :alice: That I must love a loathed enemy.")
+ (0.1 ":alice!~u@svpn88yjcdj42.irc PRIVMSG #foo :bob: As't please your lordship: I'll leave you.")
+ (0.1 ":bob!~u@svpn88yjcdj42.irc PRIVMSG #foo :alice: Then there is no true lover in the forest; else sighing every minute and groaning every hour would detect the lazy foot of Time as well as a clock.")
+ (0.1 ":alice!~u@svpn88yjcdj42.irc PRIVMSG #foo :bob: His discretion, I am sure, cannot carry his valour, for the goose carries not the fox. It is well: leave it to his discretion, and let us listen to the moon.")
+ (0.1 ":bob!~u@svpn88yjcdj42.irc PRIVMSG #foo :Done"))
+
+((hi 10 "PRIVMSG #foo :Hi"))
diff --git a/test/lisp/erc/resources/erc-d/resources/irc-parser-tests.eld b/test/lisp/erc/resources/erc-d/resources/irc-parser-tests.eld
new file mode 100644
index 00000000000..168569f5481
--- /dev/null
+++ b/test/lisp/erc/resources/erc-d/resources/irc-parser-tests.eld
@@ -0,0 +1,380 @@
+;;; -*- mode: lisp-data; -*-
+
+;; https://github.com/DanielOaks/irc-parser-tests
+((mask-match
+ (tests
+ ((mask . "*@127.0.0.1")
+ (matches "coolguy!ab@127.0.0.1" "cooldud3!~bc@127.0.0.1")
+ (fails "coolguy!ab@127.0.0.5" "cooldud3!~d@124.0.0.1"))
+ ((mask . "cool*@*")
+ (matches "coolguy!ab@127.0.0.1" "cooldud3!~bc@127.0.0.1" "cool132!ab@example.com")
+ (fails "koolguy!ab@127.0.0.5" "cooodud3!~d@124.0.0.1"))
+ ((mask . "cool!*@*")
+ (matches "cool!guyab@127.0.0.1" "cool!~dudebc@127.0.0.1" "cool!312ab@example.com")
+ (fails "coolguy!ab@127.0.0.1" "cooldud3!~bc@127.0.0.1" "koolguy!ab@127.0.0.5" "cooodud3!~d@124.0.0.1"))
+ ((mask . "cool!?username@*")
+ (matches "cool!ausername@127.0.0.1" "cool!~username@127.0.0.1")
+ (fails "cool!username@127.0.0.1"))
+ ((mask . "cool!a?*@*")
+ (matches "cool!ab@127.0.0.1" "cool!abc@127.0.0.1")
+ (fails "cool!a@127.0.0.1"))
+ ((mask . "cool[guy]!*@*")
+ (matches "cool[guy]!guy@127.0.0.1" "cool[guy]!a@example.com")
+ (fails "coolg!ab@127.0.0.1" "cool[!ac@127.0.1.1"))))
+ (msg-join
+ (tests
+ ((desc . "Simple test with verb and params.")
+ (atoms
+ (verb . "foo")
+ (params "bar" "baz" "asdf"))
+ (matches "foo bar baz asdf" "foo bar baz :asdf"))
+ ((desc . "Simple test with source and no params.")
+ (atoms
+ (source . "src")
+ (verb . "AWAY"))
+ (matches ":src AWAY"))
+ ((desc . "Simple test with source and empty trailing param.")
+ (atoms
+ (source . "src")
+ (verb . "AWAY")
+ (params ""))
+ (matches ":src AWAY :"))
+ ((desc . "Simple test with source.")
+ (atoms
+ (source . "coolguy")
+ (verb . "foo")
+ (params "bar" "baz" "asdf"))
+ (matches ":coolguy foo bar baz asdf" ":coolguy foo bar baz :asdf"))
+ ((desc . "Simple test with trailing param.")
+ (atoms
+ (verb . "foo")
+ (params "bar" "baz" "asdf quux"))
+ (matches "foo bar baz :asdf quux"))
+ ((desc . "Simple test with empty trailing param.")
+ (atoms
+ (verb . "foo")
+ (params "bar" "baz" ""))
+ (matches "foo bar baz :"))
+ ((desc . "Simple test with trailing param containing colon.")
+ (atoms
+ (verb . "foo")
+ (params "bar" "baz" ":asdf"))
+ (matches "foo bar baz ::asdf"))
+ ((desc . "Test with source and trailing param.")
+ (atoms
+ (source . "coolguy")
+ (verb . "foo")
+ (params "bar" "baz" "asdf quux"))
+ (matches ":coolguy foo bar baz :asdf quux"))
+ ((desc . "Test with trailing containing beginning+end whitespace.")
+ (atoms
+ (source . "coolguy")
+ (verb . "foo")
+ (params "bar" "baz" " asdf quux "))
+ (matches ":coolguy foo bar baz : asdf quux "))
+ ((desc . "Test with trailing containing what looks like another trailing param.")
+ (atoms
+ (source . "coolguy")
+ (verb . "PRIVMSG")
+ (params "bar" "lol :) "))
+ (matches ":coolguy PRIVMSG bar :lol :) "))
+ ((desc . "Simple test with source and empty trailing.")
+ (atoms
+ (source . "coolguy")
+ (verb . "foo")
+ (params "bar" "baz" ""))
+ (matches ":coolguy foo bar baz :"))
+ ((desc . "Trailing contains only spaces.")
+ (atoms
+ (source . "coolguy")
+ (verb . "foo")
+ (params "bar" "baz" " "))
+ (matches ":coolguy foo bar baz : "))
+ ((desc . "Param containing tab (tab is not considered SPACE for message splitting).")
+ (atoms
+ (source . "coolguy")
+ (verb . "foo")
+ (params "b ar" "baz"))
+ (matches ":coolguy foo b ar baz" ":coolguy foo b ar :baz"))
+ ((desc . "Tag with no value and space-filled trailing.")
+ (atoms
+ (tags
+ (asd . ""))
+ (source . "coolguy")
+ (verb . "foo")
+ (params "bar" "baz" " "))
+ (matches "@asd :coolguy foo bar baz : "))
+ ((desc . "Tags with escaped values.")
+ (atoms
+ (verb . "foo")
+ (tags
+ (a . "b\\and\nk")
+ (d . "gh;764")))
+ (matches "@a=b\\\\and\\nk;d=gh\\:764 foo" "@d=gh\\:764;a=b\\\\and\\nk foo"))
+ ((desc . "Tags with escaped values and params.")
+ (atoms
+ (verb . "foo")
+ (tags
+ (a . "b\\and\nk")
+ (d . "gh;764"))
+ (params "par1" "par2"))
+ (matches "@a=b\\\\and\\nk;d=gh\\:764 foo par1 par2" "@a=b\\\\and\\nk;d=gh\\:764 foo par1 :par2" "@d=gh\\:764;a=b\\\\and\\nk foo par1 par2" "@d=gh\\:764;a=b\\\\and\\nk foo par1 :par2"))
+ ((desc . "Tag with long, strange values (including LF and newline).")
+ (atoms
+ (tags
+ (foo . "\\\\;\\s \n"))
+ (verb . "COMMAND"))
+ (matches "@foo=\\\\\\\\\\:\\\\s\\s\\r\\n COMMAND"))))
+ (msg-split
+ (tests
+ ((input . "foo bar baz asdf")
+ (atoms
+ (verb . "foo")
+ (params "bar" "baz" "asdf")))
+ ((input . ":coolguy foo bar baz asdf")
+ (atoms
+ (source . "coolguy")
+ (verb . "foo")
+ (params "bar" "baz" "asdf")))
+ ((input . "foo bar baz :asdf quux")
+ (atoms
+ (verb . "foo")
+ (params "bar" "baz" "asdf quux")))
+ ((input . "foo bar baz :")
+ (atoms
+ (verb . "foo")
+ (params "bar" "baz" "")))
+ ((input . "foo bar baz ::asdf")
+ (atoms
+ (verb . "foo")
+ (params "bar" "baz" ":asdf")))
+ ((input . ":coolguy foo bar baz :asdf quux")
+ (atoms
+ (source . "coolguy")
+ (verb . "foo")
+ (params "bar" "baz" "asdf quux")))
+ ((input . ":coolguy foo bar baz : asdf quux ")
+ (atoms
+ (source . "coolguy")
+ (verb . "foo")
+ (params "bar" "baz" " asdf quux ")))
+ ((input . ":coolguy PRIVMSG bar :lol :) ")
+ (atoms
+ (source . "coolguy")
+ (verb . "PRIVMSG")
+ (params "bar" "lol :) ")))
+ ((input . ":coolguy foo bar baz :")
+ (atoms
+ (source . "coolguy")
+ (verb . "foo")
+ (params "bar" "baz" "")))
+ ((input . ":coolguy foo bar baz : ")
+ (atoms
+ (source . "coolguy")
+ (verb . "foo")
+ (params "bar" "baz" " ")))
+ ((input . "@a=b;c=32;k;rt=ql7 foo")
+ (atoms
+ (verb . "foo")
+ (tags
+ (a . "b")
+ (c . "32")
+ (k . "")
+ (rt . "ql7"))))
+ ((input . "@a=b\\\\and\\nk;c=72\\s45;d=gh\\:764 foo")
+ (atoms
+ (verb . "foo")
+ (tags
+ (a . "b\\and\nk")
+ (c . "72 45")
+ (d . "gh;764"))))
+ ((input . "@c;h=;a=b :quux ab cd")
+ (atoms
+ (tags
+ (c . "")
+ (h . "")
+ (a . "b"))
+ (source . "quux")
+ (verb . "ab")
+ (params "cd")))
+ ((input . ":src JOIN #chan")
+ (atoms
+ (source . "src")
+ (verb . "JOIN")
+ (params "#chan")))
+ ((input . ":src JOIN :#chan")
+ (atoms
+ (source . "src")
+ (verb . "JOIN")
+ (params "#chan")))
+ ((input . ":src AWAY")
+ (atoms
+ (source . "src")
+ (verb . "AWAY")))
+ ((input . ":src AWAY ")
+ (atoms
+ (source . "src")
+ (verb . "AWAY")))
+ ((input . ":cool guy foo bar baz")
+ (atoms
+ (source . "cool guy")
+ (verb . "foo")
+ (params "bar" "baz")))
+ ((input . ":coolguy!ag@net5work.admin PRIVMSG foo :bar baz")
+ (atoms
+ (source . "coolguy!ag@net5work.admin")
+ (verb . "PRIVMSG")
+ (params "foo" "bar baz")))
+ ((input . ":coolguy!~ag@net05work.admin PRIVMSG foo :bar baz")
+ (atoms
+ (source . "coolguy!~ag@net05work.admin")
+ (verb . "PRIVMSG")
+ (params "foo" "bar baz")))
+ ((input . "@tag1=value1;tag2;vendor1/tag3=value2;vendor2/tag4= :irc.example.com COMMAND param1 param2 :param3 param3")
+ (atoms
+ (tags
+ (tag1 . "value1")
+ (tag2 . "")
+ (vendor1/tag3 . "value2")
+ (vendor2/tag4 . ""))
+ (source . "irc.example.com")
+ (verb . "COMMAND")
+ (params "param1" "param2" "param3 param3")))
+ ((input . ":irc.example.com COMMAND param1 param2 :param3 param3")
+ (atoms
+ (source . "irc.example.com")
+ (verb . "COMMAND")
+ (params "param1" "param2" "param3 param3")))
+ ((input . "@tag1=value1;tag2;vendor1/tag3=value2;vendor2/tag4 COMMAND param1 param2 :param3 param3")
+ (atoms
+ (tags
+ (tag1 . "value1")
+ (tag2 . "")
+ (vendor1/tag3 . "value2")
+ (vendor2/tag4 . ""))
+ (verb . "COMMAND")
+ (params "param1" "param2" "param3 param3")))
+ ((input . "COMMAND")
+ (atoms
+ (verb . "COMMAND")))
+ ((input . "@foo=\\\\\\\\\\:\\\\s\\s\\r\\n COMMAND")
+ (atoms
+ (tags
+ (foo . "\\\\;\\s \n"))
+ (verb . "COMMAND")))
+ ((input . ":gravel.mozilla.org 432 #momo :Erroneous Nickname: Illegal characters")
+ (atoms
+ (source . "gravel.mozilla.org")
+ (verb . "432")
+ (params "#momo" "Erroneous Nickname: Illegal characters")))
+ ((input . ":gravel.mozilla.org MODE #tckk +n ")
+ (atoms
+ (source . "gravel.mozilla.org")
+ (verb . "MODE")
+ (params "#tckk" "+n")))
+ ((input . ":services.esper.net MODE #foo-bar +o foobar ")
+ (atoms
+ (source . "services.esper.net")
+ (verb . "MODE")
+ (params "#foo-bar" "+o" "foobar")))
+ ((input . "@tag1=value\\\\ntest COMMAND")
+ (atoms
+ (tags
+ (tag1 . "value\\ntest"))
+ (verb . "COMMAND")))
+ ((input . "@tag1=value\\1 COMMAND")
+ (atoms
+ (tags
+ (tag1 . "value1"))
+ (verb . "COMMAND")))
+ ((input . "@tag1=value1\\ COMMAND")
+ (atoms
+ (tags
+ (tag1 . "value1"))
+ (verb . "COMMAND")))
+ ((input . "@tag1=1;tag2=3;tag3=4;tag1=5 COMMAND")
+ (atoms
+ (tags
+ (tag1 . "5")
+ (tag2 . "3")
+ (tag3 . "4"))
+ (verb . "COMMAND")))
+ ((input . "@tag1=1;tag2=3;tag3=4;tag1=5;vendor/tag2=8 COMMAND")
+ (atoms
+ (tags
+ (tag1 . "5")
+ (tag2 . "3")
+ (tag3 . "4")
+ (vendor/tag2 . "8"))
+ (verb . "COMMAND")))
+ ((input . ":SomeOp MODE #channel :+i")
+ (atoms
+ (source . "SomeOp")
+ (verb . "MODE")
+ (params "#channel" "+i")))
+ ((input . ":SomeOp MODE #channel +oo SomeUser :AnotherUser")
+ (atoms
+ (source . "SomeOp")
+ (verb . "MODE")
+ (params "#channel" "+oo" "SomeUser" "AnotherUser")))))
+ (userhost-split
+ (tests
+ ((source . "coolguy")
+ (atoms
+ (nick . "coolguy")))
+ ((source . "coolguy!ag@127.0.0.1")
+ (atoms
+ (nick . "coolguy")
+ (user . "ag")
+ (host . "127.0.0.1")))
+ ((source . "coolguy!~ag@localhost")
+ (atoms
+ (nick . "coolguy")
+ (user . "~ag")
+ (host . "localhost")))
+ ((source . "coolguy@127.0.0.1")
+ (atoms
+ (nick . "coolguy")
+ (host . "127.0.0.1")))
+ ((source . "coolguy!ag")
+ (atoms
+ (nick . "coolguy")
+ (user . "ag")))
+ ((source . "coolguy!ag@net5work.admin")
+ (atoms
+ (nick . "coolguy")
+ (user . "ag")
+ (host . "net5work.admin")))
+ ((source . "coolguy!~ag@net05work.admin")
+ (atoms
+ (nick . "coolguy")
+ (user . "~ag")
+ (host . "net05work.admin")))))
+ (validate-hostname
+ (tests
+ ((host . "irc.example.com")
+ (valid . t))
+ ((host . "i.coolguy.net")
+ (valid . t))
+ ((host . "irc-srv.net.uk")
+ (valid . t))
+ ((host . "iRC.CooLguY.NeT")
+ (valid . t))
+ ((host . "gsf.ds342.co.uk")
+ (valid . t))
+ ((host . "324.net.uk")
+ (valid . t))
+ ((host . "xn--bcher-kva.ch")
+ (valid . t))
+ ((host . "-lol-.net.uk")
+ (valid . :false))
+ ((host . "-lol.net.uk")
+ (valid . :false))
+ ((host . "_irc._sctp.lol.net.uk")
+ (valid . :false))
+ ((host . "irc")
+ (valid . :false))
+ ((host . "com")
+ (valid . :false))
+ ((host . "")
+ (valid . :false)))))
diff --git a/test/lisp/erc/resources/erc-d/resources/linger-multi-a.eld b/test/lisp/erc/resources/erc-d/resources/linger-multi-a.eld
new file mode 100644
index 00000000000..751500537d9
--- /dev/null
+++ b/test/lisp/erc/resources/erc-d/resources/linger-multi-a.eld
@@ -0,0 +1,3 @@
+;; -*- mode: lisp-data; -*-
+((pass 1 "PASS " (? ?:) "a"))
+((linger 100 LINGER)) \ No newline at end of file
diff --git a/test/lisp/erc/resources/erc-d/resources/linger-multi-b.eld b/test/lisp/erc/resources/erc-d/resources/linger-multi-b.eld
new file mode 100644
index 00000000000..c906c9e649b
--- /dev/null
+++ b/test/lisp/erc/resources/erc-d/resources/linger-multi-b.eld
@@ -0,0 +1,3 @@
+;; -*- mode: lisp-data; -*-
+((pass 1 "PASS " (? ?:) "b"))
+((linger 1 LINGER))
diff --git a/test/lisp/erc/resources/erc-d/resources/linger.eld b/test/lisp/erc/resources/erc-d/resources/linger.eld
new file mode 100644
index 00000000000..36c81a3af4b
--- /dev/null
+++ b/test/lisp/erc/resources/erc-d/resources/linger.eld
@@ -0,0 +1,33 @@
+;;; -*- mode: lisp-data -*-
+
+((pass 10.0 "PASS " (? ?:) "changeme"))
+((nick 0.2 "NICK tester"))
+
+((user 0.2 "USER user 0 * :tester")
+ (0 ":irc.example.org 001 tester :Welcome to the Internet Relay Network tester")
+ (0 ":irc.example.org 002 tester :Your host is irc.example.org")
+ (0 ":irc.example.org 003 tester :This server was created just now")
+ (0 ":irc.example.org 004 tester irc.example.org BERios CEIRabehiklmnoqstv Iabehkloqv")
+ (0 ":irc.example.org 005 tester MODES NETWORK=ExampleOrg NICKLEN=32 PREFIX=(qaohv)~&@%+"
+ " :are supported by this server")
+ (0 ":irc.example.org 251 tester :There are 3 users and 0 invisible on 1 server(s)")
+ ;; Just to mix thing's up (force handler to schedule timer)
+ (0.1 ":irc.example.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.example.org 253 tester 0 :unregistered connections")
+ (0 ":irc.example.org 254 tester 1 :channels formed")
+ (0 ":irc.example.org 255 tester :I have 3 clients and 0 servers")
+ (0 ":irc.example.org 265 tester 3 3 :Current local users 3, max 3")
+ (0 ":irc.example.org 266 tester 3 3 :Current global users 3, max 3")
+ (0 ":irc.example.org 422 tester :MOTD File is missing"))
+
+((mode-user 1.2 "MODE tester +i")
+ (0 ":irc.example.org 221 tester +Zi")
+ (0 ":irc.example.org 306 tester :You have been marked as being away")
+ (0 ":tester!~tester@localhost JOIN #chan")
+ (0 ":irc.example.org 353 alice = #chan :+alice!~alice@example.com @%+bob!~bob@example.org")
+ (0 ":irc.example.org 366 alice #chan :End of NAMES list"))
+
+((mode-chan 1.2 "MODE #chan")
+ (0 ":bob!~bob@example.org PRIVMSG #chan :hey"))
+
+((linger 1.0 LINGER))
diff --git a/test/lisp/erc/resources/erc-d/resources/no-block.eld b/test/lisp/erc/resources/erc-d/resources/no-block.eld
new file mode 100644
index 00000000000..1b1f3965637
--- /dev/null
+++ b/test/lisp/erc/resources/erc-d/resources/no-block.eld
@@ -0,0 +1,55 @@
+;;; -*- mode: lisp-data -*-
+((pass 10.0 "PASS " (? ?:) "changeme"))
+((nick 0.2 "NICK tester"))
+
+((user 0.2 "USER user 0 * :tester")
+ (0.0 ":irc.org 001 tester :Welcome to the Internet Relay Network tester")
+ (0.0 ":irc.org 002 tester :Your host is irc.org")
+ (0.0 ":irc.org 003 tester :This server was created just now")
+ (0.0 ":irc.org 004 tester irc.org BERios CEIRabehiklmnoqstv Iabehkloqv")
+ (0.0 ":irc.org 005 tester MODES NETWORK=ExampleOrg NICKLEN=32 PREFIX=(qaohv)~&@%+"
+ " :are supported by this server")
+ (0.0 ":irc.org 251 tester :There are 3 users and 0 invisible on 1 server(s)")
+ (0.0 ":irc.org 252 tester 0 :IRC Operators online")
+ (0.0 ":irc.org 253 tester 0 :unregistered connections")
+ (0.0 ":irc.org 254 tester 1 :channels formed")
+ (0.0 ":irc.org 255 tester :I have 3 clients and 0 servers")
+ (0.0 ":irc.org 265 tester 3 3 :Current local users 3, max 3")
+ (0.0 ":irc.org 266 tester 3 3 :Current global users 3, max 3")
+ (0.0 ":irc.org 422 tester :MOTD File is missing"))
+
+((mode-user 1.2 "MODE tester +i")
+ (0.0 ":irc.org 221 tester +Zi")
+ (0.0 ":irc.org 306 tester :You have been marked as being away"))
+
+((join-foo 1.2 "JOIN #foo")
+ (0 ":tester!~tester@localhost JOIN #foo")
+ (0 ":irc.example.org 353 alice = #foo :+alice!~alice@example.com @%+bob!~bob@example.org")
+ (0 ":irc.example.org 366 alice #foo :End of NAMES list"))
+
+;; This would time out if the mode-foo's outgoing blocked (remove minus signs to see)
+((~join-bar 1.5 "JOIN #bar")
+ (0 ":tester!~tester@localhost JOIN #bar")
+ (0 ":irc.example.org 353 alice = #bar :+alice!~alice@example.com @%+bob!~bob@example.org")
+ (0 ":irc.example.org 366 alice #bar :End of NAMES list"))
+
+((mode-foo 1.2 "MODE #foo")
+ (0.0 ":irc.example.org 324 tester #foo +Cint")
+ (0.0 ":irc.example.org 329 tester #foo 1519850102")
+ (-0.1 ":bob!~u@svpn88yjcdj42.irc PRIVMSG #foo :alice: But, in defence, by mercy, 'tis most just.")
+ (-0.2 ":alice!~u@svpn88yjcdj42.irc PRIVMSG #foo :bob: Grows, lives, and dies, in single blessedness.")
+ (-0.3 ":bob!~u@svpn88yjcdj42.irc PRIVMSG #foo :alice: For these two hours, Rosalind, I will leave thee.")
+ (-0.4 ":alice!~u@svpn88yjcdj42.irc PRIVMSG #foo :bob: By this hand, it will not kill a fly. But come, now I will be your Rosalind in a more coming-on disposition; and ask me what you will, I will grant it.")
+ (-0.5 ":bob!~u@svpn88yjcdj42.irc PRIVMSG #foo :alice: That I must love a loathed enemy.")
+ (-0.6 ":alice!~u@svpn88yjcdj42.irc PRIVMSG #foo :bob: As't please your lordship: I'll leave you.")
+ (-0.7 ":bob!~u@svpn88yjcdj42.irc PRIVMSG #foo :alice: Then there is no true lover in the forest; else sighing every minute and groaning every hour would detect the lazy foot of Time as well as a clock.")
+ (-0.8 ":alice!~u@svpn88yjcdj42.irc PRIVMSG #foo :bob: His discretion, I am sure, cannot carry his valour, for the goose carries not the fox. It is well: leave it to his discretion, and let us listen to the moon.")
+ (-0.9 ":bob!~u@svpn88yjcdj42.irc PRIVMSG #foo :alice: As living here and you no use of him.")
+ (-1.0 ":alice!~u@svpn88yjcdj42.irc PRIVMSG #foo :bob: If there be truth in sight, you are my Rosalind.")
+ (-1.1 ":bob!~u@svpn88yjcdj42.irc PRIVMSG #foo :alice: That is another's lawful promis'd love.")
+ (-1.1 ":bob!~u@svpn88yjcdj42.irc PRIVMSG #foo :I am heard."))
+
+((mode-bar 1.5 "MODE #bar")
+ (0.0 ":irc.example.org 324 tester #bar +HMfnrt 50:5h :10:5")
+ (0.0 ":irc.example.org 329 tester #bar :1602642829")
+ (0.1 ":alice!~alice@example.com PRIVMSG #bar :hi 123"))
diff --git a/test/lisp/erc/resources/erc-d/resources/no-match.eld b/test/lisp/erc/resources/erc-d/resources/no-match.eld
new file mode 100644
index 00000000000..d147be1e084
--- /dev/null
+++ b/test/lisp/erc/resources/erc-d/resources/no-match.eld
@@ -0,0 +1,32 @@
+;;; -*- mode: lisp-data -*-
+
+((pass 10.0 "PASS " (? ?:) "changeme"))
+((nick 0.2 "NICK tester"))
+
+((user 0.2 "USER user 0 * :tester")
+ (0 ":irc.example.org 001 tester :Welcome to the Internet Relay Network tester")
+ (0 ":irc.example.org 002 tester :Your host is irc.example.org")
+ (0 ":irc.example.org 003 tester :This server was created just now")
+ (0 ":irc.example.org 004 tester irc.example.org BERios CEIRabehiklmnoqstv Iabehkloqv")
+ (0 ":irc.example.org 005 tester MODES NETWORK=ExampleOrg NICKLEN=32 PREFIX=(qaohv)~&@%+"
+ " :are supported by this server")
+ (0 ":irc.example.org 251 tester :There are 3 users and 0 invisible on 1 server(s)")
+ (0 ":irc.example.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.example.org 253 tester 0 :unregistered connections")
+ (0 ":irc.example.org 254 tester 1 :channels formed")
+ (0 ":irc.example.org 255 tester :I have 3 clients and 0 servers")
+ (0 ":irc.example.org 265 tester 3 3 :Current local users 3, max 3")
+ (0 ":irc.example.org 266 tester 3 3 :Current global users 3, max 3")
+ (0 ":irc.example.org 422 tester :MOTD File is missing"))
+
+((mode-user 1.2 "MODE tester +i")
+ (0 ":irc.example.org 221 tester +Zi")
+ (0 ":irc.example.org 306 tester :You have been marked as being away"))
+
+((join 1.2 "JOIN #chan")
+ (0 ":tester!~tester@localhost JOIN #chan")
+ (0 ":irc.example.org 353 alice = #chan :+alice!~alice@example.com @%+bob!~bob@example.org")
+ (0 ":irc.example.org 366 alice #chan :End of NAMES list"))
+
+((mode-chan 0.2 "MODE #chan")
+ (0.1 ":bob!~bob@example.org PRIVMSG #chan :hey"))
diff --git a/test/lisp/erc/resources/erc-d/resources/no-pong.eld b/test/lisp/erc/resources/erc-d/resources/no-pong.eld
new file mode 100644
index 00000000000..30cd805d76c
--- /dev/null
+++ b/test/lisp/erc/resources/erc-d/resources/no-pong.eld
@@ -0,0 +1,27 @@
+;;; -*- mode: lisp-data -*-
+
+((pass 10.0 "PASS " (? ?:) "changeme"))
+((nick 0.2 "NICK tester"))
+
+((~ping 1.2 "PING " nonce)
+ (0.1 ":irc.example.org PONG irc.example.com " echo))
+
+((user 0.2 "USER user 0 * :tester")
+ (0 ":irc.example.org 001 tester :Welcome to the Internet Relay Network tester")
+ (0 ":irc.example.org 002 tester :Your host is irc.example.org")
+ (0 ":irc.example.org 003 tester :This server was created just now")
+ (0 ":irc.example.org 004 tester irc.example.org BERios CEIRabehiklmnoqstv Iabehkloqv")
+ (0 ":irc.example.org 005 tester MODES NETWORK=ExampleOrg NICKLEN=32 PREFIX=(qaohv)~&@%+"
+ " :are supported by this server")
+ (0 ":irc.example.org 251 tester :There are 3 users and 0 invisible on 1 server(s)")
+ (0 ":irc.example.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.example.org 253 tester 0 :unregistered connections")
+ (0 ":irc.example.org 254 tester 1 :channels formed")
+ (0 ":irc.example.org 255 tester :I have 3 clients and 0 servers")
+ (0 ":irc.example.org 265 tester 3 3 :Current local users 3, max 3")
+ (0 ":irc.example.org 266 tester 3 3 :Current global users 3, max 3")
+ (0 ":irc.example.org 422 tester :MOTD File is missing"))
+
+((mode-user 1.2 "MODE tester +i")
+ (0 ":irc.example.org 221 tester +Zi")
+ (0 ":irc.example.org 306 tester :You have been marked as being away"))
diff --git a/test/lisp/erc/resources/erc-d/resources/nonstandard.eld b/test/lisp/erc/resources/erc-d/resources/nonstandard.eld
new file mode 100644
index 00000000000..c9cd608e6be
--- /dev/null
+++ b/test/lisp/erc/resources/erc-d/resources/nonstandard.eld
@@ -0,0 +1,6 @@
+;;; -*- mode: lisp-data -*-
+((one 1 "ONE one"))
+((two 1 "TWO two"))
+((blank 1 ""))
+((one-space 1 " "))
+((two-spaces 1 " "))
diff --git a/test/lisp/erc/resources/erc-d/resources/proxy-barnet.eld b/test/lisp/erc/resources/erc-d/resources/proxy-barnet.eld
new file mode 100644
index 00000000000..e74d20d5b37
--- /dev/null
+++ b/test/lisp/erc/resources/erc-d/resources/proxy-barnet.eld
@@ -0,0 +1,24 @@
+;;; -*- mode: lisp-data -*-
+
+((pass 10.0 "PASS " (? ?:) network ":changeme"))
+((nick 1.2 "NICK tester"))
+
+((user 1.2 "USER user 0 * :tester")
+ (0.001 ":" fqdn " 001 tester :Welcome to the BAR Network tester")
+ (0.002 ":" fqdn " 002 tester :Your host is " fqdn)
+ (0.003 ":" fqdn " 003 tester :This server was created just now")
+ (0.004 ":" fqdn " 004 tester " fqdn " BERios CEIRabehiklmnoqstv Iabehkloqv")
+ (0.005 ":" fqdn " 005 tester MODES NETWORK=" net " NICKLEN=32 PREFIX=(qaohv)~&@%+"
+ " :are supported by this server")
+ (0.006 ":" fqdn " 251 tester :There are 3 users and 0 invisible on 1 server(s)")
+ (0.007 ":" fqdn " 252 tester 0 :IRC Operators online")
+ (0.008 ":" fqdn " 253 tester 0 :unregistered connections")
+ (0.009 ":" fqdn " 254 tester 1 :channels formed")
+ (0.010 ":" fqdn " 255 tester :I have 3 clients and 0 servers")
+ (0.011 ":" fqdn " 265 tester 3 3 :Current local users 3, max 3")
+ (0.012 ":" fqdn " 266 tester 3 3 :Current global users 3, max 3")
+ (0.013 ":" fqdn " 422 tester :MOTD File is missing"))
+
+((mode-user 1.2 "MODE tester +i")
+ (0.014 ":" fqdn " 221 tester +Zi")
+ (0.015 ":" fqdn " 306 tester :You have been marked as being away"))
diff --git a/test/lisp/erc/resources/erc-d/resources/proxy-foonet.eld b/test/lisp/erc/resources/erc-d/resources/proxy-foonet.eld
new file mode 100644
index 00000000000..cc2e9d253c1
--- /dev/null
+++ b/test/lisp/erc/resources/erc-d/resources/proxy-foonet.eld
@@ -0,0 +1,24 @@
+;;; -*- mode: lisp-data -*-
+
+((pass 10.0 "PASS " (? ?:) network ":changeme"))
+((nick 1.2 "NICK tester"))
+
+((user 2.2 "USER user 0 * :tester")
+ (0.015 ":" fqdn " 001 tester :Welcome to the FOO Network tester")
+ (0.014 ":" fqdn " 002 tester :Your host is " fqdn)
+ (0.013 ":" fqdn " 003 tester :This server was created just now")
+ (0.012 ":" fqdn " 004 tester " fqdn " BERios CEIRabehiklmnoqstv Iabehkloqv")
+ (0.011 ":" fqdn " 005 tester MODES NETWORK=" net " NICKLEN=32 PREFIX=(qaohv)~&@%+"
+ " :are supported by this server")
+ (0.010 ":" fqdn " 251 tester :There are 3 users and 0 invisible on 1 server(s)")
+ (0.009 ":" fqdn " 252 tester 0 :IRC Operators online")
+ (0.008 ":" fqdn " 253 tester 0 :unregistered connections")
+ (0.007 ":" fqdn " 254 tester 1 :channels formed")
+ (0.006 ":" fqdn " 255 tester :I have 3 clients and 0 servers")
+ (0.005 ":" fqdn " 265 tester 3 3 :Current local users 3, max 3")
+ (0.004 ":" fqdn " 266 tester 3 3 :Current global users 3, max 3")
+ (0.003 ":" fqdn " 422 tester :MOTD File is missing"))
+
+((mode-user 1.2 "MODE tester +i")
+ (0.002 ":" fqdn " 221 tester +Zi")
+ (0.001 ":" fqdn " 306 tester :You have been marked as being away"))
diff --git a/test/lisp/erc/resources/erc-d/resources/proxy-solo.eld b/test/lisp/erc/resources/erc-d/resources/proxy-solo.eld
new file mode 100644
index 00000000000..af216c80edc
--- /dev/null
+++ b/test/lisp/erc/resources/erc-d/resources/proxy-solo.eld
@@ -0,0 +1,9 @@
+;;; -*- mode: lisp-data -*-
+
+((pass 10.0 "PASS " (? ?:) "changeme"))
+((nick 0.2 "NICK tester"))
+
+((user 0.2 "USER user 0 * :" (group (+ alpha)) eos)
+ (0 ":*status!znc@znc.in NOTICE " nick " :You have no networks configured."
+ " Use /znc AddNetwork <network> to add one.")
+ (0 ":irc.znc.in 001 " nick " :Welcome " nick "!"))
diff --git a/test/lisp/erc/resources/erc-d/resources/proxy-subprocess.el b/test/lisp/erc/resources/erc-d/resources/proxy-subprocess.el
new file mode 100644
index 00000000000..bb8869dff69
--- /dev/null
+++ b/test/lisp/erc/resources/erc-d/resources/proxy-subprocess.el
@@ -0,0 +1,45 @@
+;;; proxy-subprocess.el --- Example setup file for erc-d -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2020-2022 Free Software Foundation, Inc.
+;;
+;; This file is part of GNU Emacs.
+;;
+;; This program is free software: you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation, either version 3 of the
+;; License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see
+;; <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;; Code:
+
+(defvar erc-d-tmpl-vars)
+
+(setq erc-d-tmpl-vars
+
+ (list
+ (cons 'fqdn (lambda (helper)
+ (let ((name (funcall helper :dialog-name)))
+ (funcall helper :set
+ (if (eq name 'proxy-foonet)
+ "irc.foo.net"
+ "irc.bar.net")))))
+
+ (cons 'net (lambda (helper)
+ (let ((name (funcall helper :dialog-name)))
+ (funcall helper :set
+ (if (eq name 'proxy-foonet)
+ "FooNet"
+ "BarNet")))))
+
+ (cons 'network '(group (+ alpha)))))
+
+;;; proxy-subprocess.el ends here
diff --git a/test/lisp/erc/resources/erc-d/resources/timeout.eld b/test/lisp/erc/resources/erc-d/resources/timeout.eld
new file mode 100644
index 00000000000..9cfad4fa8cd
--- /dev/null
+++ b/test/lisp/erc/resources/erc-d/resources/timeout.eld
@@ -0,0 +1,27 @@
+;;; -*- mode: lisp-data -*-
+
+((pass 10.0 "PASS " (? ?:) "changeme"))
+((nick 0.2 "NICK tester"))
+
+((user 0.2 "USER user 0 * :tester")
+ (0 ":irc.example.org 001 tester :Welcome to the Internet Relay Network tester")
+ (0 ":irc.example.org 002 tester :Your host is irc.example.org")
+ (0 ":irc.example.org 003 tester :This server was created just now")
+ (0 ":irc.example.org 004 tester irc.example.org BERios CEIRabehiklmnoqstv Iabehkloqv")
+ (0 ":irc.example.org 005 tester MODES NETWORK=ExampleOrg NICKLEN=32 PREFIX=(qaohv)~&@%+"
+ " :are supported by this server")
+ (0 ":irc.example.org 251 tester :There are 3 users and 0 invisible on 1 server(s)")
+ (0 ":irc.example.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.example.org 253 tester 0 :unregistered connections")
+ (0 ":irc.example.org 254 tester 1 :channels formed")
+ (0 ":irc.example.org 255 tester :I have 3 clients and 0 servers")
+ (0 ":irc.example.org 265 tester 3 3 :Current local users 3, max 3")
+ (0 ":irc.example.org 266 tester 3 3 :Current global users 3, max 3")
+ (0 ":irc.example.org 422 tester :MOTD File is missing"))
+
+((mode-user 1.2 "MODE tester +i")
+ (0 ":irc.example.org 221 tester +Zi")
+ (0 ":irc.example.org 306 tester :You have been marked as being away"))
+
+((mode 0.2 "MODE #chan")
+ (0.1 ":bob!~bob@example.org PRIVMSG #chan :hey"))
diff --git a/test/lisp/erc/resources/erc-d/resources/unexpected.eld b/test/lisp/erc/resources/erc-d/resources/unexpected.eld
new file mode 100644
index 00000000000..ac0a8fecfa6
--- /dev/null
+++ b/test/lisp/erc/resources/erc-d/resources/unexpected.eld
@@ -0,0 +1,28 @@
+;;; -*- mode: lisp-data -*-
+((t 10.0 "PASS " (? ?:) "changeme"))
+((t 0.2 "NICK tester"))
+
+((t 0.2 "USER user 0 * :tester")
+ (0.0 ":irc.example.org 001 tester :Welcome to the Internet Relay Network tester")
+ (0.0 ":irc.example.org 002 tester :Your host is irc.example.org")
+ (0.0 ":irc.example.org 003 tester :This server was created just now")
+ (0.0 ":irc.example.org 004 tester irc.example.org BERios CEIRabehiklmnoqstv Iabehkloqv")
+ (0.0 ":irc.example.org 005 tester MODES NETWORK=ExampleOrg NICKLEN=32 PREFIX=(qaohv)~&@%+"
+ " :are supported by this server")
+ (0.0 ":irc.example.org 251 tester :There are 3 users and 0 invisible on 1 server(s)")
+ (0.0 ":irc.example.org 252 tester 0 :IRC Operators online")
+ (0.0 ":irc.example.org 253 tester 0 :unregistered connections")
+ (0.0 ":irc.example.org 254 tester 1 :channels formed")
+ (0.0 ":irc.example.org 255 tester :I have 3 clients and 0 servers")
+ (0.0 ":irc.example.org 265 tester 3 3 :Current local users 3, max 3")
+ (0.0 ":irc.example.org 266 tester 3 3 :Current global users 3, max 3")
+ (0.0 ":irc.example.org 422 tester :MOTD File is missing"))
+
+((mode-user 1.2 "MODE tester +i")
+ (0.0 ":irc.example.org 221 tester +Zi")
+
+ (0.0 ":irc.example.org 306 tester :You have been marked as being away")
+ (0.0 ":tester!~tester@localhost JOIN #chan")
+ (0.0 ":irc.example.org 353 alice = #chan :+alice!~alice@example.com @%+bob!~bob@example.org")
+ (0.0 ":irc.example.org 366 alice #chan :End of NAMES list")
+ (0.1 ":bob!~bob@example.org PRIVMSG #chan :hey"))
diff --git a/test/lisp/erc/resources/erc-scenarios-common.el b/test/lisp/erc/resources/erc-scenarios-common.el
new file mode 100644
index 00000000000..cbabfcd26be
--- /dev/null
+++ b/test/lisp/erc/resources/erc-scenarios-common.el
@@ -0,0 +1,516 @@
+;;; erc-scenarios-common.el --- Common helpers for ERC scenarios -*- lexical-binding: t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+;;
+;; This file is part of GNU Emacs.
+;;
+;; This program is free software: you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation, either version 3 of the
+;; License, or (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see
+;; <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; These are e2e-ish test cases primarily intended to assert core,
+;; fundamental behavior expected of any modern IRC client. Tests may
+;; also simulate specific scenarios drawn from bug reports. Incoming
+;; messages are provided by playback scripts resembling I/O logs. In
+;; place of time stamps, they have time deltas, which are used to
+;; govern the test server in a fashion reminiscent of music rolls (or
+;; the script(1) UNIX program). These scripts can be found in the
+;; other directories under test/lisp/erc/resources.
+;;
+;; Isolation:
+;;
+;; The set of enabled modules is shared among all tests. The function
+;; `erc-update-modules' activates them (as minor modes), but it never
+;; deactivates them. So there's no going back, and let-binding
+;; `erc-modules' is useless. The safest route is therefore to (1)
+;; assume the set of default modules is already activated or will be
+;; over the course of the test session and (2) let-bind relevant user
+;; options as needed. For example, to limit the damage of
+;; `erc-autojoin-channels-alist' to a given test, assume the
+;; `erc-join' library has already been loaded or will be on the next
+;; call to `erc-open'. And then just let-bind
+;; `erc-autojoin-channels-alist' for the duration of the test.
+;;
+;; Playing nice:
+;;
+;; Right now, these tests all rely on an ugly fixture macro named
+;; `erc-scenarios-common-with-cleanup', which is defined just below.
+;; It helps restore (but not really prepare) the environment by
+;; destroying any stray processes or buffers named in the first
+;; argument, a `let*'-style VAR-LIST. Relying on such a macro is
+;; unfortunate because in many ways it actually hampers readability by
+;; favoring magic over verbosity. But without it (or something
+;; similar), any failing test would cause all subsequent tests in this
+;; file to fail like dominoes (making all but the first backtrace
+;; useless).
+;;
+;; Misc:
+;;
+;; Note that in the following examples, nicknames Alice and Bob are
+;; always associated with the fake network FooNet, while nicks Joe and
+;; Mike are always on BarNet. (Networks are sometimes downcased.)
+;;
+;; XXX This file should *not* contain any test cases.
+
+;;; Code:
+
+(require 'ert-x) ; cl-lib
+(eval-and-compile
+ (let* ((d (expand-file-name ".." (ert-resource-directory)))
+ (load-path (cons (concat d "/erc-d") load-path)))
+ (require 'erc-d-t)
+ (require 'erc-d)))
+
+(require 'erc-backend)
+
+(eval-when-compile (require 'erc-join)
+ (require 'erc-services))
+
+(declare-function erc-network "erc-networks")
+(defvar erc-network)
+
+(defvar erc-scenarios-common--resources-dir
+ (expand-file-name "../" (ert-resource-directory)))
+
+;; Teardown is already inhibited when running interactively, which
+;; prevents subsequent tests from succeeding, so we might as well
+;; treat inspection as the goal.
+(unless noninteractive
+ (setq erc-server-auto-reconnect nil))
+
+(defvar erc-scenarios-common-dialog nil)
+(defvar erc-scenarios-common-extra-teardown nil)
+
+(defun erc-scenarios-common--add-silence ()
+ (advice-add #'erc-login :around #'erc-d-t-silence-around)
+ (advice-add #'erc-handle-login :around #'erc-d-t-silence-around)
+ (advice-add #'erc-server-connect :around #'erc-d-t-silence-around))
+
+(defun erc-scenarios-common--remove-silence ()
+ (advice-remove #'erc-login #'erc-d-t-silence-around)
+ (advice-remove #'erc-handle-login #'erc-d-t-silence-around)
+ (advice-remove #'erc-server-connect #'erc-d-t-silence-around))
+
+(defun erc-scenarios-common--print-trace ()
+ (when (and (boundp 'trace-buffer) (get-buffer trace-buffer))
+ (with-current-buffer trace-buffer
+ (message "%S" (buffer-string))
+ (kill-buffer))))
+
+(eval-and-compile
+ (defun erc-scenarios-common--make-bindings (bindings)
+ `((erc-d-u-canned-dialog-dir (expand-file-name
+ (or erc-scenarios-common-dialog
+ (cadr (assq 'erc-scenarios-common-dialog
+ ',bindings)))
+ erc-scenarios-common--resources-dir))
+ (erc-d-tmpl-vars `(,@erc-d-tmpl-vars
+ (quit . ,(erc-quit/part-reason-default))
+ (erc-version . ,erc-version)))
+ (erc-modules (copy-sequence erc-modules))
+ (inhibit-interaction t)
+ (auth-source-do-cache nil)
+ (erc-auth-source-parameters-join-function nil)
+ (erc-autojoin-channels-alist nil)
+ (erc-server-auto-reconnect nil)
+ (erc-d-linger-secs 10)
+ ,@bindings)))
+
+(defmacro erc-scenarios-common-with-cleanup (bindings &rest body)
+ "Provide boilerplate cleanup tasks after calling BODY with BINDINGS.
+
+If an `erc-d' process exists, wait for it to start before running BODY.
+If `erc-autojoin-mode' mode is bound, restore it during cleanup if
+disabled by BODY. Other defaults common to these test cases are added
+below and can be overridden, except when wanting the \"real\" default
+value, which must be looked up or captured outside of the calling form.
+
+Dialog resource directories are located by expanding the variable
+`erc-scenarios-common-dialog' or its value in BINDINGS."
+ (declare (indent 1))
+
+ (let* ((orig-autojoin-mode (make-symbol "orig-autojoin-mode"))
+ (combind `((,orig-autojoin-mode (bound-and-true-p erc-autojoin-mode))
+ ,@(erc-scenarios-common--make-bindings bindings))))
+
+ `(erc-d-t-with-cleanup (,@combind)
+
+ (ert-info ("Restore autojoin, etc., kill ERC buffers")
+ (dolist (buf (buffer-list))
+ (when-let ((erc-d-u--process-buffer)
+ (proc (get-buffer-process buf)))
+ (delete-process proc)))
+
+ (erc-scenarios-common--remove-silence)
+
+ (when erc-scenarios-common-extra-teardown
+ (ert-info ("Running extra teardown")
+ (funcall erc-scenarios-common-extra-teardown)))
+
+ (when (and (boundp 'erc-autojoin-mode)
+ (not (eq erc-autojoin-mode ,orig-autojoin-mode)))
+ (erc-autojoin-mode (if ,orig-autojoin-mode +1 -1)))
+
+ (when noninteractive
+ (erc-scenarios-common--print-trace)
+ (erc-d-t-kill-related-buffers)
+ (delete-other-windows)))
+
+ (erc-scenarios-common--add-silence)
+
+ (ert-info ("Wait for dumb server")
+ (dolist (buf (buffer-list))
+ (with-current-buffer buf
+ (when erc-d-u--process-buffer
+ (erc-d-t-search-for 3 "Starting")))))
+
+ (ert-info ("Activate erc-debug-irc-protocol")
+ (unless (and noninteractive (not erc-debug-irc-protocol))
+ (erc-toggle-debug-irc-protocol)))
+
+ ,@body)))
+
+(defun erc-scenarios-common-assert-initial-buf-name (id port)
+ ;; Assert no limbo period when explicit ID given
+ (should (string= (if id
+ (symbol-name id)
+ (format "127.0.0.1:%d" port))
+ (buffer-name))))
+
+(defun erc-scenarios-common-buflist (prefix)
+ "Return list of buffers with names sharing PREFIX."
+ (let (case-fold-search)
+ (erc-networks--id-sort-buffers
+ (delq nil
+ (mapcar (lambda (b)
+ (when (string-prefix-p prefix (buffer-name b)) b))
+ (buffer-list))))))
+
+;; This is more realistic than `erc-send-message' because it runs
+;; `erc-pre-send-functions', etc. Keyboard macros may be preferable,
+;; but they sometimes experience complications when an earlier test
+;; has failed.
+(defun erc-scenarios-common-say (str)
+ (let (erc-accidental-paste-threshold-seconds)
+ (goto-char erc-input-marker)
+ (insert str)
+ (erc-send-current-line)))
+
+
+;;;; Fixtures
+
+(cl-defun erc-scenarios-common--base-network-id-bouncer
+ ((&key autop foo-id bar-id after
+ &aux
+ (foo-id (and foo-id 'oofnet))
+ (bar-id (and bar-id 'rabnet))
+ (serv-buf-foo (if foo-id "oofnet" "foonet"))
+ (serv-buf-bar (if bar-id "rabnet" "barnet"))
+ (chan-buf-foo (if foo-id "#chan@oofnet" "#chan@foonet"))
+ (chan-buf-bar (if bar-id "#chan@rabnet" "#chan@barnet")))
+ &rest dialogs)
+ "Ensure retired option `erc-rename-buffers' is now the default behavior.
+The option `erc-rename-buffers' is now deprecated and on by default, so
+this now just asserts baseline behavior. Originally from scenario
+clash-of-chans/rename-buffers as explained in Bug#48598: 28.0.50;
+buffer-naming collisions involving bouncers in ERC."
+ (erc-scenarios-common-with-cleanup
+ ((erc-scenarios-common-dialog "base/netid/bouncer")
+ (erc-d-t-cleanup-sleep-secs 1)
+ (erc-server-flood-penalty 0.1)
+ (dumb-server (apply #'erc-d-run "localhost" t dialogs))
+ (port (process-contact dumb-server :service))
+ (expect (erc-d-t-make-expecter))
+ (erc-server-auto-reconnect autop)
+ erc-server-buffer-foo erc-server-process-foo
+ erc-server-buffer-bar erc-server-process-bar)
+
+ (ert-info ("Connect to foonet")
+ (with-current-buffer
+ (setq erc-server-buffer-foo (erc :server "127.0.0.1"
+ :port port
+ :nick "tester"
+ :password "foonet:changeme"
+ :full-name "tester"
+ :id foo-id))
+ (setq erc-server-process-foo erc-server-process)
+ (erc-scenarios-common-assert-initial-buf-name foo-id port)
+ (erc-d-t-wait-for 3 (eq (erc-network) 'foonet))
+ (erc-d-t-wait-for 3 (string= (buffer-name) serv-buf-foo))
+ (funcall expect 5 "foonet")))
+
+ (ert-info ("Join #chan@foonet")
+ (with-current-buffer erc-server-buffer-foo (erc-cmd-JOIN "#chan"))
+ (with-current-buffer (erc-d-t-wait-for 5 (get-buffer "#chan"))
+ (funcall expect 5 "<alice>")))
+
+ (ert-info ("Connect to barnet")
+ (with-current-buffer
+ (setq erc-server-buffer-bar (erc :server "127.0.0.1"
+ :port port
+ :nick "tester"
+ :password "barnet:changeme"
+ :full-name "tester"
+ :id bar-id))
+ (setq erc-server-process-bar erc-server-process)
+ (erc-scenarios-common-assert-initial-buf-name bar-id port)
+ (erc-d-t-wait-for 6 (eq (erc-network) 'barnet))
+ (erc-d-t-wait-for 3 (string= (buffer-name) serv-buf-bar))
+ (funcall expect 5 "barnet")))
+
+ (ert-info ("Server buffers are unique, no names based on IPs")
+ (should-not (eq erc-server-buffer-foo erc-server-buffer-bar))
+ (should-not (erc-scenarios-common-buflist "127.0.0.1")))
+
+ (ert-info ("Join #chan@barnet")
+ (with-current-buffer erc-server-buffer-bar (erc-cmd-JOIN "#chan")))
+
+ (erc-d-t-wait-for 5 "Exactly 2 #chan-prefixed buffers exist"
+ (equal (list (get-buffer chan-buf-bar)
+ (get-buffer chan-buf-foo))
+ (erc-scenarios-common-buflist "#chan")))
+
+ (ert-info ("#chan@<esid> is exclusive to foonet")
+ (with-current-buffer chan-buf-foo
+ (erc-d-t-search-for 1 "<bob>")
+ (erc-d-t-absent-for 0.1 "<joe>")
+ (should (eq erc-server-process erc-server-process-foo))
+ (erc-d-t-search-for 10 "ape is dead")
+ (erc-d-t-wait-for 5 (not (erc-server-process-alive)))))
+
+ (ert-info ("#chan@<esid> is exclusive to barnet")
+ (with-current-buffer chan-buf-bar
+ (erc-d-t-search-for 1 "<joe>")
+ (erc-d-t-absent-for 0.1 "<bob>")
+ (erc-d-t-wait-for 5 (eq erc-server-process erc-server-process-bar))
+ (erc-d-t-search-for 15 "keeps you from dishonour")
+ (erc-d-t-wait-for 5 (not (erc-server-process-alive)))))
+
+ (when after (funcall after))))
+
+(defun erc-scenarios-common--clash-rename-pass-handler (dialog exchange)
+ (when (eq (erc-d-dialog-name dialog) 'stub-again)
+ (let* ((match (erc-d-exchange-match exchange 1))
+ (sym (if (string= match "foonet") 'foonet-again 'barnet-again)))
+ (should (member match (list "foonet" "barnet")))
+ (erc-d-load-replacement-dialog dialog sym 1))))
+
+(defun erc-scenarios-common--base-network-id-bouncer--reconnect (foo-id bar-id)
+ (let ((erc-d-tmpl-vars '((token . (group (| "barnet" "foonet")))))
+ (erc-d-match-handlers
+ ;; Auto reconnect is nondeterministic, so let computer decide
+ (list :pass #'erc-scenarios-common--clash-rename-pass-handler))
+ (after
+ (lambda ()
+ ;; Simulate disconnection and `erc-server-auto-reconnect'
+ (ert-info ("Reconnect to foonet and barnet back-to-back")
+ (with-current-buffer (if foo-id "oofnet" "foonet")
+ (erc-d-t-wait-for 10 (erc-server-process-alive)))
+ (with-current-buffer (if bar-id "rabnet" "barnet")
+ (erc-d-t-wait-for 10 (erc-server-process-alive))))
+
+ (ert-info ("#chan@foonet is exclusive to foonet")
+ (with-current-buffer (if foo-id "#chan@oofnet" "#chan@foonet")
+ (erc-d-t-search-for 1 "<alice>")
+ (erc-d-t-absent-for 0.1 "<joe>")
+ (erc-d-t-search-for 20 "please your lordship")))
+
+ (ert-info ("#chan@barnet is exclusive to barnet")
+ (with-current-buffer (if bar-id "#chan@rabnet" "#chan@barnet")
+ (erc-d-t-search-for 1 "<joe>")
+ (erc-d-t-absent-for 0.1 "<bob>")
+ (erc-d-t-search-for 20 "much in private")))
+
+ ;; XXX this is important (reconnects overlapped, so we'd get
+ ;; chan@127.0.0.1:6667)
+ (should-not (erc-scenarios-common-buflist "127.0.0.1"))
+ ;; Reconnection order doesn't matter here because session objects
+ ;; are persisted, meaning original timestamps preserved.
+ (should (equal (list (get-buffer (if bar-id "#chan@rabnet"
+ "#chan@barnet"))
+ (get-buffer (if foo-id "#chan@oofnet"
+ "#chan@foonet")))
+ (erc-scenarios-common-buflist "#chan"))))))
+ (erc-scenarios-common--base-network-id-bouncer
+ (list :autop t :foo-id foo-id :bar-id bar-id :after after)
+ 'foonet-drop 'barnet-drop
+ 'stub-again 'stub-again
+ 'foonet-again 'barnet-again)))
+
+(defun erc-scenarios-common--upstream-reconnect (test &rest dialogs)
+ (erc-scenarios-common-with-cleanup
+ ((erc-scenarios-common-dialog "base/upstream-reconnect")
+ (erc-d-t-cleanup-sleep-secs 1)
+ (erc-server-flood-penalty 0.1)
+ (dumb-server (apply #'erc-d-run "localhost" t dialogs))
+ (port (process-contact dumb-server :service))
+ (expect (erc-d-t-make-expecter)))
+
+ (ert-info ("Connect to foonet")
+ (with-current-buffer (erc :server "127.0.0.1"
+ :port port
+ :nick "tester"
+ :user "tester@vanilla/foonet"
+ :password "changeme"
+ :full-name "tester")
+ (erc-scenarios-common-assert-initial-buf-name nil port)
+ (erc-d-t-wait-for 3 (eq (erc-network) 'foonet))
+ (erc-d-t-wait-for 3 (string= (buffer-name) "foonet"))
+ (funcall expect 5 "foonet")))
+
+ (ert-info ("Join #chan@foonet")
+ (with-current-buffer (erc-d-t-wait-for 5 (get-buffer "#chan"))
+ (funcall expect 5 "<alice>")))
+
+ (ert-info ("Connect to barnet")
+ (with-current-buffer (erc :server "127.0.0.1"
+ :port port
+ :nick "tester"
+ :user "tester@vanilla/barnet"
+ :password "changeme"
+ :full-name "tester")
+ (erc-scenarios-common-assert-initial-buf-name nil port)
+ (erc-d-t-wait-for 10 (eq (erc-network) 'barnet))
+ (erc-d-t-wait-for 3 (string= (buffer-name) "barnet"))
+ (funcall expect 5 "barnet")))
+
+ (ert-info ("Server buffers are unique, no names based on IPs")
+ (should-not (erc-scenarios-common-buflist "127.0.0.1")))
+
+ (with-current-buffer (erc-d-t-wait-for 5 (get-buffer "#chan@foonet"))
+ (funcall expect 5 "#chan was created on ")
+ (ert-info ("Joined again #chan@foonet")
+ (funcall expect 10 "#chan was created on "))
+ (funcall expect 10 "My lord, in heart"))
+
+ (with-current-buffer (erc-d-t-wait-for 5 (get-buffer "#chan@barnet"))
+ (funcall expect 5 "#chan was created on ")
+ (ert-info ("Joined again #chan@barnet")
+ (funcall expect 10 "#chan was created on "))
+ (funcall expect 10 "Go to; farewell"))
+
+ (funcall test)))
+
+;; XXX this is okay, but we also need to check that target buffers are
+;; already associated with a new process *before* a JOIN is sent by a
+;; server's playback burst. This doesn't do that.
+;;
+;; This *does* check that superfluous JOINs sent by the autojoin
+;; module are harmless when they're not acked (superfluous because the
+;; bouncer/server intitates the JOIN).
+
+(defun erc-scenarios-common--join-network-id (foo-reconnector foo-id bar-id)
+ "Ensure channels rejoined by erc-join.el DTRT.
+Originally from scenario clash-of-chans/autojoin as described in
+Bug#48598: 28.0.50; buffer-naming collisions involving bouncers in ERC."
+ (erc-scenarios-common-with-cleanup
+ ((chan-buf-foo (format "#chan@%s" (or foo-id "foonet")))
+ (chan-buf-bar (format "#chan@%s" (or bar-id "barnet")))
+ (erc-scenarios-common-dialog "join/network-id")
+ (erc-d-t-cleanup-sleep-secs 1)
+ (erc-server-flood-penalty 0.5)
+ (dumb-server (erc-d-run "localhost" t 'foonet 'barnet 'foonet-again))
+ (port (process-contact dumb-server :service))
+ (expect (erc-d-t-make-expecter))
+ erc-server-buffer-foo erc-server-process-foo
+ erc-server-buffer-bar erc-server-process-bar)
+
+ (should (memq 'autojoin erc-modules))
+
+ (ert-info ("Connect to foonet")
+ (with-current-buffer
+ (setq erc-server-buffer-foo (erc :server "127.0.0.1"
+ :port port
+ :nick "tester"
+ :password "foonet:changeme"
+ :full-name "tester"
+ :id foo-id))
+ (setq erc-server-process-foo erc-server-process)
+ (erc-scenarios-common-assert-initial-buf-name foo-id port)
+ (erc-d-t-wait-for 5 (eq (erc-network) 'foonet))
+ (funcall expect 5 "foonet")))
+
+ (ert-info ("Join #chan, find sentinel, quit")
+ (with-current-buffer erc-server-buffer-foo (erc-cmd-JOIN "#chan"))
+ (with-current-buffer (erc-d-t-wait-for 5 (get-buffer "#chan"))
+ (funcall expect 5 "vile thing")
+ (erc-cmd-QUIT "")))
+
+ (erc-d-t-wait-for 2 "Foonet connection deceased"
+ (not (erc-server-process-alive erc-server-buffer-foo)))
+
+ (should (equal erc-autojoin-channels-alist
+ (if foo-id '((oofnet "#chan")) '((foonet "#chan")))))
+
+ (ert-info ("Connect to barnet")
+ (with-current-buffer
+ (setq erc-server-buffer-bar (erc :server "127.0.0.1"
+ :port port
+ :nick "tester"
+ :password "barnet:changeme"
+ :full-name "tester"
+ :id bar-id))
+ (setq erc-server-process-bar erc-server-process)
+ (erc-d-t-wait-for 5 (eq erc-network 'barnet))
+ (should (string= (buffer-name) (if bar-id "rabnet" "barnet")))))
+
+ (ert-info ("Server buffers are unique, no stray IP-based names")
+ (should-not (eq erc-server-buffer-foo erc-server-buffer-bar))
+ (should-not (erc-scenarios-common-buflist "127.0.0.1")))
+
+ (ert-info ("Only one #chan buffer exists")
+ (should (equal (list (get-buffer "#chan"))
+ (erc-scenarios-common-buflist "#chan"))))
+
+ (ert-info ("#chan is not auto-joined")
+ (with-current-buffer "#chan"
+ (erc-d-t-absent-for 0.1 "<joe>")
+ (should-not (process-live-p erc-server-process))
+ (erc-d-t-ensure-for 0.1 "server buffer remains foonet"
+ (eq erc-server-process erc-server-process-foo))))
+
+ (with-current-buffer erc-server-buffer-bar
+ (erc-cmd-JOIN "#chan")
+ (erc-d-t-wait-for 3 (get-buffer chan-buf-foo))
+ (erc-d-t-wait-for 3 (get-buffer chan-buf-bar))
+ (with-current-buffer chan-buf-bar
+ (erc-d-t-wait-for 3 (eq erc-server-process erc-server-process-bar))
+ (funcall expect 5 "marry her instantly")))
+
+ (ert-info ("Reconnect to foonet")
+ (with-current-buffer (setq erc-server-buffer-foo
+ (funcall foo-reconnector))
+ (should (member (if foo-id '(oofnet "#chan") '(foonet "#chan"))
+ erc-autojoin-channels-alist))
+ (erc-d-t-wait-for 3 (erc-server-process-alive))
+ (setq erc-server-process-foo erc-server-process)
+ (erc-d-t-wait-for 2 (eq erc-network 'foonet))
+ (should (string= (buffer-name) (if foo-id "oofnet" "foonet")))
+ (funcall expect 5 "foonet")))
+
+ (ert-info ("#chan@foonet is clean, no cross-contamination")
+ (with-current-buffer chan-buf-foo
+ (erc-d-t-wait-for 3 (eq erc-server-process erc-server-process-foo))
+ (funcall expect 3 "<bob>")
+ (erc-d-t-absent-for 0.1 "<joe>")
+ (funcall expect 10 "not given me")))
+
+ (ert-info ("All #chan@barnet output received")
+ (with-current-buffer chan-buf-bar
+ (funcall expect 10 "hath an uncle here")))))
+
+(provide 'erc-scenarios-common)
+
+;;; erc-scenarios-common.el ends here
diff --git a/test/lisp/erc/resources/join/auth-source/foonet.eld b/test/lisp/erc/resources/join/auth-source/foonet.eld
new file mode 100644
index 00000000000..32b9e3fa0b6
--- /dev/null
+++ b/test/lisp/erc/resources/join/auth-source/foonet.eld
@@ -0,0 +1,33 @@
+;; -*- mode: lisp-data; -*-
+((pass 1 "PASS :changeme"))
+((nick 1 "NICK dummy"))
+((user 1 "USER user 0 * :dummy")
+ (0.00 ":irc.foonet.org 001 dummy :Welcome to the foonet IRC Network dummy")
+ (0.01 ":irc.foonet.org 002 dummy :Your host is irc.foonet.org, running version ergo-v2.8.0")
+ (0.00 ":irc.foonet.org 003 dummy :This server was created Tue, 24 May 2022 05:28:42 UTC")
+ (0.00 ":irc.foonet.org 004 dummy irc.foonet.org ergo-v2.8.0 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0.00 ":irc.foonet.org 005 dummy AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0.01 ":irc.foonet.org 005 dummy MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0.01 ":irc.foonet.org 005 dummy draft/CHATHISTORY=100 :are supported by this server")
+ (0.00 ":irc.foonet.org 251 dummy :There are 0 users and 4 invisible on 1 server(s)")
+ (0.00 ":irc.foonet.org 252 dummy 0 :IRC Operators online")
+ (0.00 ":irc.foonet.org 253 dummy 0 :unregistered connections")
+ (0.00 ":irc.foonet.org 254 dummy 2 :channels formed")
+ (0.00 ":irc.foonet.org 255 dummy :I have 4 clients and 0 servers")
+ (0.00 ":irc.foonet.org 265 dummy 4 4 :Current local users 4, max 4")
+ (0.00 ":irc.foonet.org 266 dummy 4 4 :Current global users 4, max 4")
+ (0.00 ":irc.foonet.org 422 dummy :MOTD File is missing"))
+
+((mode 6 "MODE dummy +i")
+ (0.00 ":irc.foonet.org 221 dummy +i")
+ (0.00 ":irc.foonet.org NOTICE dummy :This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect.")
+ (0.02 ":irc.foonet.org 221 dummy +i"))
+
+((join 6.47 "JOIN #spam secret")
+ (0.03 ":dummy!~u@w9rfqveugz722.irc JOIN #spam"))
+
+((mode 1 "MODE #spam")
+ (0.01 ":irc.foonet.org 353 dummy = #spam :~tester dummy")
+ (0.00 ":irc.foonet.org 366 dummy #spam :End of NAMES list")
+ (0.01 ":irc.foonet.org 324 dummy #spam +knt secret")
+ (0.03 ":irc.foonet.org 329 dummy #spam 1653370308"))
diff --git a/test/lisp/erc/resources/join/legacy/foonet.eld b/test/lisp/erc/resources/join/legacy/foonet.eld
new file mode 100644
index 00000000000..344ba7c1daf
--- /dev/null
+++ b/test/lisp/erc/resources/join/legacy/foonet.eld
@@ -0,0 +1,38 @@
+;; -*- mode: lisp-data; -*-
+((pass 1 "PASS :changeme"))
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
+ (0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.foonet.org 003 tester :This server was created Tue, 04 May 2021 05:06:18 UTC")
+ (0 ":irc.foonet.org 004 tester irc.foonet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.foonet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=FooNet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.foonet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.foonet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (0 ":irc.foonet.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.foonet.org 253 tester 0 :unregistered connections")
+ (0 ":irc.foonet.org 254 tester 1 :channels formed")
+ (0 ":irc.foonet.org 255 tester :I have 3 clients and 0 servers")
+ (0 ":irc.foonet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0 ":irc.foonet.org 422 tester :MOTD File is missing"))
+
+((mode-user 3.2 "MODE tester +i")
+ (0 ":irc.foonet.org 221 tester +i")
+ (0 ":irc.foonet.org NOTICE tester :This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect."))
+
+((join 6 "JOIN #chan")
+ (0 ":tester!~u@9g6b728983yd2.irc JOIN #chan")
+ (0 ":irc.foonet.org 353 tester = #chan :alice tester @bob")
+ (0 ":irc.foonet.org 366 tester #chan :End of NAMES list"))
+
+((mode 5 "MODE #chan")
+ (0 ":irc.foonet.org 324 tester #chan +nt")
+ (0 ":irc.foonet.org 329 tester #chan 1620104779")
+ (0.1 ":bob!~u@rz2v467q4rwhy.irc PRIVMSG #chan :tester, welcome!")
+ (0.1 ":alice!~u@rz2v467q4rwhy.irc PRIVMSG #chan :tester, welcome!")
+ (0.1 ":bob!~u@rz2v467q4rwhy.irc PRIVMSG #chan :alice: But, as it seems, did violence on herself.")
+ (0.1 ":alice!~u@rz2v467q4rwhy.irc PRIVMSG #chan :bob: Well, this is the forest of Arden.")
+ (0.1 ":alice!~u@rz2v467q4rwhy.irc PRIVMSG #chan :bob: And will you, being a man of your breeding, be married under a bush, like a beggar ? Get you to church, and have a good priest that can tell you what marriage is: this fellow will but join you together as they join wainscot; then one of you will prove a shrunk panel, and like green timber, warp, warp.")
+ (0.1 ":bob!~u@rz2v467q4rwhy.irc PRIVMSG #chan :alice: Live, and be prosperous; and farewell, good fellow."))
diff --git a/test/lisp/erc/resources/join/network-id/barnet.eld b/test/lisp/erc/resources/join/network-id/barnet.eld
new file mode 100644
index 00000000000..e33dd6be29e
--- /dev/null
+++ b/test/lisp/erc/resources/join/network-id/barnet.eld
@@ -0,0 +1,43 @@
+;; -*- mode: lisp-data; -*-
+((pass 2 "PASS :barnet:changeme"))
+((nick 2 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0 ":irc.barnet.org 001 tester :Welcome to the barnet IRC Network tester")
+ (0 ":irc.barnet.org 002 tester :Your host is irc.barnet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.barnet.org 003 tester :This server was created Mon, 10 May 2021 00:58:22 UTC")
+ (0 ":irc.barnet.org 004 tester irc.barnet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.barnet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.barnet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=barnet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.barnet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.barnet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (0 ":irc.barnet.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.barnet.org 254 tester 1 :channels formed")
+ (0 ":irc.barnet.org 255 tester :I have 3 clients and 0 servers")
+ (0 ":irc.barnet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0 ":irc.barnet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0 ":irc.barnet.org 422 tester :MOTD File is missing"))
+
+((mode-user 12 "MODE tester +i"))
+;; No mode answer
+
+((join 2 "JOIN #chan")
+ (0 ":tester!~u@6yximxrnkg65a.irc JOIN #chan")
+ (0 ":irc.barnet.org 353 tester = #chan :@joe mike tester")
+ (0 ":irc.barnet.org 366 tester #chan :End of NAMES list")
+ (0.1 ":joe!~u@6yximxrnkg65a.irc PRIVMSG #chan :tester, welcome!")
+ (0 ":mike!~u@6yximxrnkg65a.irc PRIVMSG #chan :tester, welcome!"))
+
+((mode 1 "MODE #chan")
+ (0 ":irc.barnet.org 324 tester #chan +nt")
+ (0 ":irc.barnet.org 329 tester #chan 1620608304")
+ ;; Wait for foonet's buffer playback
+ (0.1 ":mike!~u@6yximxrnkg65a.irc PRIVMSG #chan :joe: Go take her hence, and marry her instantly.")
+ (0.1 ":joe!~u@6yximxrnkg65a.irc PRIVMSG #chan :mike: Of all the four, or the three, or the two, or one of the four.")
+ (0.1 ":mike!~u@6yximxrnkg65a.irc PRIVMSG #chan :joe: And gives the crutch the cradle's infancy.")
+ (0.1 ":joe!~u@6yximxrnkg65a.irc PRIVMSG #chan :mike: Such is the simplicity of man to hearken after the flesh.")
+ (0.05 ":mike!~u@6yximxrnkg65a.irc PRIVMSG #chan :joe: The leaf to read them. Let us toward the king.")
+ (0.05 ":joe!~u@6yximxrnkg65a.irc PRIVMSG #chan :mike: Many can brook the weather that love not the wind.")
+ (0.05 ":mike!~u@6yximxrnkg65a.irc PRIVMSG #chan :joe: And now, dear maid, be you as free to us.")
+ (0.00 ":joe!~u@6yximxrnkg65a.irc PRIVMSG #chan :mike: He hath an uncle here in Messina will be very much glad of it."))
+
+((linger 3.5 LINGER))
diff --git a/test/lisp/erc/resources/join/network-id/foonet-again.eld b/test/lisp/erc/resources/join/network-id/foonet-again.eld
new file mode 100644
index 00000000000..b230eff27c7
--- /dev/null
+++ b/test/lisp/erc/resources/join/network-id/foonet-again.eld
@@ -0,0 +1,46 @@
+;; -*- mode: lisp-data; -*-
+((pass-redux 10 "PASS :foonet:changeme"))
+((nick-redux 1 "NICK tester"))
+
+((user-redux 1 "USER user 0 * :tester")
+ (0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
+ (0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.foonet.org 003 tester :This server was created Mon, 10 May 2021 00:58:22 UTC")
+ (0 ":irc.foonet.org 004 tester irc.foonet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.foonet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.foonet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.foonet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (0 ":irc.foonet.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.foonet.org 254 tester 1 :channels formed")
+ (0 ":irc.foonet.org 255 tester :I have 3 clients and 0 servers")
+ (0 ":irc.foonet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0 ":irc.foonet.org 422 tester :MOTD File is missing"))
+
+((mode-user 10.2 "MODE tester +i")
+ ;; No mode answer ^
+
+ ;; History
+ (0 ":tester!~u@q6ddatxcq6txy.irc JOIN #chan")
+ (0 ":irc.foonet.org 353 tester = #chan :@alice bob tester")
+ (0 ":irc.foonet.org 366 tester #chan :End of /NAMES list.")
+ (0 ":***!znc@znc.in PRIVMSG #chan :Buffer Playback...")
+ (0 ":bob!~u@q6ddatxcq6txy.irc PRIVMSG #chan :[02:43:23] alice: And soar with them above a common bound.")
+ (0 ":alice!~u@q6ddatxcq6txy.irc PRIVMSG #chan :[02:43:27] bob: And be aveng'd on cursed Tamora.")
+ (0 ":bob!~u@q6ddatxcq6txy.irc PRIVMSG #chan :[02:43:29] alice: He did love her, sir, as a gentleman loves a woman.")
+ (0 ":***!znc@znc.in PRIVMSG #chan :Playback Complete."))
+
+;; As a server, we ignore useless join sent by autojoin module
+((~join 10 "JOIN #chan"))
+
+((mode-redux 10 "MODE #chan")
+ (0 ":irc.foonet.org 324 tester #chan +nt")
+ (0 ":irc.foonet.org 329 tester #chan 1620608304")
+ (0.1 ":alice!~u@q6ddatxcq6txy.irc PRIVMSG #chan :bob: Ay, madam, with the swiftest wing of speed.")
+ (0.1 ":bob!~u@q6ddatxcq6txy.irc PRIVMSG #chan :alice: Five times in that ere once in our five wits.")
+ (0.1 ":alice!~u@q6ddatxcq6txy.irc PRIVMSG #chan :bob: And bid him come to take his last farewell.")
+ (0.1 ":bob!~u@q6ddatxcq6txy.irc PRIVMSG #chan :alice: But we are spirits of another sort.")
+ (0.1 ":alice!~u@q6ddatxcq6txy.irc PRIVMSG #chan :bob: It was not given me, nor I did not buy it."))
+
+((linger 6 LINGER))
diff --git a/test/lisp/erc/resources/join/network-id/foonet.eld b/test/lisp/erc/resources/join/network-id/foonet.eld
new file mode 100644
index 00000000000..7d63f5f0c6c
--- /dev/null
+++ b/test/lisp/erc/resources/join/network-id/foonet.eld
@@ -0,0 +1,39 @@
+;; -*- mode: lisp-data; -*-
+((pass 10 "PASS :foonet:changeme"))
+((nick 1 "NICK tester"))
+
+((user 1 "USER user 0 * :tester")
+ (0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
+ (0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.foonet.org 003 tester :This server was created Mon, 10 May 2021 00:58:22 UTC")
+ (0 ":irc.foonet.org 004 tester irc.foonet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.foonet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.foonet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.foonet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (0 ":irc.foonet.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.foonet.org 254 tester 1 :channels formed")
+ (0 ":irc.foonet.org 255 tester :I have 3 clients and 0 servers")
+ (0 ":irc.foonet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0 ":irc.foonet.org 422 tester :MOTD File is missing"))
+
+((mode-user 10.2 "MODE tester +i"))
+;; No mode answer ^
+
+((join 3 "JOIN #chan")
+ (0 ":tester!~u@q6ddatxcq6txy.irc JOIN #chan")
+ (0 ":irc.foonet.org 353 tester = #chan :@alice bob tester")
+ (0 ":irc.foonet.org 366 tester #chan :End of NAMES list")
+ (0.1 ":bob!~u@q6ddatxcq6txy.irc PRIVMSG #chan :tester, welcome!")
+ (0 ":alice!~u@q6ddatxcq6txy.irc PRIVMSG #chan :tester, welcome!"))
+
+((mode 3 "MODE #chan")
+ (0 ":irc.foonet.org 324 tester #chan +nt")
+ (0 ":irc.foonet.org 329 tester #chan 1620608304")
+ (0.1 ":bob!~u@q6ddatxcq6txy.irc PRIVMSG #chan :alice: Pray you, sir, deliver me this paper.")
+ (0.1 ":alice!~u@q6ddatxcq6txy.irc PRIVMSG #chan :bob: Wake when some vile thing is near."))
+
+((quit 3 "QUIT :\2ERC\2"))
+
+((drop 0 DROP))
diff --git a/test/lisp/erc/resources/join/reconnect/foonet-again.eld b/test/lisp/erc/resources/join/reconnect/foonet-again.eld
new file mode 100644
index 00000000000..f1fcc439cc3
--- /dev/null
+++ b/test/lisp/erc/resources/join/reconnect/foonet-again.eld
@@ -0,0 +1,45 @@
+;; -*- mode: lisp-data; -*-
+((pass 1 "PASS :changeme"))
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
+ (0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.foonet.org 003 tester :This server was created Tue, 04 May 2021 05:06:18 UTC")
+ (0 ":irc.foonet.org 004 tester irc.foonet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.foonet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=FooNet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.foonet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.foonet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (0 ":irc.foonet.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.foonet.org 253 tester 0 :unregistered connections")
+ (0 ":irc.foonet.org 254 tester 1 :channels formed")
+ (0 ":irc.foonet.org 255 tester :I have 3 clients and 0 servers")
+ (0 ":irc.foonet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0 ":irc.foonet.org 422 tester :MOTD File is missing"))
+
+((mode-user 3.2 "MODE tester +i")
+ (0 ":irc.foonet.org 221 tester +i")
+ (0 ":irc.foonet.org NOTICE tester :This server is still in debug mode."))
+
+((~join-chan 12 "JOIN #chan")
+ (0 ":tester!~u@9g6b728983yd2.irc JOIN #chan")
+ (0 ":irc.foonet.org 353 tester = #chan :alice tester @bob")
+ (0 ":irc.foonet.org 366 tester #chan :End of NAMES list"))
+
+((~join-spam 12 "JOIN #spam")
+ (0 ":tester!~u@9g6b728983yd2.irc JOIN #spam")
+ (0 ":irc.foonet.org 353 tester = #spam :alice tester @bob")
+ (0 ":irc.foonet.org 366 tester #spam :End of NAMES list"))
+
+((~mode-chan 4 "MODE #chan")
+ (0 ":irc.foonet.org 324 tester #chan +nt")
+ (0 ":irc.foonet.org 329 tester #chan 1620104779")
+ (0.1 ":bob!~u@rz2v467q4rwhy.irc PRIVMSG #chan :alice: But, as it seems, did violence on herself.")
+ (0.1 ":alice!~u@rz2v467q4rwhy.irc PRIVMSG #chan :bob: Well, this is the forest of Arden."))
+
+((mode-spam 4 "MODE #spam")
+ (0 ":irc.foonet.org 324 tester #spam +nt")
+ (0 ":irc.foonet.org 329 tester #spam 1620104779")
+ (0.1 ":bob!~u@rz2v467q4rwhy.irc PRIVMSG #spam :alice: Signior Iachimo will not from it. Pray, let us follow 'em.")
+ (0.1 ":alice!~u@rz2v467q4rwhy.irc PRIVMSG #spam :bob: Our queen and all her elves come here anon."))
diff --git a/test/lisp/erc/resources/join/reconnect/foonet.eld b/test/lisp/erc/resources/join/reconnect/foonet.eld
new file mode 100644
index 00000000000..efb269f5ae5
--- /dev/null
+++ b/test/lisp/erc/resources/join/reconnect/foonet.eld
@@ -0,0 +1,45 @@
+;; -*- mode: lisp-data; -*-
+((pass 1 "PASS :changeme"))
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
+ (0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version oragono-2.6.0-7481bf0385b95b16")
+ (0 ":irc.foonet.org 003 tester :This server was created Tue, 04 May 2021 05:06:18 UTC")
+ (0 ":irc.foonet.org 004 tester irc.foonet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
+ (0 ":irc.foonet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=FooNet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
+ (0 ":irc.foonet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
+ (0 ":irc.foonet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
+ (0 ":irc.foonet.org 252 tester 0 :IRC Operators online")
+ (0 ":irc.foonet.org 253 tester 0 :unregistered connections")
+ (0 ":irc.foonet.org 254 tester 1 :channels formed")
+ (0 ":irc.foonet.org 255 tester :I have 3 clients and 0 servers")
+ (0 ":irc.foonet.org 265 tester 3 3 :Current local users 3, max 3")
+ (0 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3")
+ (0 ":irc.foonet.org 422 tester :MOTD File is missing"))
+
+((mode-user 3.2 "MODE tester +i")
+ (0 ":irc.foonet.org 221 tester +i")
+ (0 ":irc.foonet.org NOTICE tester :This server is in debug mode.")
+
+ (0 ":tester!~u@9g6b728983yd2.irc JOIN #chan")
+ (0 ":irc.foonet.org 353 tester = #chan :alice tester @bob")
+ (0 ":irc.foonet.org 366 tester #chan :End of NAMES list")
+
+ (0 ":tester!~u@9g6b728983yd2.irc JOIN #spam")
+ (0 ":irc.foonet.org 353 tester = #spam :alice tester @bob")
+ (0 ":irc.foonet.org 366 tester #spam :End of NAMES list"))
+
+((mode-chan 4 "MODE #chan")
+ (0 ":irc.foonet.org 324 tester #chan +nt")
+ (0 ":irc.foonet.org 329 tester #chan 1620104779")
+ (0.1 ":bob!~u@rz2v467q4rwhy.irc PRIVMSG #chan :tester, welcome!")
+ (0.1 ":alice!~u@rz2v467q4rwhy.irc PRIVMSG #chan :tester, welcome!"))
+
+((mode-spam 4 "MODE #spam")
+ (0 ":irc.foonet.org 324 tester #spam +nt")
+ (0 ":irc.foonet.org 329 tester #spam 1620104779")
+ (0.1 ":bob!~u@rz2v467q4rwhy.irc PRIVMSG #spam :tester, welcome!")
+ (0.1 ":alice!~u@rz2v467q4rwhy.irc PRIVMSG #spam :tester, welcome!"))
+
+((drop 0 DROP))
diff --git a/test/lisp/erc/resources/networks/announced-missing/foonet.eld b/test/lisp/erc/resources/networks/announced-missing/foonet.eld
new file mode 100644
index 00000000000..79b0fb462a8
--- /dev/null
+++ b/test/lisp/erc/resources/networks/announced-missing/foonet.eld
@@ -0,0 +1,8 @@
+;; -*- mode: lisp-data; -*-
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0 ":irc.foonet.org 001 tester :Welcome to the FooNet Internet Relay Chat Network tester")
+ (0 ":irc.foonet.org 422 tester :MOTD File is missing"))
+
+((mode-user 1.2 "MODE tester +i")
+ (0 ":tester MODE tester :+Zi"))
diff --git a/test/lisp/erc/resources/services/auth-source/libera.eld b/test/lisp/erc/resources/services/auth-source/libera.eld
new file mode 100644
index 00000000000..c8dbc9d425a
--- /dev/null
+++ b/test/lisp/erc/resources/services/auth-source/libera.eld
@@ -0,0 +1,49 @@
+;; -*- mode: lisp-data; -*-
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0.26 ":zirconium.libera.chat NOTICE * :*** Checking Ident")
+ (0.01 ":zirconium.libera.chat NOTICE * :*** Looking up your hostname...")
+ (0.01 ":zirconium.libera.chat NOTICE * :*** No Ident response")
+ (0.02 ":zirconium.libera.chat NOTICE * :*** Found your hostname: static-198-54-131-100.cust.tzulo.com")
+ (0.02 ":zirconium.libera.chat 001 tester :Welcome to the Libera.Chat Internet Relay Chat Network tester")
+ (0.01 ":zirconium.libera.chat 002 tester :Your host is zirconium.libera.chat[46.16.175.175/6697], running version solanum-1.0-dev")
+ (0.03 ":zirconium.libera.chat 003 tester :This server was created Wed Jun 9 2021 at 01:38:28 UTC")
+ (0.02 ":zirconium.libera.chat 004 tester zirconium.libera.chat solanum-1.0-dev DGQRSZaghilopsuwz CFILMPQSbcefgijklmnopqrstuvz bkloveqjfI")
+ (0.00 ":zirconium.libera.chat 005 tester ETRACE WHOX FNC MONITOR=100 SAFELIST ELIST=CTU CALLERID=g KNOCK CHANTYPES=# EXCEPTS INVEX CHANMODES=eIbq,k,flj,CFLMPQScgimnprstuz :are supported by this server")
+ (0.03 ":zirconium.libera.chat 005 tester CHANLIMIT=#:250 PREFIX=(ov)@+ MAXLIST=bqeI:100 MODES=4 NETWORK=Libera.Chat STATUSMSG=@+ CASEMAPPING=rfc1459 NICKLEN=16 MAXNICKLEN=16 CHANNELLEN=50 TOPICLEN=390 DEAF=D :are supported by this server")
+ (0.02 ":zirconium.libera.chat 005 tester TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,PRIVMSG:4,NOTICE:4,ACCEPT:,MONITOR: EXTBAN=$,ajrxz CLIENTVER=3.0 :are supported by this server")
+ (0.02 ":zirconium.libera.chat 251 tester :There are 68 users and 37640 invisible on 25 servers")
+ (0.00 ":zirconium.libera.chat 252 tester 36 :IRC Operators online")
+ (0.01 ":zirconium.libera.chat 253 tester 5 :unknown connection(s)")
+ (0.00 ":zirconium.libera.chat 254 tester 19341 :channels formed")
+ (0.01 ":zirconium.libera.chat 255 tester :I have 3321 clients and 1 servers")
+ (0.01 ":zirconium.libera.chat 265 tester 3321 4289 :Current local users 3321, max 4289")
+ (0.00 ":zirconium.libera.chat 266 tester 37708 38929 :Current global users 37708, max 38929")
+ (0.01 ":zirconium.libera.chat 250 tester :Highest connection count: 4290 (4289 clients) (38580 connections received)")
+ (0.21 ":zirconium.libera.chat 375 tester :- zirconium.libera.chat Message of the Day - ")
+ (0.00 ":zirconium.libera.chat 372 tester :- This server provided by Seeweb <https://www.seeweb.it/>")
+ (0.01 ":zirconium.libera.chat 372 tester :- Welcome to Libera Chat, the IRC network for")
+ (0.01 ":zirconium.libera.chat 372 tester :- free & open-source software and peer directed projects.")
+ (0.00 ":zirconium.libera.chat 372 tester :- ")
+ (0.00 ":zirconium.libera.chat 372 tester :- Use of Libera Chat is governed by our network policies.")
+ (0.00 ":zirconium.libera.chat 372 tester :- ")
+ (0.01 ":zirconium.libera.chat 372 tester :- Please visit us in #libera for questions and support.")
+ (0.01 ":zirconium.libera.chat 372 tester :- ")
+ (0.01 ":zirconium.libera.chat 372 tester :- Website and documentation: https://libera.chat")
+ (0.01 ":zirconium.libera.chat 372 tester :- Webchat: https://web.libera.chat")
+ (0.01 ":zirconium.libera.chat 372 tester :- Network policies: https://libera.chat/policies")
+ (0.01 ":zirconium.libera.chat 372 tester :- Email: support@libera.chat")
+ (0.00 ":zirconium.libera.chat 376 tester :End of /MOTD command."))
+
+((mode-user 1.2 "MODE tester +i")
+ (0.02 ":tester MODE tester :+Zi")
+ (0.02 ":NickServ!NickServ@services.libera.chat NOTICE tester :This nickname is registered. Please choose a different nickname, or identify via \2/msg NickServ IDENTIFY tester <password>\2"))
+
+((privmsg 2 "PRIVMSG NickServ :IDENTIFY changeme")
+ (0.96 ":NickServ!NickServ@services.libera.chat NOTICE tester :You are now identified for \2tester\2.")
+ (0.25 ":NickServ!NickServ@services.libera.chat NOTICE tester :Last login from: \2~tester@school.edu/tester\2 on Jun 18 01:15:56 2021 +0000."))
+
+((quit 5 "QUIT :\2ERC\2")
+ (0.19 ":tester!~user@static-198-54-131-100.cust.tzulo.com QUIT :Client Quit"))
+
+((linger 1 LINGER))
diff --git a/test/lisp/erc/resources/services/password/libera.eld b/test/lisp/erc/resources/services/password/libera.eld
new file mode 100644
index 00000000000..c8dbc9d425a
--- /dev/null
+++ b/test/lisp/erc/resources/services/password/libera.eld
@@ -0,0 +1,49 @@
+;; -*- mode: lisp-data; -*-
+((nick 1 "NICK tester"))
+((user 1 "USER user 0 * :tester")
+ (0.26 ":zirconium.libera.chat NOTICE * :*** Checking Ident")
+ (0.01 ":zirconium.libera.chat NOTICE * :*** Looking up your hostname...")
+ (0.01 ":zirconium.libera.chat NOTICE * :*** No Ident response")
+ (0.02 ":zirconium.libera.chat NOTICE * :*** Found your hostname: static-198-54-131-100.cust.tzulo.com")
+ (0.02 ":zirconium.libera.chat 001 tester :Welcome to the Libera.Chat Internet Relay Chat Network tester")
+ (0.01 ":zirconium.libera.chat 002 tester :Your host is zirconium.libera.chat[46.16.175.175/6697], running version solanum-1.0-dev")
+ (0.03 ":zirconium.libera.chat 003 tester :This server was created Wed Jun 9 2021 at 01:38:28 UTC")
+ (0.02 ":zirconium.libera.chat 004 tester zirconium.libera.chat solanum-1.0-dev DGQRSZaghilopsuwz CFILMPQSbcefgijklmnopqrstuvz bkloveqjfI")
+ (0.00 ":zirconium.libera.chat 005 tester ETRACE WHOX FNC MONITOR=100 SAFELIST ELIST=CTU CALLERID=g KNOCK CHANTYPES=# EXCEPTS INVEX CHANMODES=eIbq,k,flj,CFLMPQScgimnprstuz :are supported by this server")
+ (0.03 ":zirconium.libera.chat 005 tester CHANLIMIT=#:250 PREFIX=(ov)@+ MAXLIST=bqeI:100 MODES=4 NETWORK=Libera.Chat STATUSMSG=@+ CASEMAPPING=rfc1459 NICKLEN=16 MAXNICKLEN=16 CHANNELLEN=50 TOPICLEN=390 DEAF=D :are supported by this server")
+ (0.02 ":zirconium.libera.chat 005 tester TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,PRIVMSG:4,NOTICE:4,ACCEPT:,MONITOR: EXTBAN=$,ajrxz CLIENTVER=3.0 :are supported by this server")
+ (0.02 ":zirconium.libera.chat 251 tester :There are 68 users and 37640 invisible on 25 servers")
+ (0.00 ":zirconium.libera.chat 252 tester 36 :IRC Operators online")
+ (0.01 ":zirconium.libera.chat 253 tester 5 :unknown connection(s)")
+ (0.00 ":zirconium.libera.chat 254 tester 19341 :channels formed")
+ (0.01 ":zirconium.libera.chat 255 tester :I have 3321 clients and 1 servers")
+ (0.01 ":zirconium.libera.chat 265 tester 3321 4289 :Current local users 3321, max 4289")
+ (0.00 ":zirconium.libera.chat 266 tester 37708 38929 :Current global users 37708, max 38929")
+ (0.01 ":zirconium.libera.chat 250 tester :Highest connection count: 4290 (4289 clients) (38580 connections received)")
+ (0.21 ":zirconium.libera.chat 375 tester :- zirconium.libera.chat Message of the Day - ")
+ (0.00 ":zirconium.libera.chat 372 tester :- This server provided by Seeweb <https://www.seeweb.it/>")
+ (0.01 ":zirconium.libera.chat 372 tester :- Welcome to Libera Chat, the IRC network for")
+ (0.01 ":zirconium.libera.chat 372 tester :- free & open-source software and peer directed projects.")
+ (0.00 ":zirconium.libera.chat 372 tester :- ")
+ (0.00 ":zirconium.libera.chat 372 tester :- Use of Libera Chat is governed by our network policies.")
+ (0.00 ":zirconium.libera.chat 372 tester :- ")
+ (0.01 ":zirconium.libera.chat 372 tester :- Please visit us in #libera for questions and support.")
+ (0.01 ":zirconium.libera.chat 372 tester :- ")
+ (0.01 ":zirconium.libera.chat 372 tester :- Website and documentation: https://libera.chat")
+ (0.01 ":zirconium.libera.chat 372 tester :- Webchat: https://web.libera.chat")
+ (0.01 ":zirconium.libera.chat 372 tester :- Network policies: https://libera.chat/policies")
+ (0.01 ":zirconium.libera.chat 372 tester :- Email: support@libera.chat")
+ (0.00 ":zirconium.libera.chat 376 tester :End of /MOTD command."))
+
+((mode-user 1.2 "MODE tester +i")
+ (0.02 ":tester MODE tester :+Zi")
+ (0.02 ":NickServ!NickServ@services.libera.chat NOTICE tester :This nickname is registered. Please choose a different nickname, or identify via \2/msg NickServ IDENTIFY tester <password>\2"))
+
+((privmsg 2 "PRIVMSG NickServ :IDENTIFY changeme")
+ (0.96 ":NickServ!NickServ@services.libera.chat NOTICE tester :You are now identified for \2tester\2.")
+ (0.25 ":NickServ!NickServ@services.libera.chat NOTICE tester :Last login from: \2~tester@school.edu/tester\2 on Jun 18 01:15:56 2021 +0000."))
+
+((quit 5 "QUIT :\2ERC\2")
+ (0.19 ":tester!~user@static-198-54-131-100.cust.tzulo.com QUIT :Client Quit"))
+
+((linger 1 LINGER))
diff --git a/test/lisp/eshell/em-alias-tests.el b/test/lisp/eshell/em-alias-tests.el
new file mode 100644
index 00000000000..497159e3460
--- /dev/null
+++ b/test/lisp/eshell/em-alias-tests.el
@@ -0,0 +1,87 @@
+;;; em-alias-tests.el --- em-alias test suite -*- lexical-binding:t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Tests for Eshell's alias module.
+
+;;; Code:
+
+(require 'ert)
+(require 'esh-mode)
+(require 'eshell)
+(require 'em-alias)
+
+(require 'eshell-tests-helpers
+ (expand-file-name "eshell-tests-helpers"
+ (file-name-directory (or load-file-name
+ default-directory))))
+;;; Tests:
+
+(ert-deftest em-alias-test/simple-alias ()
+ "Test a simple alias with no arguments"
+ (with-temp-eshell
+ (eshell-insert-command "alias say-hi 'echo hi'")
+ (eshell-command-result-p "say-hi" "hi\n")
+ (eshell-command-result-p "say-hi bye" "hi\n")))
+
+(ert-deftest em-alias-test/alias-arg-vars ()
+ "Test alias with $0, $1, ... variables"
+ (with-temp-eshell
+ (eshell-insert-command "alias show-args 'printnl $0 \"$1 $2\"'")
+ (eshell-command-result-p "show-args one two" "show-args\none two\n")))
+
+(ert-deftest em-alias-test/alias-arg-vars-indices ()
+ "Test alias with $1, $2, ... variables using indices"
+ (with-temp-eshell
+ (eshell-insert-command "alias funny-sum '+ $1[0] $2[1]'")
+ (eshell-command-result-p "funny-sum (list 1 2) (list 3 4)"
+ "5\n")))
+
+(ert-deftest em-alias-test/alias-arg-vars-split-indices ()
+ "Test alias with $0, $1, ... variables using split indices"
+ (with-temp-eshell
+ (eshell-insert-command "alias my-prefix 'echo $0[- 0]'")
+ (eshell-command-result-p "my-prefix"
+ "my\n")
+ (eshell-insert-command "alias funny-sum '+ $1[: 0] $2[: 1]'")
+ (eshell-command-result-p "funny-sum 1:2 3:4"
+ "5\n")))
+
+(ert-deftest em-alias-test/alias-all-args-var ()
+ "Test alias with the $* variable"
+ (with-temp-eshell
+ (eshell-insert-command "alias show-all-args 'printnl $*'")
+ (eshell-command-result-p "show-all-args" "\\`\\'")
+ (eshell-command-result-p "show-all-args a" "a\n")
+ (eshell-command-result-p "show-all-args a b c" "a\nb\nc\n")))
+
+(ert-deftest em-alias-test/alias-all-args-var-indices ()
+ "Test alias with the $* variable using indices"
+ (with-temp-eshell
+ (eshell-insert-command "alias add-pair '+ $*[0] $*[1]'")
+ (eshell-command-result-p "add-pair 1 2" "3\n")))
+
+(ert-deftest em-alias-test/alias-all-args-var-split-indices ()
+ "Test alias with the $* variable using split indices"
+ (with-temp-eshell
+ (eshell-insert-command "alias add-funny-pair '+ $*[0][: 0] $*[1][: 1]'")
+ (eshell-command-result-p "add-funny-pair 1:2 3:4" "5\n")))
+
+;; em-alias-tests.el ends here
diff --git a/test/lisp/eshell/em-basic-tests.el b/test/lisp/eshell/em-basic-tests.el
new file mode 100644
index 00000000000..7a24f8b46c3
--- /dev/null
+++ b/test/lisp/eshell/em-basic-tests.el
@@ -0,0 +1,71 @@
+;;; em-basic-tests.el --- em-basic test suite -*- lexical-binding:t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Tests for basic Eshell commands.
+
+;;; Code:
+
+(require 'ert)
+(require 'em-basic)
+
+(require 'eshell-tests-helpers
+ (expand-file-name "eshell-tests-helpers"
+ (file-name-directory (or load-file-name
+ default-directory))))
+
+;;; Tests:
+
+(ert-deftest em-basic-test/umask-print-numeric ()
+ "Test printing umask numerically."
+ (cl-letf (((symbol-function 'default-file-modes) (lambda () #o775)))
+ (should (equal (eshell-test-command-result "umask") "002\n")))
+ (cl-letf (((symbol-function 'default-file-modes) (lambda () #o654)))
+ (should (equal (eshell-test-command-result "umask") "123\n")))
+ ;; Make sure larger numbers don't cause problems.
+ (cl-letf (((symbol-function 'default-file-modes) (lambda () #o1775)))
+ (should (equal (eshell-test-command-result "umask") "002\n"))))
+
+(ert-deftest em-basic-test/umask-read-symbolic ()
+ "Test printing umask symbolically."
+ (cl-letf (((symbol-function 'default-file-modes) (lambda () #o775)))
+ (should (equal (eshell-test-command-result "umask -S")
+ "u=rwx,g=rwx,o=rx\n")))
+ (cl-letf (((symbol-function 'default-file-modes) (lambda () #o654)))
+ (should (equal (eshell-test-command-result "umask -S")
+ "u=wx,g=rx,o=x\n")))
+ ;; Make sure larger numbers don't cause problems.
+ (cl-letf (((symbol-function 'default-file-modes) (lambda () #o1775)))
+ (should (equal (eshell-test-command-result "umask -S")
+ "u=rwx,g=rwx,o=rx\n"))))
+
+(ert-deftest em-basic-test/umask-set ()
+ "Test setting umask."
+ (let ((file-modes 0))
+ (cl-letf (((symbol-function 'set-default-file-modes)
+ (lambda (mode) (setq file-modes mode))))
+ (eshell-test-command-result "umask 002")
+ (should (= file-modes #o775))
+ (eshell-test-command-result "umask 123")
+ (should (= file-modes #o654))
+ (eshell-test-command-result "umask $(identity #o222)")
+ (should (= file-modes #o555)))))
+
+;; em-basic-tests.el ends here
diff --git a/test/lisp/eshell/em-dirs-tests.el b/test/lisp/eshell/em-dirs-tests.el
new file mode 100644
index 00000000000..8e96cc07471
--- /dev/null
+++ b/test/lisp/eshell/em-dirs-tests.el
@@ -0,0 +1,102 @@
+;;; em-dirs-tests.el --- em-dirs test suite -*- lexical-binding:t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Tests for Eshell's dirs module.
+
+;;; Code:
+
+(require 'ert)
+(require 'esh-mode)
+(require 'eshell)
+(require 'em-dirs)
+
+(require 'eshell-tests-helpers
+ (expand-file-name "eshell-tests-helpers"
+ (file-name-directory (or load-file-name
+ default-directory))))
+;;; Tests:
+
+(ert-deftest em-dirs-test/pwd-var ()
+ "Test using the $PWD variable."
+ (let ((default-directory "/some/path"))
+ (should (equal (eshell-test-command-result "echo $PWD")
+ (expand-file-name default-directory)))))
+
+(ert-deftest em-dirs-test/pwd-var-indices ()
+ "Test using the $PWD variable with indices."
+ (let ((default-directory "/some/path/here"))
+ (should (equal (eshell-test-command-result "echo $PWD[/ 1]")
+ "some"))
+ (should (equal (eshell-test-command-result "echo $PWD[/ 1 3]")
+ '("some" "here")))))
+
+(ert-deftest em-dirs-test/short-pwd-var ()
+ "Test using the $+ (current directory) variable."
+ (let ((default-directory "/some/path"))
+ (should (equal (eshell-test-command-result "echo $+")
+ (expand-file-name default-directory)))))
+
+(ert-deftest em-dirs-test/oldpwd-var ()
+ "Test using the $OLDPWD variable."
+ (let (eshell-last-dir-ring-file-name)
+ (with-temp-eshell
+ (eshell-command-result-p "echo $OLDPWD"
+ "\\`\\'")
+ (ring-insert eshell-last-dir-ring "/some/path")
+ (eshell-command-result-p "echo $OLDPWD"
+ "/some/path\n"))))
+
+(ert-deftest em-dirs-test/oldpwd-var-indices ()
+ "Test using the $OLDPWD variable with indices."
+ (let (eshell-last-dir-ring-file-name)
+ (with-temp-eshell
+ (ring-insert eshell-last-dir-ring "/some/path/here")
+ (eshell-command-result-p "echo $OLDPWD[/ 1]"
+ "some\n")
+ (eshell-command-result-p "echo $OLDPWD[/ 1 3]"
+ "(\"some\" \"here\")\n"))))
+
+(ert-deftest em-dirs-test/directory-ring-var ()
+ "Test using the $- (directory ring) variable."
+ (let (eshell-last-dir-ring-file-name)
+ (with-temp-eshell
+ (eshell-command-result-p "echo $-"
+ "\\`\\'")
+ (ring-insert eshell-last-dir-ring "/some/path")
+ (ring-insert eshell-last-dir-ring "/other/path")
+ (eshell-command-result-p "echo $-"
+ "/other/path\n")
+ (eshell-command-result-p "echo $-[0]"
+ "/other/path\n")
+ (eshell-command-result-p "echo $-[1]"
+ "/some/path\n"))))
+
+(ert-deftest em-dirs-test/directory-ring-var-indices ()
+ "Test using the $- (directory ring) variable with multiple indices."
+ (let (eshell-last-dir-ring-file-name)
+ (with-temp-eshell
+ (ring-insert eshell-last-dir-ring "/some/path/here")
+ (eshell-command-result-p "echo $-[0][/ 1]"
+ "some\n")
+ (eshell-command-result-p "echo $-[1][/ 1 3]"
+ "(\"some\" \"here\")\n"))))
+
+;; em-dirs-tests.el ends here
diff --git a/test/lisp/eshell/em-extpipe-tests.el b/test/lisp/eshell/em-extpipe-tests.el
new file mode 100644
index 00000000000..29f5dc05512
--- /dev/null
+++ b/test/lisp/eshell/em-extpipe-tests.el
@@ -0,0 +1,205 @@
+;;; em-extpipe-tests.el --- em-extpipe test suite -*- lexical-binding:t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+
+;; Author: Sean Whitton <spwhitton@spwhitton.name>
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'ert)
+(require 'ert-x)
+(require 'em-extpipe)
+(require 'eshell-tests-helpers
+ (expand-file-name "eshell-tests-helpers"
+ (file-name-directory (or load-file-name
+ default-directory))))
+
+(defmacro em-extpipe-tests--deftest (name input &rest body)
+ (declare (indent 2))
+ `(ert-deftest ,name ()
+ (cl-macrolet
+ ((should-parse (expected)
+ `(let ((shell-file-name "sh")
+ (shell-command-switch "-c"))
+ ;; Strip `eshell-trap-errors'.
+ (should (equal ,expected
+ (cadr (eshell-parse-command input))))))
+ (with-substitute-for-temp (&rest body)
+ ;; Substitute name of an actual temporary file and/or
+ ;; buffer into `input'. The substitution logic is
+ ;; appropriate for only the use we put it to in this file.
+ `(ert-with-temp-file temp
+ (let ((temp-buffer (generate-new-buffer " *temp*" t)))
+ (unwind-protect
+ (let ((input
+ (replace-regexp-in-string
+ "temp\\([^>]\\|\\'\\)" temp
+ (string-replace "#<buffer temp>"
+ (buffer-name temp-buffer)
+ input))))
+ ,@body)
+ (when (buffer-name temp-buffer)
+ (kill-buffer temp-buffer))))))
+ (temp-should-string= (expected)
+ `(string= ,expected (string-trim-right
+ (with-temp-buffer
+ (insert-file-contents temp)
+ (buffer-string)))))
+ (temp-buffer-should-string= (expected)
+ `(string= ,expected (string-trim-right
+ (with-current-buffer temp-buffer
+ (buffer-string))))))
+ (skip-unless shell-file-name)
+ (skip-unless shell-command-switch)
+ (skip-unless (executable-find shell-file-name))
+ (let ((input ,input))
+ (with-temp-eshell ,@body)))))
+
+(em-extpipe-tests--deftest em-extpipe-test-1
+ "echo \"bar\" *| rev >temp"
+ (skip-unless (executable-find "rev"))
+ (should-parse '(eshell-named-command
+ "sh" (list "-c" "echo \"bar\" | rev >temp")))
+ (with-substitute-for-temp
+ (eshell-command-result-p input "^$")
+ (temp-should-string= "rab")))
+
+(em-extpipe-tests--deftest em-extpipe-test-2
+ "echo \"bar\" | rev *>temp"
+ (skip-unless (executable-find "rev"))
+ (should-parse
+ '(eshell-execute-pipeline
+ '((eshell-named-command "echo" (list (eshell-escape-arg "bar")))
+ (eshell-named-command "sh" (list "-c" "rev >temp")))))
+ (with-substitute-for-temp
+ (eshell-command-result-p input "^$")
+ (temp-should-string= "rab")))
+
+(em-extpipe-tests--deftest em-extpipe-test-3 "foo *| bar | baz -d"
+ (should-parse
+ '(eshell-execute-pipeline
+ '((eshell-named-command "sh" (list "-c" "foo | bar"))
+ (eshell-named-command "baz" (list "-d"))))))
+
+(em-extpipe-tests--deftest em-extpipe-test-4
+ "echo \"bar\" *| rev >#<buffer temp>"
+ (skip-unless (executable-find "rev"))
+ (should-parse
+ '(progn
+ (ignore
+ (eshell-set-output-handle 1 'overwrite
+ (get-buffer-create "temp")))
+ (eshell-named-command "sh"
+ (list "-c" "echo \"bar\" | rev"))))
+ (with-substitute-for-temp
+ (eshell-command-result-p input "^$")
+ (temp-buffer-should-string= "rab")))
+
+(em-extpipe-tests--deftest em-extpipe-test-5
+ "foo *| bar >#<buffer quux> baz"
+ (should-parse '(eshell-named-command
+ "sh" (list "-c" "foo | bar >#<buffer quux> baz"))))
+
+(em-extpipe-tests--deftest em-extpipe-test-6
+ "foo >#<buffer quux> *| bar baz"
+ (should-parse '(eshell-named-command
+ "sh" (list "-c" "foo >#<buffer quux> | bar baz"))))
+
+(em-extpipe-tests--deftest em-extpipe-test-7
+ "foo *| bar >#<buffer quux> >>#<process other>"
+ (should-parse
+ '(progn
+ (ignore
+ (eshell-set-output-handle 1 'overwrite
+ (get-buffer-create "quux")))
+ (ignore
+ (eshell-set-output-handle 1 'append
+ (get-process "other")))
+ (eshell-named-command "sh"
+ (list "-c" "foo | bar")))))
+
+(em-extpipe-tests--deftest em-extpipe-test-8
+ "foo *| bar >/dev/kill | baz"
+ (should-parse
+ '(eshell-execute-pipeline
+ '((progn
+ (ignore
+ (eshell-set-output-handle 1 'overwrite "/dev/kill"))
+ (eshell-named-command "sh"
+ (list "-c" "foo | bar")))
+ (eshell-named-command "baz")))))
+
+(em-extpipe-tests--deftest em-extpipe-test-9 "foo \\*| bar"
+ (should-parse
+ '(eshell-execute-pipeline
+ '((eshell-named-command "foo"
+ (list (eshell-escape-arg "*")))
+ (eshell-named-command "bar")))))
+
+(em-extpipe-tests--deftest em-extpipe-test-10 "foo \"*|\" *>bar"
+ (should-parse
+ '(eshell-named-command "sh" (list "-c" "foo \"*|\" >bar"))))
+
+(em-extpipe-tests--deftest em-extpipe-test-11 "foo '*|' bar"
+ (should-parse '(eshell-named-command
+ "foo" (list (eshell-escape-arg "*|") "bar"))))
+
+(em-extpipe-tests--deftest em-extpipe-test-12 ">foo bar *| baz"
+ (should-parse
+ '(eshell-named-command "sh" (list "-c" ">foo bar | baz"))))
+
+(em-extpipe-tests--deftest em-extpipe-test-13 "foo*|bar"
+ (should-parse '(eshell-execute-pipeline
+ '((eshell-named-command (eshell-concat nil "foo" "*"))
+ (eshell-named-command "bar")))))
+
+(em-extpipe-tests--deftest em-extpipe-test-14 "tac *<temp"
+ (skip-unless (executable-find "tac"))
+ (should-parse '(eshell-named-command "sh" (list "-c" "tac <temp")))
+ (with-substitute-for-temp
+ (with-temp-buffer (insert "bar\nbaz\n") (write-file temp))
+ (eshell-command-result-p input "baz\nbar")))
+
+(em-extpipe-tests--deftest em-extpipe-test-15 "echo \"bar\" *| cat"
+ (skip-unless (executable-find "cat"))
+ (should-parse
+ '(eshell-named-command "sh" (list "-c" "echo \"bar\" | cat")))
+ (cl-letf (((symbol-function 'eshell/cat)
+ (lambda (&rest _args) (eshell-print "nonsense"))))
+ (eshell-command-result-p input "bar")
+ (eshell-command-result-p "echo \"bar\" | cat" "nonsense")))
+
+(em-extpipe-tests--deftest em-extpipe-test-16 "echo \"bar\" *| rev"
+ (skip-unless (executable-find "rev"))
+ (should-parse
+ '(eshell-named-command "sh" (list "-c" "echo \"bar\" | rev")))
+ (let ((eshell-prefer-lisp-functions t))
+ (cl-letf (((symbol-function 'rev)
+ (lambda (&rest _args) (eshell-print "nonsense"))))
+ (eshell-command-result-p input "rab")
+ (eshell-command-result-p "echo \"bar\" | rev" "nonsense"))))
+
+;; Confirm we don't break input of sharp-quoted symbols (Bug#53518).
+(em-extpipe-tests--deftest em-extpipe-test-17 "funcall #'upcase foo"
+ (eshell-command-result-p input "FOO"))
+
+;;; em-extpipe-tests.el ends here
diff --git a/test/lisp/eshell/em-glob-tests.el b/test/lisp/eshell/em-glob-tests.el
new file mode 100644
index 00000000000..b733be35d9a
--- /dev/null
+++ b/test/lisp/eshell/em-glob-tests.el
@@ -0,0 +1,197 @@
+;;; em-glob-tests.el --- em-glob test suite -*- lexical-binding:t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Tests for Eshell's glob expansion.
+
+;;; Code:
+
+(require 'ert)
+(require 'em-glob)
+
+(defmacro with-fake-files (files &rest body)
+ "Evaluate BODY forms, pretending that FILES exist on the filesystem.
+FILES is a list of file names that should be reported as
+appropriate by `file-name-all-completions'. Any file name
+component ending in \"symlink\" is treated as a symbolic link."
+ (declare (indent 1))
+ `(cl-letf (((symbol-function 'file-name-all-completions)
+ (lambda (file directory)
+ (cl-assert (string= file ""))
+ (setq directory (expand-file-name directory))
+ `("./" "../"
+ ,@(delete-dups
+ (remq nil
+ (mapcar
+ (lambda (file)
+ (setq file (expand-file-name file))
+ (when (string-prefix-p directory file)
+ (replace-regexp-in-string
+ "/.*" "/"
+ (substring file (length directory)))))
+ ,files))))))
+ ((symbol-function 'file-symlink-p)
+ (lambda (file)
+ (string-suffix-p "symlink" file))))
+ ,@body))
+
+;;; Tests:
+
+(ert-deftest em-glob-test/match-any-string ()
+ "Test that \"*\" pattern matches any string."
+ (with-fake-files '("a.el" "b.el" "c.txt" "dir/a.el")
+ (should (equal (eshell-extended-glob "*.el")
+ '("a.el" "b.el")))))
+
+(ert-deftest em-glob-test/match-any-directory ()
+ "Test that \"*/\" pattern matches any directory."
+ (with-fake-files '("a.el" "b.el" "dir/a.el" "dir/sub/a.el" "symlink/")
+ (should (equal (eshell-extended-glob "*/")
+ '("dir/" "symlink/")))))
+
+(ert-deftest em-glob-test/match-any-character ()
+ "Test that \"?\" pattern matches any character."
+ (with-fake-files '("a.el" "b.el" "ccc.el" "d.txt" "dir/a.el")
+ (should (equal (eshell-extended-glob "?.el")
+ '("a.el" "b.el")))))
+
+(ert-deftest em-glob-test/match-recursive ()
+ "Test that \"**/\" recursively matches directories."
+ (with-fake-files '("a.el" "b.el" "ccc.el" "d.txt" "dir/a.el" "dir/sub/a.el"
+ "dir/symlink/a.el" "symlink/a.el" "symlink/sub/a.el")
+ (should (equal (eshell-extended-glob "**/a.el")
+ '("a.el" "dir/a.el" "dir/sub/a.el")))
+ (should (equal (eshell-extended-glob "**/")
+ '("dir/" "dir/sub/")))))
+
+(ert-deftest em-glob-test/match-recursive-follow-symlinks ()
+ "Test that \"***/\" recursively matches directories, following symlinks."
+ (with-fake-files '("a.el" "b.el" "ccc.el" "d.txt" "dir/a.el" "dir/sub/a.el"
+ "dir/symlink/a.el" "symlink/a.el" "symlink/sub/a.el")
+ (should (equal (eshell-extended-glob "***/a.el")
+ '("a.el" "dir/a.el" "dir/sub/a.el" "dir/symlink/a.el"
+ "symlink/a.el" "symlink/sub/a.el")))
+ (should (equal (eshell-extended-glob "***/")
+ '("dir/" "dir/sub/" "dir/symlink/" "symlink/"
+ "symlink/sub/")))))
+
+(ert-deftest em-glob-test/match-recursive-mixed ()
+ "Test combination of \"**/\" and \"***/\"."
+ (with-fake-files '("dir/a.el" "dir/sub/a.el" "dir/sub2/a.el"
+ "dir/symlink/a.el" "dir/sub/symlink/a.el" "symlink/a.el"
+ "symlink/sub/a.el" "symlink/sub/symlink/a.el")
+ (should (equal (eshell-extended-glob "**/sub/***/a.el")
+ '("dir/sub/a.el" "dir/sub/symlink/a.el")))
+ (should (equal (eshell-extended-glob "***/sub/**/a.el")
+ '("dir/sub/a.el" "symlink/sub/a.el")))))
+
+(ert-deftest em-glob-test/match-character-set-individual ()
+ "Test \"[...]\" for individual characters."
+ (with-fake-files '("a.el" "b.el" "c.el" "d.el" "dir/a.el")
+ (should (equal (eshell-extended-glob "[ab].el")
+ '("a.el" "b.el")))
+ (should (equal (eshell-extended-glob "[^ab].el")
+ '("c.el" "d.el")))))
+
+(ert-deftest em-glob-test/match-character-set-range ()
+ "Test \"[...]\" for character ranges."
+ (with-fake-files '("a.el" "b.el" "c.el" "d.el" "dir/a.el")
+ (should (equal (eshell-extended-glob "[a-c].el")
+ '("a.el" "b.el" "c.el")))
+ (should (equal (eshell-extended-glob "[^a-c].el")
+ '("d.el")))))
+
+(ert-deftest em-glob-test/match-character-set-class ()
+ "Test \"[...]\" for character classes."
+ (with-fake-files '("1.el" "a.el" "b.el" "c.el" "dir/a.el")
+ (should (equal (eshell-extended-glob "[[:alpha:]].el")
+ '("a.el" "b.el" "c.el")))
+ (should (equal (eshell-extended-glob "[^[:alpha:]].el")
+ '("1.el")))))
+
+(ert-deftest em-glob-test/match-character-set-mixed ()
+ "Test \"[...]\" with multiple kinds of members at once."
+ (with-fake-files '("1.el" "a.el" "b.el" "c.el" "d.el" "dir/a.el")
+ (should (equal (eshell-extended-glob "[ac-d[:digit:]].el")
+ '("1.el" "a.el" "c.el" "d.el")))
+ (should (equal (eshell-extended-glob "[^ac-d[:digit:]].el")
+ '("b.el")))))
+
+(ert-deftest em-glob-test/match-group-alternative ()
+ "Test \"(x|y)\" matches either \"x\" or \"y\"."
+ (with-fake-files '("em-alias.el" "em-banner.el" "esh-arg.el" "misc.el"
+ "test/em-xtra.el")
+ (should (equal (eshell-extended-glob "e(m|sh)-*.el")
+ '("em-alias.el" "em-banner.el" "esh-arg.el")))))
+
+(ert-deftest em-glob-test/match-n-or-more-characters ()
+ "Test that \"x#\" and \"x#\" match zero or more instances of \"x\"."
+ (with-fake-files '("h.el" "ha.el" "hi.el" "hii.el" "dir/hi.el")
+ (should (equal (eshell-extended-glob "hi#.el")
+ '("h.el" "hi.el" "hii.el")))
+ (should (equal (eshell-extended-glob "hi##.el")
+ '("hi.el" "hii.el")))))
+
+(ert-deftest em-glob-test/match-n-or-more-groups ()
+ "Test that \"(x)#\" and \"(x)#\" match zero or more instances of \"(x)\"."
+ (with-fake-files '("h.el" "ha.el" "hi.el" "hii.el" "dir/hi.el")
+ (should (equal (eshell-extended-glob "hi#.el")
+ '("h.el" "hi.el" "hii.el")))
+ (should (equal (eshell-extended-glob "hi##.el")
+ '("hi.el" "hii.el")))))
+
+(ert-deftest em-glob-test/match-n-or-more-character-sets ()
+ "Test that \"[x]#\" and \"[x]#\" match zero or more instances of \"[x]\"."
+ (with-fake-files '("w.el" "wh.el" "wha.el" "whi.el" "whaha.el" "dir/wha.el")
+ (should (equal (eshell-extended-glob "w[ah]#.el")
+ '("w.el" "wh.el" "wha.el" "whaha.el")))
+ (should (equal (eshell-extended-glob "w[ah]##.el")
+ '("wh.el" "wha.el" "whaha.el")))))
+
+(ert-deftest em-glob-test/match-x-but-not-y ()
+ "Test that \"x~y\" matches \"x\" but not \"y\"."
+ (with-fake-files '("1" "12" "123" "42" "dir/1")
+ (should (equal (eshell-extended-glob "[[:digit:]]##~4?")
+ '("1" "12" "123")))))
+
+(ert-deftest em-glob-test/match-dot-files ()
+ "Test that dot files are matched correctly."
+ (with-fake-files '("foo.el" ".emacs")
+ (should (equal (eshell-extended-glob ".*")
+ '("../" "./" ".emacs")))
+ (let (eshell-glob-include-dot-dot)
+ (should (equal (eshell-extended-glob ".*")
+ '(".emacs"))))
+ (let ((eshell-glob-include-dot-files t))
+ (should (equal (eshell-extended-glob "*")
+ '("../" "./" ".emacs" "foo.el")))
+ (let (eshell-glob-include-dot-dot)
+ (should (equal (eshell-extended-glob "*")
+ '(".emacs" "foo.el")))))))
+
+(ert-deftest em-glob-test/no-matches ()
+ "Test behavior when a glob fails to match any files."
+ (with-fake-files '("foo.el" "bar.el")
+ (should (equal (eshell-extended-glob "*.txt")
+ "*.txt"))
+ (let ((eshell-error-if-no-glob t))
+ (should-error (eshell-extended-glob "*.txt")))))
+
+;; em-glob-tests.el ends here
diff --git a/test/lisp/eshell/em-hist-tests.el b/test/lisp/eshell/em-hist-tests.el
index c598ce7d4f0..634e9819839 100644
--- a/test/lisp/eshell/em-hist-tests.el
+++ b/test/lisp/eshell/em-hist-tests.el
@@ -20,19 +20,18 @@
;;; Code:
(require 'ert)
+(require 'ert-x)
(require 'em-hist)
(ert-deftest eshell-write-readonly-history ()
"Test that having read-only strings in history is okay."
- (let ((histfile (make-temp-file "eshell-history"))
- (eshell-history-ring (make-ring 2)))
- (ring-insert eshell-history-ring
- (propertize "echo foo" 'read-only t))
- (ring-insert eshell-history-ring
- (propertize "echo bar" 'read-only t))
- (unwind-protect
- (eshell-write-history histfile)
- (delete-file histfile))))
+ (ert-with-temp-file histfile
+ (let ((eshell-history-ring (make-ring 2)))
+ (ring-insert eshell-history-ring
+ (propertize "echo foo" 'read-only t))
+ (ring-insert eshell-history-ring
+ (propertize "echo bar" 'read-only t))
+ (eshell-write-history histfile))))
(provide 'em-hist-test)
diff --git a/test/lisp/eshell/em-ls-tests.el b/test/lisp/eshell/em-ls-tests.el
index 2f739979169..272280e81c7 100644
--- a/test/lisp/eshell/em-ls-tests.el
+++ b/test/lisp/eshell/em-ls-tests.el
@@ -25,30 +25,30 @@
;;; Code:
(require 'ert)
+(require 'ert-x)
(require 'em-ls)
(require 'dired)
(ert-deftest em-ls-test-bug27631 ()
"Test for https://debbugs.gnu.org/27631 ."
- (let* ((dir (make-temp-file "bug27631" 'dir))
- (dir1 (expand-file-name "dir1" dir))
- (dir2 (expand-file-name "dir2" dir))
- (default-directory dir)
- (orig eshell-ls-use-in-dired)
- buf)
- (unwind-protect
- (progn
- (customize-set-value 'eshell-ls-use-in-dired t)
- (make-directory dir1)
- (make-directory dir2)
- (with-temp-file (expand-file-name "a.txt" dir1))
- (with-temp-file (expand-file-name "b.txt" dir2))
- (setq buf (dired (expand-file-name "dir*/*.txt" dir)))
- (dired-toggle-marks)
- (should (cdr (dired-get-marked-files))))
- (customize-set-variable 'eshell-ls-use-in-dired orig)
- (delete-directory dir 'recursive)
- (when (buffer-live-p buf) (kill-buffer buf)))))
+ (ert-with-temp-directory dir
+ (let* ((dir1 (expand-file-name "dir1" dir))
+ (dir2 (expand-file-name "dir2" dir))
+ (default-directory dir)
+ (orig eshell-ls-use-in-dired)
+ buf)
+ (unwind-protect
+ (progn
+ (customize-set-value 'eshell-ls-use-in-dired t)
+ (make-directory dir1)
+ (make-directory dir2)
+ (with-temp-file (expand-file-name "a.txt" dir1))
+ (with-temp-file (expand-file-name "b.txt" dir2))
+ (setq buf (dired (expand-file-name "dir*/*.txt" dir)))
+ (dired-toggle-marks)
+ (should (cdr (dired-get-marked-files))))
+ (customize-set-variable 'eshell-ls-use-in-dired orig)
+ (when (buffer-live-p buf) (kill-buffer buf))))))
(ert-deftest em-ls-test-bug27817 ()
"Test for https://debbugs.gnu.org/27817 ."
diff --git a/test/lisp/eshell/em-pred-tests.el b/test/lisp/eshell/em-pred-tests.el
new file mode 100644
index 00000000000..c8c1a6a9317
--- /dev/null
+++ b/test/lisp/eshell/em-pred-tests.el
@@ -0,0 +1,566 @@
+;;; em-pred-tests.el --- em-pred test suite -*- lexical-binding:t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Tests for Eshell's argument predicates/modifiers.
+
+;;; Code:
+
+(require 'ert)
+(require 'esh-mode)
+(require 'eshell)
+(require 'em-glob)
+(require 'em-pred)
+
+(require 'eshell-tests-helpers
+ (expand-file-name "eshell-tests-helpers"
+ (file-name-directory (or load-file-name
+ default-directory))))
+
+(defvar eshell-test-value nil)
+
+(defun eshell-eval-predicate (initial-value predicate)
+ "Evaluate PREDICATE on INITIAL-VALUE, returning the result.
+PREDICATE is an Eshell argument predicate/modifier."
+ (let ((eshell-test-value initial-value))
+ (ignore-errors
+ (eshell-test-command-result
+ (format "echo $eshell-test-value(%s)" predicate)))))
+
+(defun eshell-parse-file-name-attributes (file)
+ "Parse a fake FILE name to determine its attributes.
+Fake file names are file names beginning with \"/fake/\". This
+allows defining file names for fake files with various properties
+to query via predicates. Attributes are written as a
+comma-separate list of ATTR=VALUE pairs as the file's base name,
+like:
+
+ /fake/type=-,modes=0755.el
+
+The following attributes are recognized:
+
+ * \"type\": A single character describing the file type;
+ accepts the same values as the first character of the file
+ modes in `ls -l'.
+ * \"modes\": The file's permission modes, in octal.
+ * \"links\": The number of links to this file.
+ * \"uid\": The UID of the file's owner.
+ * \"gid\": The UID of the file's group.
+ * \"atime\": The time the file was last accessed, in seconds
+ since the UNIX epoch.
+ * \"mtime\": As \"atime\", but for modification time.
+ * \"ctime\": As \"atime\", but for inode change time.
+ * \"size\": The file's size in bytes."
+ (mapcar (lambda (i)
+ (pcase (split-string i "=")
+ (`("modes" ,modes)
+ (cons 'modes (string-to-number modes 8)))
+ (`(,(and (or "links" "uid" "gid" "size") key) ,value)
+ (cons (intern key) (string-to-number value)))
+ (`(,(and (or "atime" "mtime" "ctime") key) ,value)
+ (cons (intern key) (time-convert (string-to-number value))))
+ (`(,key ,value)
+ (cons (intern key) value))
+ (_ (error "invalid format %S" i))))
+ (split-string (file-name-base file) ",")))
+
+(defmacro eshell-partial-let-func (overrides &rest body)
+ "Temporarily bind to FUNCTION-NAMEs and evaluate BODY.
+This is roughly analogous to advising functions, but only does so
+while BODY is executing, and only calls NEW-FUNCTION if its first
+argument is a string beginning with \"/fake/\".
+
+This allows selectively overriding functions to test file
+properties with fake files without altering the functions'
+behavior for real files.
+
+\(fn ((FUNCTION-NAME NEW-FUNCTION) ...) BODY...)"
+ (declare (indent 1))
+ `(cl-letf
+ ,(mapcar
+ (lambda (override)
+ `((symbol-function #',(car override))
+ (let ((orig-function (symbol-function #',(car override))))
+ (lambda (file &rest rest)
+ (apply
+ (if (and (stringp file) (string-prefix-p "/fake/" file))
+ ,(cadr override)
+ orig-function)
+ file rest)))))
+ overrides)
+ ,@body))
+
+(defmacro eshell-with-file-attributes-from-name (&rest body)
+ "Temporarily override file attribute functions and evaluate BODY."
+ (declare (indent 0))
+ `(eshell-partial-let-func
+ ((file-attributes
+ (lambda (file &optional _id-format)
+ (let ((attrs (eshell-parse-file-name-attributes file)))
+ (list (equal (alist-get 'type attrs) "d")
+ (or (alist-get 'links attrs) 1)
+ (or (alist-get 'uid attrs) 0)
+ (or (alist-get 'gid attrs) 0)
+ (or (alist-get 'atime attrs) nil)
+ (or (alist-get 'mtime attrs) nil)
+ (or (alist-get 'ctime attrs) nil)
+ (or (alist-get 'size attrs) 0)
+ (format "%s---------" (or (alist-get 'type attrs) "-"))
+ nil 0 0))))
+ (file-modes
+ (lambda (file _nofollow)
+ (let ((attrs (eshell-parse-file-name-attributes file)))
+ (or (alist-get 'modes attrs) 0))))
+ (file-exists-p #'always)
+ (file-regular-p
+ (lambda (file)
+ (let ((attrs (eshell-parse-file-name-attributes file)))
+ (member (or (alist-get 'type attrs) "-") '("-" "l")))))
+ (file-symlink-p
+ (lambda (file)
+ (let ((attrs (eshell-parse-file-name-attributes file)))
+ (equal (alist-get 'type attrs) "l"))))
+ (file-executable-p
+ (lambda (file)
+ (let ((attrs (eshell-parse-file-name-attributes file)))
+ ;; For simplicity, just return whether the file is
+ ;; world-executable.
+ (= (logand (or (alist-get 'modes attrs) 0) 1) 1)))))
+ ,@body))
+
+;;; Tests:
+
+
+;; Argument predicates
+
+(ert-deftest em-pred-test/predicate-file-types ()
+ "Test file type predicates."
+ (eshell-with-file-attributes-from-name
+ (let ((files (mapcar (lambda (i) (format "/fake/type=%s" i))
+ '("b" "c" "d/" "p" "s" "l" "-"))))
+ (should (equal (eshell-eval-predicate files "%")
+ '("/fake/type=b" "/fake/type=c")))
+ (should (equal (eshell-eval-predicate files "%b") '("/fake/type=b")))
+ (should (equal (eshell-eval-predicate files "%c") '("/fake/type=c")))
+ (should (equal (eshell-eval-predicate files "/") '("/fake/type=d/")))
+ (should (equal (eshell-eval-predicate files ".") '("/fake/type=-")))
+ (should (equal (eshell-eval-predicate files "p") '("/fake/type=p")))
+ (should (equal (eshell-eval-predicate files "=") '("/fake/type=s")))
+ (should (equal (eshell-eval-predicate files "@") '("/fake/type=l"))))))
+
+(ert-deftest em-pred-test/predicate-executable ()
+ "Test that \"*\" matches only regular, non-symlink executable files."
+ (eshell-with-file-attributes-from-name
+ (let ((files '("/fake/modes=0777" "/fake/modes=0666"
+ "/fake/type=d,modes=0777" "/fake/type=l,modes=0777")))
+ (should (equal (eshell-eval-predicate files "*")
+ '("/fake/modes=0777"))))))
+
+(defmacro em-pred-test--file-modes-deftest (name mode-template predicates
+ &optional docstring)
+ "Define NAME as a file-mode test.
+MODE-TEMPLATE is a format string to convert an integer from 0 to
+7 to an octal file mode. PREDICATES is a list of strings for the
+read, write, and execute predicates to query the file's modes."
+ (declare (indent 4) (doc-string 4))
+ `(ert-deftest ,name ()
+ ,docstring
+ (eshell-with-file-attributes-from-name
+ (let ((file-template (concat "/fake/modes=" ,mode-template)))
+ (cl-flet ((make-files (perms)
+ (mapcar (lambda (i) (format file-template i))
+ perms)))
+ (pcase-let ((files (make-files (number-sequence 0 7)))
+ (`(,read ,write ,exec) ,predicates))
+ (should (equal (eshell-eval-predicate files read)
+ (make-files '(4 5 6 7))))
+ (should (equal (eshell-eval-predicate files (concat "^" read))
+ (make-files '(0 1 2 3))))
+ (should (equal (eshell-eval-predicate files write)
+ (make-files '(2 3 6 7))))
+ (should (equal (eshell-eval-predicate files (concat "^" write))
+ (make-files '(0 1 4 5))))
+ (should (equal (eshell-eval-predicate files exec)
+ (make-files '(1 3 5 7))))
+ (should (equal (eshell-eval-predicate files (concat "^" exec))
+ (make-files '(0 2 4 6))))))))))
+
+(em-pred-test--file-modes-deftest em-pred-test/predicate-file-modes-owner
+ "0%o00" '("r" "w" "x")
+ "Test predicates for file permissions for the owner.")
+
+(em-pred-test--file-modes-deftest em-pred-test/predicate-file-modes-group
+ "00%o0" '("A" "I" "E")
+ "Test predicates for file permissions for the group.")
+
+(em-pred-test--file-modes-deftest em-pred-test/predicate-file-modes-world
+ "000%o" '("R" "W" "X")
+ "Test predicates for file permissions for the world.")
+
+(em-pred-test--file-modes-deftest em-pred-test/predicate-file-modes-flags
+ "%o000" '("s" "S" "t")
+ "Test predicates for \"s\" (setuid), \"S\" (setgid), and \"t\" (sticky).")
+
+(ert-deftest em-pred-test/predicate-effective-uid ()
+ "Test that \"U\" matches files owned by the effective UID."
+ (eshell-with-file-attributes-from-name
+ (cl-letf (((symbol-function 'user-uid) (lambda () 1)))
+ (let ((files '("/fake/uid=1" "/fake/uid=2")))
+ (should (equal (eshell-eval-predicate files "U")
+ '("/fake/uid=1")))))))
+
+(ert-deftest em-pred-test/predicate-effective-gid ()
+ "Test that \"G\" matches files owned by the effective GID."
+ (eshell-with-file-attributes-from-name
+ (cl-letf (((symbol-function 'group-gid) (lambda () 1)))
+ (let ((files '("/fake/gid=1" "/fake/gid=2")))
+ (should (equal (eshell-eval-predicate files "G")
+ '("/fake/gid=1")))))))
+
+(ert-deftest em-pred-test/predicate-links ()
+ "Test that \"l\" filters by number of links."
+ (eshell-with-file-attributes-from-name
+ (let ((files '("/fake/links=1" "/fake/links=2" "/fake/links=3")))
+ (should (equal (eshell-eval-predicate files "l1")
+ '("/fake/links=1")))
+ (should (equal (eshell-eval-predicate files "l+1")
+ '("/fake/links=2" "/fake/links=3")))
+ (should (equal (eshell-eval-predicate files "l-3")
+ '("/fake/links=1" "/fake/links=2"))))))
+
+(ert-deftest em-pred-test/predicate-uid ()
+ "Test that \"u\" filters by UID/user name."
+ (eshell-with-file-attributes-from-name
+ (let ((files '("/fake/uid=1" "/fake/uid=2"))
+ (user-names '("root" "one" "two")))
+ (should (equal (eshell-eval-predicate files "u1")
+ '("/fake/uid=1")))
+ (cl-letf (((symbol-function 'eshell-user-id)
+ (lambda (name) (seq-position user-names name))))
+ (should (equal (eshell-eval-predicate files "u'one'")
+ '("/fake/uid=1")))))))
+
+(ert-deftest em-pred-test/predicate-gid ()
+ "Test that \"g\" filters by GID/group name."
+ (eshell-with-file-attributes-from-name
+ (let ((files '("/fake/gid=1" "/fake/gid=2"))
+ (group-names '("root" "one" "two")))
+ (should (equal (eshell-eval-predicate files "g1")
+ '("/fake/gid=1")))
+ (cl-letf (((symbol-function 'eshell-group-id)
+ (lambda (name) (seq-position group-names name))))
+ (should (equal (eshell-eval-predicate files "g'one'")
+ '("/fake/gid=1")))))))
+
+(defmacro em-pred-test--time-deftest (name file-attribute predicate
+ &optional docstring)
+ "Define NAME as a file-time test.
+FILE-ATTRIBUTE is the file's attribute to set (e.g. \"atime\").
+PREDICATE is the predicate used to query that attribute."
+ (declare (indent 4) (doc-string 4))
+ `(ert-deftest ,name ()
+ ,docstring
+ (eshell-with-file-attributes-from-name
+ (cl-flet ((make-file (time)
+ (format "/fake/%s=%d" ,file-attribute time)))
+ (let* ((now (time-convert nil 'integer))
+ (yesterday (- now 86400))
+ (files (mapcar #'make-file (list now yesterday))))
+ ;; Test comparison against a number of days.
+ (should (equal (eshell-eval-predicate
+ files (concat ,predicate "-1"))
+ (mapcar #'make-file (list now))))
+ (should (equal (eshell-eval-predicate
+ files (concat ,predicate "+1"))
+ (mapcar #'make-file (list yesterday))))
+ (should (equal (eshell-eval-predicate
+ files (concat ,predicate "+2"))
+ nil))
+ ;; Test comparison against a number of hours.
+ (should (equal (eshell-eval-predicate
+ files (concat ,predicate "h-1"))
+ (mapcar #'make-file (list now))))
+ (should (equal (eshell-eval-predicate
+ files (concat ,predicate "h+1"))
+ (mapcar #'make-file (list yesterday))))
+ (should (equal (eshell-eval-predicate
+ files (concat ,predicate "+48"))
+ nil))
+ ;; Test comparison against another file.
+ (should (equal (eshell-eval-predicate
+ files (format "%s-'%s'" ,predicate (make-file now)))
+ nil))
+ (should (equal (eshell-eval-predicate
+ files (format "%s+'%s'" ,predicate (make-file now)))
+ (mapcar #'make-file (list yesterday)))))))))
+
+(em-pred-test--time-deftest em-pred-test/predicate-access-time
+ "atime" "a"
+ "Test that \"a\" filters by access time.")
+
+(em-pred-test--time-deftest em-pred-test/predicate-modification-time
+ "mtime" "m"
+ "Test that \"m\" filters by change time.")
+
+(em-pred-test--time-deftest em-pred-test/predicate-change-time
+ "ctime" "c"
+ "Test that \"c\" filters by change time.")
+
+(ert-deftest em-pred-test/predicate-size ()
+ "Test that \"L\" filters by file size."
+ (eshell-with-file-attributes-from-name
+ (let ((files '("/fake/size=0"
+ ;; 1 and 2 KiB.
+ "/fake/size=1024" "/fake/size=2048"
+ ;; 1 and 2 MiB.
+ "/fake/size=1048576" "/fake/size=2097152")))
+ ;; Size in bytes.
+ (should (equal (eshell-eval-predicate files "L2048")
+ '("/fake/size=2048")))
+ (should (equal (eshell-eval-predicate files "L+2048")
+ '("/fake/size=1048576" "/fake/size=2097152")))
+ (should (equal (eshell-eval-predicate files "L-2048")
+ '("/fake/size=0" "/fake/size=1024")))
+ ;; Size in blocks.
+ (should (equal (eshell-eval-predicate files "Lp4")
+ '("/fake/size=2048")))
+ (should (equal (eshell-eval-predicate files "Lp+4")
+ '("/fake/size=1048576" "/fake/size=2097152")))
+ (should (equal (eshell-eval-predicate files "Lp-4")
+ '("/fake/size=0" "/fake/size=1024")))
+ ;; Size in KiB.
+ (should (equal (eshell-eval-predicate files "Lk2")
+ '("/fake/size=2048")))
+ (should (equal (eshell-eval-predicate files "Lk+2")
+ '("/fake/size=1048576" "/fake/size=2097152")))
+ (should (equal (eshell-eval-predicate files "Lk-2")
+ '("/fake/size=0" "/fake/size=1024")))
+ ;; Size in MiB.
+ (should (equal (eshell-eval-predicate files "LM1")
+ '("/fake/size=1048576")))
+ (should (equal (eshell-eval-predicate files "LM+1")
+ '("/fake/size=2097152")))
+ (should (equal (eshell-eval-predicate files "LM-1")
+ '("/fake/size=0" "/fake/size=1024" "/fake/size=2048"))))))
+
+
+;; Argument modifiers
+
+(ert-deftest em-pred-test/modifier-eval ()
+ "Test that \":E\" re-evaluates the value."
+ (should (equal (eshell-eval-predicate "${echo hi}" ":E") "hi"))
+ (should (equal (eshell-eval-predicate
+ '("${echo hi}" "$(upcase \"bye\")") ":E")
+ '("hi" "BYE"))))
+
+(ert-deftest em-pred-test/modifier-downcase ()
+ "Test that \":L\" downcases values."
+ (should (equal (eshell-eval-predicate "FOO" ":L") "foo"))
+ (should (equal (eshell-eval-predicate '("FOO" "BAR") ":L")
+ '("foo" "bar"))))
+
+(ert-deftest em-pred-test/modifier-upcase ()
+ "Test that \":U\" upcases values."
+ (should (equal (eshell-eval-predicate "foo" ":U") "FOO"))
+ (should (equal (eshell-eval-predicate '("foo" "bar") ":U")
+ '("FOO" "BAR"))))
+
+(ert-deftest em-pred-test/modifier-capitalize ()
+ "Test that \":C\" capitalizes values."
+ (should (equal (eshell-eval-predicate "foo bar" ":C") "Foo Bar"))
+ (should (equal (eshell-eval-predicate '("foo bar" "baz") ":C")
+ '("Foo Bar" "Baz"))))
+
+(ert-deftest em-pred-test/modifier-dirname ()
+ "Test that \":h\" returns the dirname."
+ (should (equal (eshell-eval-predicate "/path/to/file.el" ":h") "/path/to/"))
+ (should (equal (eshell-eval-predicate
+ '("/path/to/file.el" "/other/path/") ":h")
+ '("/path/to/" "/other/path/"))))
+
+(ert-deftest em-pred-test/modifier-basename ()
+ "Test that \":t\" returns the basename."
+ (should (equal (eshell-eval-predicate "/path/to/file.el" ":t") "file.el"))
+ (should (equal (eshell-eval-predicate
+ '("/path/to/file.el" "/other/path/") ":t")
+ '("file.el" ""))))
+
+(ert-deftest em-pred-test/modifier-extension ()
+ "Test that \":e\" returns the extension."
+ (should (equal (eshell-eval-predicate "/path/to/file.el" ":e") "el"))
+ (should (equal (eshell-eval-predicate
+ '("/path/to/file.el" "/other/path/") ":e")
+ '("el" nil))))
+
+(ert-deftest em-pred-test/modifier-sans-extension ()
+ "Test that \":r\" returns the file name san extension."
+ (should (equal (eshell-eval-predicate "/path/to/file.el" ":r")
+ "/path/to/file"))
+ (should (equal (eshell-eval-predicate
+ '("/path/to/file.el" "/other/path/") ":r")
+ '("/path/to/file" "/other/path/"))))
+
+(ert-deftest em-pred-test/modifier-quote ()
+ "Test that \":q\" quotes arguments."
+ (should (equal-including-properties
+ (eshell-eval-predicate '("foo" "bar") ":q")
+ (list (eshell-escape-arg "foo") (eshell-escape-arg "bar")))))
+
+(ert-deftest em-pred-test/modifier-substitute ()
+ "Test that \":s/PAT/REP/\" replaces PAT with REP once."
+ (should (equal (eshell-eval-predicate "bar" ":s/a/*/") "b*r"))
+ (should (equal (eshell-eval-predicate "bar" ":s|a|*|") "b*r"))
+ (should (equal (eshell-eval-predicate "bar" ":s{a}{*}") "b*r"))
+ (should (equal (eshell-eval-predicate "bar" ":s{a}'*'") "b*r"))
+ (should (equal (eshell-eval-predicate '("foo" "bar" "baz") ":s/[ao]/*/")
+ '("f*o" "b*r" "b*z")))
+ (should (equal (eshell-eval-predicate '("foo" "bar" "baz") ":s|[ao]|*|")
+ '("f*o" "b*r" "b*z"))))
+
+(ert-deftest em-pred-test/modifier-global-substitute ()
+ "Test that \":s/PAT/REP/\" replaces PAT with REP for all occurrences."
+ (should (equal (eshell-eval-predicate "foo" ":gs/a/*/") "foo"))
+ (should (equal (eshell-eval-predicate "foo" ":gs|a|*|") "foo"))
+ (should (equal (eshell-eval-predicate "bar" ":gs/a/*/") "b*r"))
+ (should (equal (eshell-eval-predicate "bar" ":gs|a|*|") "b*r"))
+ (should (equal (eshell-eval-predicate "foo" ":gs/o/O/") "fOO"))
+ (should (equal (eshell-eval-predicate '("foo" "bar" "baz") ":gs/[aeiou]/*/")
+ '("f**" "b*r" "b*z")))
+ (should (equal (eshell-eval-predicate '("foo" "bar" "baz") ":gs|[aeiou]|*|")
+ '("f**" "b*r" "b*z"))))
+
+(ert-deftest em-pred-test/modifier-include ()
+ "Test that \":i/PAT/\" filters elements to include only ones matching PAT."
+ (should (equal (eshell-eval-predicate "foo" ":i/a/") nil))
+ (should (equal (eshell-eval-predicate "bar" ":i/a/") "bar"))
+ (should (equal (eshell-eval-predicate '("foo" "bar" "baz") ":i/a/")
+ '("bar" "baz"))))
+
+(ert-deftest em-pred-test/modifier-exclude ()
+ "Test that \":x/PAT/\" filters elements to exclude any matching PAT."
+ (should (equal (eshell-eval-predicate "foo" ":x/a/") "foo"))
+ (should (equal (eshell-eval-predicate "bar" ":x/a/") nil))
+ (should (equal (eshell-eval-predicate '("foo" "bar" "baz") ":x/a/")
+ '("foo"))))
+
+(ert-deftest em-pred-test/modifier-split ()
+ "Test that \":S\" and \":S/PAT/\" split elements by spaces (or PAT)."
+ (should (equal (eshell-eval-predicate "foo bar baz" ":S")
+ '("foo" "bar" "baz")))
+ (should (equal (eshell-eval-predicate '("foo bar" "baz") ":S")
+ '(("foo" "bar") ("baz"))))
+ (should (equal (eshell-eval-predicate "foo-bar-baz" ":S/-/")
+ '("foo" "bar" "baz")))
+ (should (equal (eshell-eval-predicate '("foo-bar" "baz") ":S/-/")
+ '(("foo" "bar") ("baz")))))
+
+(ert-deftest em-pred-test/modifier-join ()
+ "Test that \":j\" and \":j/DELIM/\" join elements by spaces (or DELIM)."
+ (should (equal (eshell-eval-predicate "foo" ":j") "foo"))
+ (should (equal (eshell-eval-predicate '("foo" "bar" "baz") ":j")
+ "foo bar baz"))
+ (should (equal (eshell-eval-predicate "foo" ":j/-/") "foo"))
+ (should (equal (eshell-eval-predicate '("foo" "bar" "baz") ":j/-/")
+ "foo-bar-baz")))
+
+(ert-deftest em-pred-test/modifier-sort ()
+ "Test that \":o\" sorts elements in lexicographic order."
+ (should (equal (eshell-eval-predicate "foo" ":o") "foo"))
+ (should (equal (eshell-eval-predicate '("foo" "bar" "baz") ":o")
+ '("bar" "baz" "foo"))))
+
+(ert-deftest em-pred-test/modifier-sort-reverse ()
+ "Test that \":o\" sorts elements in reverse lexicographic order."
+ (should (equal (eshell-eval-predicate "foo" ":O") "foo"))
+ (should (equal (eshell-eval-predicate '("foo" "bar" "baz") ":O")
+ '("foo" "baz" "bar"))))
+
+(ert-deftest em-pred-test/modifier-unique ()
+ "Test that \":u\" filters out duplicate elements."
+ (should (equal (eshell-eval-predicate "foo" ":u") "foo"))
+ (should (equal (eshell-eval-predicate '("foo" "bar" "baz") ":u")
+ '("foo" "bar" "baz")))
+ (should (equal (eshell-eval-predicate '("foo" "bar" "baz" "foo") ":u")
+ '("foo" "bar" "baz"))))
+
+(ert-deftest em-pred-test/modifier-reverse ()
+ "Test that \":r\" reverses the order of elements."
+ (should (equal (eshell-eval-predicate "foo" ":R") "foo"))
+ (should (equal (eshell-eval-predicate '("foo" "bar" "baz") ":R")
+ '("baz" "bar" "foo"))))
+
+
+;; Miscellaneous
+
+(ert-deftest em-pred-test/combine-predicate-and-modifier ()
+ "Test combination of predicates and modifiers."
+ (eshell-with-file-attributes-from-name
+ (let ((files '("/fake/type=-.el" "/fake/type=-.txt" "/fake/type=s.el"
+ "/fake/subdir/type=-.el")))
+ (should (equal (eshell-eval-predicate files ".:e:u")
+ '("el" "txt"))))))
+
+(ert-deftest em-pred-test/predicate-delimiters ()
+ "Test various delimiter pairs with predicates and modifiers."
+ (dolist (delims eshell-pred-delimiter-pairs)
+ (eshell-with-file-attributes-from-name
+ (let ((files '("/fake/uid=1" "/fake/uid=2"))
+ (user-names '("root" "one" "two")))
+ (cl-letf (((symbol-function 'eshell-user-id)
+ (lambda (name) (seq-position user-names name))))
+ (should (equal (eshell-eval-predicate
+ files (format "u%cone%c" (car delims) (cdr delims)))
+ '("/fake/uid=1"))))))
+ (should (equal (eshell-eval-predicate
+ '("foo" "bar" "baz")
+ (format ":j%c-%c" (car delims) (cdr delims)))
+ "foo-bar-baz"))))
+
+(ert-deftest em-pred-test/predicate-escaping ()
+ "Test string escaping in predicate and modifier parameters."
+ ;; Escaping the delimiter should remove the backslash.
+ (should (equal (eshell-eval-predicate '("foo" "bar" "baz") ":j'\\''")
+ "foo'bar'baz"))
+ ;; Escaping a backlash should remove the first backslash.
+ (should (equal (eshell-eval-predicate '("foo" "bar" "baz") ":j'\\\\'")
+ "foo\\bar\\baz"))
+ ;; Escaping a different character should keep the backslash.
+ (should (equal (eshell-eval-predicate '("foo" "bar" "baz") ":j'\\\"'")
+ "foo\\\"bar\\\"baz")))
+
+(ert-deftest em-pred-test/no-matches ()
+ "Test behavior when a predicate fails to match any files."
+ (eshell-with-file-attributes-from-name
+ (let ((files '("/fake/modes=0666" "/fake/type=d,modes=0777"
+ "/fake/type=l,modes=0777")))
+ (should (equal (eshell-eval-predicate files "*") nil))
+ (let ((eshell-error-if-no-glob t))
+ ;; Don't signal an error if the original list is empty.
+ (should (equal (eshell-eval-predicate nil "*") nil))
+ ;; Ensure this signals an error. This test case is a bit
+ ;; clumsy, since `eshell-do-eval' makes it hard to catch
+ ;; errors otherwise.
+ (let ((modifiers (with-temp-eshell
+ (eshell-with-temp-command "*"
+ (eshell-parse-modifiers)))))
+ (should-error (eshell-apply-modifiers files (car modifiers)
+ (cdr modifiers) "*")))))))
+
+;; em-pred-tests.el ends here
diff --git a/test/lisp/eshell/em-script-tests.el b/test/lisp/eshell/em-script-tests.el
new file mode 100644
index 00000000000..a34f9434021
--- /dev/null
+++ b/test/lisp/eshell/em-script-tests.el
@@ -0,0 +1,62 @@
+;;; em-script-tests.el --- em-script test suite -*- lexical-binding:t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Tests for Eshell's script module.
+
+;;; Code:
+
+(require 'ert)
+(require 'esh-mode)
+(require 'eshell)
+(require 'em-script)
+
+(require 'eshell-tests-helpers
+ (expand-file-name "eshell-tests-helpers"
+ (file-name-directory (or load-file-name
+ default-directory))))
+;;; Tests:
+
+(ert-deftest em-script-test/source-script ()
+ "Test sourcing script with no argumentss"
+ (ert-with-temp-file temp-file :text "echo hi"
+ (with-temp-eshell
+ (eshell-command-result-p (format "source %s" temp-file)
+ "hi\n"))))
+
+(ert-deftest em-script-test/source-script-arg-vars ()
+ "Test sourcing script with $0, $1, ... variables"
+ (ert-with-temp-file temp-file :text "printnl $0 \"$1 $2\""
+ (with-temp-eshell
+ (eshell-command-result-p (format "source %s one two" temp-file)
+ (format "%s\none two\n" temp-file)))))
+
+(ert-deftest em-script-test/source-script-all-args-var ()
+ "Test sourcing script with the $* variable"
+ (ert-with-temp-file temp-file :text "printnl $*"
+ (with-temp-eshell
+ (eshell-command-result-p (format "source %s" temp-file)
+ "\\`\\'")
+ (eshell-command-result-p (format "source %s a" temp-file)
+ "a\n")
+ (eshell-command-result-p (format "source %s a b c" temp-file)
+ "a\nb\nc\n"))))
+
+;; em-script-tests.el ends here
diff --git a/test/lisp/eshell/em-tramp-tests.el b/test/lisp/eshell/em-tramp-tests.el
new file mode 100644
index 00000000000..8969c1e2294
--- /dev/null
+++ b/test/lisp/eshell/em-tramp-tests.el
@@ -0,0 +1,88 @@
+;;; em-tramp-tests.el --- em-tramp test suite -*- lexical-binding:t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'ert)
+(require 'em-tramp)
+(require 'tramp)
+
+(ert-deftest em-tramp-test/su-default ()
+ "Test Eshell `su' command with no arguments."
+ (should (equal
+ (catch 'eshell-replace-command (eshell/su))
+ `(eshell-trap-errors
+ (eshell-named-command
+ "cd"
+ (list ,(format "/su:root@%s:%s"
+ tramp-default-host default-directory)))))))
+
+(ert-deftest em-tramp-test/su-user ()
+ "Test Eshell `su' command with USER argument."
+ (should (equal
+ (catch 'eshell-replace-command (eshell/su "USER"))
+ `(eshell-trap-errors
+ (eshell-named-command
+ "cd"
+ (list ,(format "/su:USER@%s:%s"
+ tramp-default-host default-directory)))))))
+
+(ert-deftest em-tramp-test/su-login ()
+ "Test Eshell `su' command with -/-l/--login option."
+ (dolist (args '(("--login")
+ ("-l")
+ ("-")))
+ (should (equal
+ (catch 'eshell-replace-command (apply #'eshell/su args))
+ `(eshell-trap-errors
+ (eshell-named-command
+ "cd"
+ (list ,(format "/su:root@%s:~/" tramp-default-host))))))))
+
+(defun mock-eshell-named-command (&rest args)
+ "Dummy function to test Eshell `sudo' command rewriting."
+ (list default-directory args))
+
+(ert-deftest em-tramp-test/sudo-basic ()
+ "Test Eshell `sudo' command with default user."
+ (cl-letf (((symbol-function 'eshell-named-command)
+ #'mock-eshell-named-command))
+ (should (equal
+ (catch 'eshell-external (eshell/sudo "echo" "hi"))
+ `(,(format "/sudo:root@%s:%s" tramp-default-host default-directory)
+ ("echo" ("hi")))))
+ (should (equal
+ (catch 'eshell-external (eshell/sudo "echo" "-u" "hi"))
+ `(,(format "/sudo:root@%s:%s" tramp-default-host default-directory)
+ ("echo" ("-u" "hi")))))))
+
+(ert-deftest em-tramp-test/sudo-user ()
+ "Test Eshell `sudo' command with specified user."
+ (cl-letf (((symbol-function 'eshell-named-command)
+ #'mock-eshell-named-command))
+ (should (equal
+ (catch 'eshell-external (eshell/sudo "-u" "USER" "echo" "hi"))
+ `(,(format "/sudo:USER@%s:%s" tramp-default-host default-directory)
+ ("echo" ("hi")))))
+ (should (equal
+ (catch 'eshell-external (eshell/sudo "-u" "USER" "echo" "-u" "hi"))
+ `(,(format "/sudo:USER@%s:%s" tramp-default-host default-directory)
+ ("echo" ("-u" "hi")))))))
+
+;;; em-tramp-tests.el ends here
diff --git a/test/lisp/eshell/esh-opt-tests.el b/test/lisp/eshell/esh-opt-tests.el
index 532adfb733a..5b30de414a3 100644
--- a/test/lisp/eshell/esh-opt-tests.el
+++ b/test/lisp/eshell/esh-opt-tests.el
@@ -22,102 +22,267 @@
(require 'ert)
(require 'esh-opt)
-(ert-deftest esh-opt-process-args-test ()
- "Unit tests which verify correct behavior of `eshell--process-args'."
+(ert-deftest esh-opt-test/process-args ()
+ "Test behavior of `eshell--process-args'."
(should
(equal '(t)
(eshell--process-args
- "sudo"
- '("-a")
- '((?a "all" nil show-all "")))))
- (should
- (equal '(nil)
- (eshell--process-args
- "sudo"
- '("-g")
- '((?a "all" nil show-all "")))))
+ "sudo" '("-a")
+ '((?a "all" nil show-all
+ "do not ignore entries starting with .")))))
(should
(equal '("root" "world")
(eshell--process-args
- "sudo"
- '("-u" "root" "world")
- '((?u "user" t user "execute a command as another USER")))))
+ "sudo" '("-u" "root" "world")
+ '((?u "user" t user
+ "execute a command as another USER"))))))
+
+(ert-deftest esh-opt-test/process-args-parse-leading-options-only ()
+ "Test behavior of :parse-leading-options-only in `eshell--process-args'."
(should
(equal '(nil "emerge" "-uDN" "world")
(eshell--process-args
- "sudo"
- '("emerge" "-uDN" "world")
- '((?u "user" t user "execute a command as another USER")
+ "sudo" '("emerge" "-uDN" "world")
+ '((?u "user" t user
+ "execute a command as another USER")
:parse-leading-options-only))))
(should
(equal '("root" "emerge" "-uDN" "world")
(eshell--process-args
- "sudo"
- '("-u" "root" "emerge" "-uDN" "world")
- '((?u "user" t user "execute a command as another USER")
+ "sudo" '("-u" "root" "emerge" "-uDN" "world")
+ '((?u "user" t user
+ "execute a command as another USER")
:parse-leading-options-only))))
(should
- (equal '("world" "emerge")
+ (equal '("DN" "emerge" "world")
(eshell--process-args
- "sudo"
- '("-u" "root" "emerge" "-uDN" "world")
- '((?u "user" t user "execute a command as another USER"))))))
+ "sudo" '("-u" "root" "emerge" "-uDN" "world")
+ '((?u "user" t user
+ "execute a command as another USER"))))))
+
+(ert-deftest esh-opt-test/process-args-external ()
+ "Test behavior of :external in `eshell--process-args'."
+ (cl-letf (((symbol-function 'eshell-search-path) #'ignore))
+ (should
+ (equal '(nil "/some/path")
+ (eshell--process-args
+ "ls" '("/some/path")
+ '((?a "all" nil show-all
+ "do not ignore entries starting with .")
+ :external "ls")))))
+ (cl-letf (((symbol-function 'eshell-search-path) #'identity))
+ (should
+ (equal '(no-catch eshell-ext-command "ls")
+ (should-error
+ (eshell--process-args
+ "ls" '("-u" "/some/path")
+ '((?a "all" nil show-all
+ "do not ignore entries starting with .")
+ :external "ls"))
+ :type 'no-catch))))
+ (cl-letf (((symbol-function 'eshell-search-path) #'ignore))
+ (should-error
+ (eshell--process-args
+ "ls" '("-u" "/some/path")
+ '((?a "all" nil show-all
+ "do not ignore entries starting with .")
+ :external "ls"))
+ :type 'error)))
+
+(ert-deftest esh-opt-test/eval-using-options-short ()
+ "Test `eshell-eval-using-options' with short options."
+ (eshell-eval-using-options
+ "ls" '("-a" "/some/path")
+ '((?a "all" nil show-all
+ "do not ignore entries starting with ."))
+ (should (eq show-all t))
+ (should (equal args '("/some/path"))))
+ (eshell-eval-using-options
+ "ls" '("/some/path")
+ '((?a "all" nil show-all
+ "do not ignore entries starting with ."))
+ (should (eq show-all nil))
+ (should (equal args '("/some/path")))))
+
+(ert-deftest esh-opt-test/eval-using-options-long ()
+ "Test `eshell-eval-using-options' with long options."
+ (eshell-eval-using-options
+ "ls" '("--all" "/some/path")
+ '((?a "all" nil show-all
+ "do not ignore entries starting with ."))
+ (should (eq show-all t))
+ (should (equal args '("/some/path")))))
+
+(ert-deftest esh-opt-test/eval-using-options-constant ()
+ "Test `eshell-eval-using-options' with options with constant values."
+ (eshell-eval-using-options
+ "ls" '("/some/path" "-h")
+ '((?h "human-readable" 1024 human-readable
+ "print sizes in human readable format"))
+ (should (eql human-readable 1024))
+ (should (equal args '("/some/path"))))
+ (eshell-eval-using-options
+ "ls" '("/some/path" "--human-readable")
+ '((?h "human-readable" 1024 human-readable
+ "print sizes in human readable format"))
+ (should (eql human-readable 1024))
+ (should (equal args '("/some/path"))))
+ (eshell-eval-using-options
+ "ls" '("/some/path")
+ '((?h "human-readable" 1024 human-readable
+ "print sizes in human readable format"))
+ (should (eq human-readable nil))
+ (should (equal args '("/some/path")))))
-(ert-deftest test-eshell-eval-using-options ()
- "Tests for `eshell-eval-using-options'."
+(ert-deftest esh-opt-test/eval-using-options-user-specified ()
+ "Test `eshell-eval-using-options' with options with user-specified values."
+ (eshell-eval-using-options
+ "ls" '("-I" "*.txt" "/some/path")
+ '((?I "ignore" t ignore-pattern
+ "do not list implied entries matching pattern"))
+ (should (equal ignore-pattern "*.txt"))
+ (should (equal args '("/some/path"))))
+ (eshell-eval-using-options
+ "ls" '("-I*.txt" "/some/path")
+ '((?I "ignore" t ignore-pattern
+ "do not list implied entries matching pattern"))
+ (should (equal ignore-pattern "*.txt"))
+ (should (equal args '("/some/path"))))
+ (eshell-eval-using-options
+ "ls" '("--ignore" "*.txt" "/some/path")
+ '((?I "ignore" t ignore-pattern
+ "do not list implied entries matching pattern"))
+ (should (equal ignore-pattern "*.txt"))
+ (should (equal args '("/some/path"))))
+ (eshell-eval-using-options
+ "ls" '("--ignore=*.txt" "/some/path")
+ '((?I "ignore" t ignore-pattern
+ "do not list implied entries matching pattern"))
+ (should (equal ignore-pattern "*.txt"))
+ (should (equal args '("/some/path")))))
+
+(ert-deftest esh-opt-test/eval-using-options-short-single-token ()
+ "Test `eshell-eval-using-options' with multiple short options in one token."
+ (eshell-eval-using-options
+ "ls" '("-al" "/some/path")
+ '((?a "all" nil show-all
+ "do not ignore entries starting with .")
+ (?l nil long-listing listing-style
+ "use a long listing format"))
+ (should (eq t show-all))
+ (should (eql listing-style 'long-listing))
+ (should (equal args '("/some/path"))))
+ (eshell-eval-using-options
+ "ls" '("-aI*.txt" "/some/path")
+ '((?a "all" nil show-all
+ "do not ignore entries starting with .")
+ (?I "ignore" t ignore-pattern
+ "do not list implied entries matching pattern"))
+ (should (eq t show-all))
+ (should (equal ignore-pattern "*.txt"))
+ (should (equal args '("/some/path")))))
+
+(ert-deftest esh-opt-test/eval-using-options-stdin ()
+ "Test that \"-\" is a positional arg in `eshell-eval-using-options'."
+ (eshell-eval-using-options
+ "cat" '("-")
+ '((?A "show-all" nil show-all
+ "show all characters"))
+ (should (eq show-all nil))
+ (should (equal args '("-"))))
+ (eshell-eval-using-options
+ "cat" '("-A" "-")
+ '((?A "show-all" nil show-all
+ "show all characters"))
+ (should (eq show-all t))
+ (should (equal args '("-"))))
+ (eshell-eval-using-options
+ "cat" '("-" "-A")
+ '((?A "show-all" nil show-all
+ "show all characters"))
+ (should (eq show-all t))
+ (should (equal args '("-")))))
+
+(ert-deftest esh-opt-test/eval-using-options-terminate-options ()
+ "Test that \"--\" terminates options in `eshell-eval-using-options'."
+ (eshell-eval-using-options
+ "ls" '("--" "-a")
+ '((?a "all" nil show-all
+ "do not ignore entries starting with ."))
+ (should (eq show-all nil))
+ (should (equal args '("-a"))))
+ (eshell-eval-using-options
+ "ls" '("--" "--all")
+ '((?a "all" nil show-all
+ "do not ignore entries starting with ."))
+ (should (eq show-all nil))
+ (should (equal args '("--all")))))
+
+(ert-deftest esh-opt-test/eval-using-options-parse-leading-options-only ()
+ "Test :parse-leading-options-only in `eshell-eval-using-options'."
(eshell-eval-using-options
"sudo" '("-u" "root" "whoami")
'((?u "user" t user "execute a command as another USER")
:parse-leading-options-only)
- (should (equal user "root")))
+ (should (equal user "root"))
+ (should (equal args '("whoami"))))
(eshell-eval-using-options
"sudo" '("--user" "root" "whoami")
'((?u "user" t user "execute a command as another USER")
:parse-leading-options-only)
- (should (equal user "root")))
-
+ (should (equal user "root"))
+ (should (equal args '("whoami"))))
(eshell-eval-using-options
"sudo" '("emerge" "-uDN" "world")
'((?u "user" t user "execute a command as another USER"))
- (should (equal user "world")))
+ (should (equal user "DN"))
+ (should (equal args '("emerge" "world"))))
(eshell-eval-using-options
"sudo" '("emerge" "-uDN" "world")
'((?u "user" t user "execute a command as another USER")
:parse-leading-options-only)
- (should (eq user nil)))
+ (should (eq user nil))
+ (should (equal args '("emerge" "-uDN" "world")))))
- (eshell-eval-using-options
- "ls" '("-I" "*.txt" "/dev/null")
- '((?I "ignore" t ignore-pattern
- "do not list implied entries matching pattern"))
- (should (equal ignore-pattern "*.txt")))
-
- (eshell-eval-using-options
- "ls" '("-l" "/dev/null")
- '((?l nil long-listing listing-style
- "use a long listing format"))
- (should (eql listing-style 'long-listing)))
- (eshell-eval-using-options
- "ls" '("/dev/null")
- '((?l nil long-listing listing-style
- "use a long listing format"))
- (should (eq listing-style nil)))
+(ert-deftest esh-opt-test/eval-using-options-unrecognized ()
+ "Test `eshell-eval-using-options' with unrecognized options."
+ (should-error
+ (eshell-eval-using-options
+ "ls" '("-u" "/some/path")
+ '((?a "all" nil _show-all
+ "do not ignore entries starting with ."))))
+ (should-error
+ (eshell-eval-using-options
+ "ls" '("-au" "/some/path")
+ '((?a "all" nil _show-all
+ "do not ignore entries starting with ."))))
+ (should-error
+ (eshell-eval-using-options
+ "ls" '("--unrecognized" "/some/path")
+ '((?a "all" nil _show-all
+ "do not ignore entries starting with .")))))
- (eshell-eval-using-options
- "ls" '("/dev/null" "-h")
- '((?h "human-readable" 1024 human-readable
- "print sizes in human readable format"))
- (should (eql human-readable 1024)))
- (eshell-eval-using-options
- "ls" '("/dev/null" "--human-readable")
- '((?h "human-readable" 1024 human-readable
- "print sizes in human readable format"))
- (should (eql human-readable 1024)))
- (eshell-eval-using-options
- "ls" '("/dev/null")
- '((?h "human-readable" 1024 human-readable
- "print sizes in human readable format"))
- (should (eq human-readable nil))))
+(ert-deftest esh-opt-test/eval-using-options-external ()
+ "Test :external in `eshell-eval-using-options'."
+ (cl-letf (((symbol-function 'eshell-search-path) #'identity)
+ ((symbol-function 'eshell-external-command) #'list))
+ (should
+ (equal (catch 'eshell-external
+ (eshell-eval-using-options
+ "ls" '("/some/path" "-u")
+ '((?a "all" nil _show-all
+ "do not ignore entries starting with .")
+ :external "ls")))
+ '("ls" ("/some/path" "-u"))))
+ (should
+ (equal (catch 'eshell-external
+ (eshell-eval-using-options
+ "ls" '("/some/path2" "-u")
+ '((?a "all" nil _show-all
+ "do not ignore entries starting with .")
+ :preserve-args
+ :external "ls")))
+ '("ls" ("/some/path2" "-u"))))))
(provide 'esh-opt-tests)
diff --git a/test/lisp/eshell/esh-proc-tests.el b/test/lisp/eshell/esh-proc-tests.el
new file mode 100644
index 00000000000..7f461d1813c
--- /dev/null
+++ b/test/lisp/eshell/esh-proc-tests.el
@@ -0,0 +1,96 @@
+;;; esh-proc-tests.el --- esh-proc test suite -*- lexical-binding:t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'ert)
+(require 'esh-mode)
+(require 'eshell)
+
+(require 'eshell-tests-helpers
+ (expand-file-name "eshell-tests-helpers"
+ (file-name-directory (or load-file-name
+ default-directory))))
+
+(ert-deftest esh-proc-test/sigpipe-exits-process ()
+ "Test that a SIGPIPE is properly sent to a process if a pipe closes"
+ (skip-unless (and (executable-find "sh")
+ (executable-find "echo")
+ (executable-find "sleep")))
+ (with-temp-eshell
+ (eshell-command-result-p
+ ;; The first command is like `yes' but slower. This is to prevent
+ ;; it from taxing Emacs's process filter too much and causing a
+ ;; hang.
+ (concat "sh -c 'while true; do echo y; sleep 1; done' | "
+ "sh -c 'read NAME; echo ${NAME}'")
+ "y\n")
+ (eshell-wait-for-subprocess t)
+ (should (eq (process-list) nil))))
+
+(ert-deftest esh-proc-test/kill-pipeline ()
+ "Test that killing a pipeline of processes only emits a single
+prompt. See bug#54136."
+ (skip-unless (and (executable-find "sh")
+ (executable-find "echo")
+ (executable-find "sleep")))
+ ;; This test doesn't work on EMBA with AOT nativecomp, but works
+ ;; fine elsewhere.
+ (skip-unless (not (getenv "EMACS_EMBA_CI")))
+ (with-temp-eshell
+ (eshell-insert-command
+ (concat "sh -c 'while true; do echo y; sleep 1; done' | "
+ "sh -c 'while true; do read NAME; done'"))
+ (let ((output-start (eshell-beginning-of-output)))
+ (eshell-kill-process)
+ (eshell-wait-for-subprocess t)
+ (should (string-match-p
+ ;; "interrupt\n" is for MS-Windows.
+ (rx (or "interrupt\n" "killed\n" "killed: 9\n"))
+ (buffer-substring-no-properties
+ output-start (eshell-end-of-output)))))))
+
+(ert-deftest esh-proc-test/kill-pipeline-head ()
+ "Test that killing the first process in a pipeline doesn't
+write the exit status to the pipe. See bug#54136."
+ (skip-unless (and (executable-find "sh")
+ (executable-find "echo")
+ (executable-find "sleep")))
+ (with-temp-eshell
+ (eshell-insert-command
+ (concat "sh -c 'while true; do sleep 1; done' | "
+ "sh -c 'while read NAME; do echo =${NAME}=; done'"))
+ (let ((output-start (eshell-beginning-of-output)))
+ (kill-process (eshell-head-process))
+ (eshell-wait-for-subprocess t)
+ (should (equal (buffer-substring-no-properties
+ output-start (eshell-end-of-output))
+ "")))))
+
+(ert-deftest esh-proc-test/kill-background-process ()
+ "Test that killing a background process doesn't emit a new
+prompt. See bug#54136."
+ (skip-unless (and (executable-find "sh")
+ (executable-find "sleep")))
+ (with-temp-eshell
+ (eshell-insert-command "sh -c 'while true; do sleep 1; done' &")
+ (kill-process (caar eshell-process-list))
+ ;; Give `eshell-sentinel' a chance to run.
+ (sit-for 0.1)
+ (eshell-match-result "\\[sh\\(\\.exe\\)?\\] [[:digit:]]+\n")))
diff --git a/test/lisp/eshell/esh-var-tests.el b/test/lisp/eshell/esh-var-tests.el
new file mode 100644
index 00000000000..54e701a6aab
--- /dev/null
+++ b/test/lisp/eshell/esh-var-tests.el
@@ -0,0 +1,547 @@
+;;; esh-var-tests.el --- esh-var test suite -*- lexical-binding:t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Tests for Eshell's variable handling.
+
+;;; Code:
+
+(require 'ert)
+(require 'esh-mode)
+(require 'eshell)
+
+(require 'eshell-tests-helpers
+ (expand-file-name "eshell-tests-helpers"
+ (file-name-directory (or load-file-name
+ default-directory))))
+
+(defvar eshell-test-value nil)
+
+;;; Tests:
+
+
+;; Variable interpolation
+
+(ert-deftest esh-var-test/interp-var ()
+ "Interpolate variable"
+ (should (equal (eshell-test-command-result "echo $user-login-name")
+ user-login-name)))
+
+(ert-deftest esh-var-test/interp-quoted-var ()
+ "Interpolate quoted variable"
+ (should (equal (eshell-test-command-result "echo $'user-login-name'")
+ user-login-name))
+ (should (equal (eshell-test-command-result "echo $\"user-login-name\"")
+ user-login-name)))
+
+(ert-deftest esh-var-test/interp-quoted-var-concat ()
+ "Interpolate and concat quoted variable"
+ (should (equal (eshell-test-command-result "echo $'user-login-name'-foo")
+ (concat user-login-name "-foo")))
+ (should (equal (eshell-test-command-result "echo $\"user-login-name\"-foo")
+ (concat user-login-name "-foo"))))
+
+(ert-deftest esh-var-test/interp-var-indices ()
+ "Interpolate list variable with indices"
+ (let ((eshell-test-value '("zero" "one" "two" "three" "four")))
+ (should (equal (eshell-test-command-result "echo $eshell-test-value[0]")
+ "zero"))
+ (should (equal (eshell-test-command-result "echo $eshell-test-value[0 2]")
+ '("zero" "two")))
+ (should (equal (eshell-test-command-result "echo $eshell-test-value[0 2 4]")
+ '("zero" "two" "four")))))
+
+(ert-deftest esh-var-test/interp-var-split-indices ()
+ "Interpolate string variable with indices"
+ (let ((eshell-test-value "zero one two three four"))
+ (should (equal (eshell-test-command-result "echo $eshell-test-value[0]")
+ "zero"))
+ (should (equal (eshell-test-command-result "echo $eshell-test-value[0 2]")
+ '("zero" "two")))
+ (should (equal (eshell-test-command-result "echo $eshell-test-value[0 2 4]")
+ '("zero" "two" "four")))))
+
+(ert-deftest esh-var-test/interp-var-string-split-indices ()
+ "Interpolate string variable with string splitter and indices"
+ (let ((eshell-test-value "zero:one:two:three:four"))
+ (should (equal (eshell-test-command-result "echo $eshell-test-value[: 0]")
+ "zero"))
+ (should (equal (eshell-test-command-result "echo $eshell-test-value[: 0 2]")
+ '("zero" "two"))))
+ (let ((eshell-test-value "zeroXoneXtwoXthreeXfour"))
+ (should (equal (eshell-test-command-result "echo $eshell-test-value[X 0]")
+ "zero"))
+ (should (equal (eshell-test-command-result "echo $eshell-test-value[X 0 2]")
+ '("zero" "two")))))
+
+(ert-deftest esh-var-test/interp-var-regexp-split-indices ()
+ "Interpolate string variable with regexp splitter and indices"
+ (let ((eshell-test-value "zero:one!two:three!four"))
+ (should (equal (eshell-test-command-result
+ "echo $eshell-test-value['[:!]' 0]")
+ "zero"))
+ (should (equal (eshell-test-command-result
+ "echo $eshell-test-value['[:!]' 0 2]")
+ '("zero" "two")))
+ (should (equal (eshell-test-command-result
+ "echo $eshell-test-value[\"[:!]\" 0]")
+ "zero"))
+ (should (equal (eshell-test-command-result
+ "echo $eshell-test-value[\"[:!]\" 0 2]")
+ '("zero" "two")))))
+
+(ert-deftest esh-var-test/interp-var-assoc ()
+ "Interpolate alist variable with index"
+ (let ((eshell-test-value '(("foo" . 1))))
+ (should (eq (eshell-test-command-result "echo $eshell-test-value[foo]")
+ 1))))
+
+(ert-deftest esh-var-test/interp-var-length-list ()
+ "Interpolate length of list variable"
+ (let ((eshell-test-value '((1 2) (3) (5 (6 7 8 9)))))
+ (should (eq (eshell-test-command-result "echo $#eshell-test-value") 3))
+ (should (eq (eshell-test-command-result "echo $#eshell-test-value[1]") 1))
+ (should (eq (eshell-test-command-result "echo $#eshell-test-value[2][1]")
+ 4))))
+
+(ert-deftest esh-var-test/interp-var-length-string ()
+ "Interpolate length of string variable"
+ (let ((eshell-test-value "foobar"))
+ (should (eq (eshell-test-command-result "echo $#eshell-test-value") 6))))
+
+(ert-deftest esh-var-test/interp-var-length-alist ()
+ "Interpolate length of alist variable"
+ (let ((eshell-test-value '(("foo" . (1 2 3)))))
+ (should (eq (eshell-test-command-result "echo $#eshell-test-value") 1))
+ (should (eq (eshell-test-command-result "echo $#eshell-test-value[foo]")
+ 3))))
+
+(ert-deftest esh-var-test/interp-lisp ()
+ "Interpolate Lisp form evaluation"
+ (should (equal (eshell-test-command-result "+ $(+ 1 2) 3") 6)))
+
+(ert-deftest esh-var-test/interp-lisp-indices ()
+ "Interpolate Lisp form evaluation with index"
+ (should (equal (eshell-test-command-result "+ $(list 1 2)[1] 3") 5)))
+
+(ert-deftest esh-var-test/interp-cmd ()
+ "Interpolate command result"
+ (should (equal (eshell-test-command-result "+ ${+ 1 2} 3") 6)))
+
+(ert-deftest esh-var-test/interp-cmd-indices ()
+ "Interpolate command result with index"
+ (should (equal (eshell-test-command-result "+ ${listify 1 2}[1] 3") 5)))
+
+(ert-deftest esh-var-test/interp-cmd-external ()
+ "Interpolate command result from external command"
+ (skip-unless (executable-find "echo"))
+ (with-temp-eshell
+ (eshell-command-result-p "echo ${*echo hi}"
+ "hi\n")))
+
+(ert-deftest esh-var-test/interp-cmd-external-indices ()
+ "Interpolate command result from external command with index"
+ (skip-unless (executable-find "echo"))
+ (with-temp-eshell
+ (eshell-command-result-p "echo ${*echo \"hi\nbye\"}[1]"
+ "bye\n")))
+
+(ert-deftest esh-var-test/interp-temp-cmd ()
+ "Interpolate command result redirected to temp file"
+ (should (equal (eshell-test-command-result "cat $<echo hi>") "hi")))
+
+(ert-deftest esh-var-test/interp-concat-lisp ()
+ "Interpolate and concat Lisp form"
+ (should (equal (eshell-test-command-result "+ $(+ 1 2)3 3") 36)))
+
+(ert-deftest esh-var-test/interp-concat-lisp2 ()
+ "Interpolate and concat two Lisp forms"
+ (should (equal (eshell-test-command-result "+ $(+ 1 2)$(+ 1 2) 3") 36)))
+
+(ert-deftest esh-var-test/interp-concat-cmd ()
+ "Interpolate and concat command with literal"
+ (should (equal (eshell-test-command-result "+ ${+ 1 2}3 3") 36))
+ (should (equal (eshell-test-command-result "echo ${*echo \"foo\nbar\"}-baz")
+ '("foo" "bar-baz")))
+ ;; Concatenating to a number in a list should produce a number...
+ (should (equal (eshell-test-command-result "echo ${*echo \"1\n2\"}3")
+ '(1 23)))
+ ;; ... but concatenating to a string that looks like a number in a list
+ ;; should produce a string.
+ (should (equal (eshell-test-command-result "echo ${*echo \"hi\n2\"}3")
+ '("hi" "23"))))
+
+(ert-deftest esh-var-test/interp-concat-cmd2 ()
+ "Interpolate and concat two commands"
+ (should (equal (eshell-test-command-result "+ ${+ 1 2}${+ 1 2} 3") 36)))
+
+(ert-deftest esh-var-test/interp-concat-cmd-external ()
+ "Interpolate command result from external command with concatenation"
+ (skip-unless (executable-find "echo"))
+ (with-temp-eshell
+ (eshell-command-result-p "echo ${echo hi}-${*echo there}"
+ "hi-there\n")))
+
+(ert-deftest esh-var-test/quoted-interp-var ()
+ "Interpolate variable inside double-quotes"
+ (should (equal (eshell-test-command-result "echo \"$user-login-name\"")
+ user-login-name)))
+
+(ert-deftest esh-var-test/quoted-interp-quoted-var ()
+ "Interpolate quoted variable inside double-quotes"
+ (should (equal (eshell-test-command-result
+ "echo \"hi, $'user-login-name'\"")
+ (concat "hi, " user-login-name)))
+ (should (equal (eshell-test-command-result
+ "echo \"hi, $\\\"user-login-name\\\"\"")
+ (concat "hi, " user-login-name))))
+
+(ert-deftest esh-var-test/quoted-interp-var-indices ()
+ "Interpolate string variable with indices inside double-quotes"
+ (let ((eshell-test-value '("zero" "one" "two" "three" "four")))
+ (should (equal (eshell-test-command-result
+ "echo \"$eshell-test-value[0]\"")
+ "zero"))
+ ;; FIXME: These tests would use the 0th index like the other tests
+ ;; here, but evaluating the command just above adds an `escaped'
+ ;; property to the string "zero". This results in the output
+ ;; printing the string properties, which is probably the wrong
+ ;; behavior. See bug#54486.
+ (should (equal (eshell-test-command-result
+ "echo \"$eshell-test-value[1 2]\"")
+ "(\"one\" \"two\")"))
+ (should (equal (eshell-test-command-result
+ "echo \"$eshell-test-value[1 2 4]\"")
+ "(\"one\" \"two\" \"four\")"))))
+
+(ert-deftest esh-var-test/quoted-interp-var-split-indices ()
+ "Interpolate string variable with indices inside double-quotes"
+ (let ((eshell-test-value "zero one two three four"))
+ (should (equal (eshell-test-command-result
+ "echo \"$eshell-test-value[0]\"")
+ "zero"))
+ (should (equal (eshell-test-command-result
+ "echo \"$eshell-test-value[0 2]\"")
+ "(\"zero\" \"two\")"))))
+
+(ert-deftest esh-var-test/quoted-interp-var-string-split-indices ()
+ "Interpolate string variable with string splitter and indices
+inside double-quotes"
+ (let ((eshell-test-value "zero:one:two:three:four"))
+ (should (equal (eshell-test-command-result
+ "echo \"$eshell-test-value[: 0]\"")
+ "zero"))
+ (should (equal (eshell-test-command-result
+ "echo \"$eshell-test-value[: 0 2]\"")
+ "(\"zero\" \"two\")")))
+ (let ((eshell-test-value "zeroXoneXtwoXthreeXfour"))
+ (should (equal (eshell-test-command-result
+ "echo \"$eshell-test-value[X 0]\"")
+ "zero"))
+ (should (equal (eshell-test-command-result
+ "echo \"$eshell-test-value[X 0 2]\"")
+ "(\"zero\" \"two\")"))))
+
+(ert-deftest esh-var-test/quoted-interp-var-regexp-split-indices ()
+ "Interpolate string variable with regexp splitter and indices"
+ (let ((eshell-test-value "zero:one!two:three!four"))
+ (should (equal (eshell-test-command-result
+ "echo \"$eshell-test-value['[:!]' 0]\"")
+ "zero"))
+ (should (equal (eshell-test-command-result
+ "echo \"$eshell-test-value['[:!]' 0 2]\"")
+ "(\"zero\" \"two\")"))
+ (should (equal (eshell-test-command-result
+ "echo \"$eshell-test-value[\\\"[:!]\\\" 0]\"")
+ "zero"))
+ (should (equal (eshell-test-command-result
+ "echo \"$eshell-test-value[\\\"[:!]\\\" 0 2]\"")
+ "(\"zero\" \"two\")"))))
+
+(ert-deftest esh-var-test/quoted-interp-var-assoc ()
+ "Interpolate alist variable with index inside double-quotes"
+ (let ((eshell-test-value '(("foo" . 1))))
+ (should (equal (eshell-test-command-result
+ "echo \"$eshell-test-value[foo]\"")
+ "1"))))
+
+(ert-deftest esh-var-test/quoted-interp-var-length-list ()
+ "Interpolate length of list variable inside double-quotes"
+ (let ((eshell-test-value '((1 2) (3) (5 (6 7 8 9)))))
+ (should (equal (eshell-test-command-result "echo \"$#eshell-test-value\"")
+ "3"))
+ (should (equal (eshell-test-command-result
+ "echo \"$#eshell-test-value[1]\"")
+ "1"))
+ (should (equal (eshell-test-command-result
+ "echo \"$#eshell-test-value[2][1]\"")
+ "4"))))
+
+(ert-deftest esh-var-test/quoted-interp-var-length-string ()
+ "Interpolate length of string variable inside double-quotes"
+ (let ((eshell-test-value "foobar"))
+ (should (equal (eshell-test-command-result "echo \"$#eshell-test-value\"")
+ "6"))))
+
+(ert-deftest esh-var-test/quoted-interp-var-length-alist ()
+ "Interpolate length of alist variable inside double-quotes"
+ (let ((eshell-test-value '(("foo" . (1 2 3)))))
+ (should (equal (eshell-test-command-result "echo \"$#eshell-test-value\"")
+ "1"))
+ (should (equal (eshell-test-command-result
+ "echo \"$#eshell-test-value[foo]\"")
+ "3"))))
+
+(ert-deftest esh-var-test/quoted-interp-lisp ()
+ "Interpolate Lisp form evaluation inside double-quotes"
+ (should (equal (eshell-test-command-result
+ "echo \"hi $(concat \\\"the\\\" \\\"re\\\")\"")
+ "hi there")))
+
+(ert-deftest esh-var-test/quoted-interp-lisp-indices ()
+ "Interpolate Lisp form evaluation with index"
+ (should (equal (eshell-test-command-result "concat \"$(list 1 2)[1]\" cool")
+ "2cool")))
+
+(ert-deftest esh-var-test/quoted-interp-cmd ()
+ "Interpolate command result inside double-quotes"
+ (should (equal (eshell-test-command-result
+ "echo \"hi ${echo \\\"there\\\"}\"")
+ "hi there")))
+
+(ert-deftest esh-var-test/quoted-interp-cmd-indices ()
+ "Interpolate command result with index inside double-quotes"
+ (should (equal (eshell-test-command-result
+ "concat \"${listify 1 2}[1]\" cool")
+ "2cool")))
+
+(ert-deftest esh-var-test/quoted-interp-temp-cmd ()
+ "Interpolate command result redirected to temp file inside double-quotes"
+ (let ((temporary-file-directory
+ (file-name-as-directory (make-temp-file "esh-vars-tests" t))))
+ (unwind-protect
+ (should (equal (eshell-test-command-result "cat \"$<echo hi>\"")
+ "hi"))
+ (delete-directory temporary-file-directory t))))
+
+(ert-deftest esh-var-test/quoted-interp-concat-cmd ()
+ "Interpolate and concat command with literal"
+ (should (equal (eshell-test-command-result
+ "echo \"${echo \\\"foo\nbar\\\"} baz\"")
+ "foo\nbar baz")))
+
+
+;; Interpolated variable conversion
+
+(ert-deftest esh-var-test/interp-convert-var-number ()
+ "Interpolate numeric variable"
+ (let ((eshell-test-value 123))
+ (should (equal (eshell-test-command-result "type-of $eshell-test-value")
+ 'integer))))
+
+(ert-deftest esh-var-test/interp-convert-var-split-indices ()
+ "Interpolate and convert string variable with indices"
+ ;; Check that numeric forms are converted to numbers.
+ (let ((eshell-test-value "000 010 020 030 040"))
+ (should (equal (eshell-test-command-result "echo $eshell-test-value[0]")
+ 0))
+ (should (equal (eshell-test-command-result "echo $eshell-test-value[0 2]")
+ '(0 20))))
+ ;; Check that multiline forms are preserved as-is.
+ (let ((eshell-test-value "foo\nbar:baz\n"))
+ (should (equal (eshell-test-command-result "echo $eshell-test-value[: 0]")
+ "foo\nbar"))
+ (should (equal (eshell-test-command-result "echo $eshell-test-value[: 1]")
+ "baz\n"))))
+
+(ert-deftest esh-var-test/interp-convert-quoted-var-number ()
+ "Interpolate numeric quoted numeric variable"
+ (let ((eshell-test-value 123))
+ (should (equal (eshell-test-command-result "type-of $'eshell-test-value'")
+ 'integer))
+ (should (equal (eshell-test-command-result "type-of $\"eshell-test-value\"")
+ 'integer))))
+
+(ert-deftest esh-var-test/interp-convert-quoted-var-split-indices ()
+ "Interpolate and convert quoted string variable with indices"
+ (let ((eshell-test-value "000 010 020 030 040"))
+ (should (equal (eshell-test-command-result "echo $'eshell-test-value'[0]")
+ 0))
+ (should (equal (eshell-test-command-result "echo $'eshell-test-value'[0 2]")
+ '(0 20)))))
+
+(ert-deftest esh-var-test/interp-convert-cmd-string-newline ()
+ "Interpolate trailing-newline command result"
+ (should (equal (eshell-test-command-result "echo ${echo \"foo\n\"}") "foo")))
+
+(ert-deftest esh-var-test/interp-convert-cmd-multiline ()
+ "Interpolate multi-line command result"
+ (should (equal (eshell-test-command-result "echo ${echo \"foo\nbar\"}")
+ '("foo" "bar")))
+ ;; Numeric output should be converted to numbers...
+ (should (equal (eshell-test-command-result "echo ${echo \"01\n02\n03\"}")
+ '(1 2 3)))
+ ;; ... but only if every line is numeric.
+ (should (equal (eshell-test-command-result "echo ${echo \"01\n02\nhi\"}")
+ '("01" "02" "hi"))))
+
+(ert-deftest esh-var-test/interp-convert-cmd-number ()
+ "Interpolate numeric command result"
+ (should (equal (eshell-test-command-result "echo ${echo \"1\"}") 1)))
+
+(ert-deftest esh-var-test/interp-convert-cmd-split-indices ()
+ "Interpolate command result with indices"
+ (should (equal (eshell-test-command-result "echo ${echo \"000 010 020\"}[0]")
+ 0))
+ (should (equal (eshell-test-command-result
+ "echo ${echo \"000 010 020\"}[0 2]")
+ '(0 20))))
+
+(ert-deftest esh-var-test/quoted-interp-convert-var-number ()
+ "Interpolate numeric variable inside double-quotes"
+ (let ((eshell-test-value 123))
+ (should (equal (eshell-test-command-result "type-of \"$eshell-test-value\"")
+ 'string))))
+
+(ert-deftest esh-var-test/quoted-interp-convert-var-split-indices ()
+ "Interpolate string variable with indices inside double-quotes"
+ (let ((eshell-test-value "000 010 020 030 040"))
+ (should (equal (eshell-test-command-result
+ "echo \"$eshell-test-value[0]\"")
+ "000"))
+ (should (equal (eshell-test-command-result
+ "echo \"$eshell-test-value[0 2]\"")
+ "(\"000\" \"020\")"))))
+
+(ert-deftest esh-var-test/quoted-interp-convert-quoted-var-number ()
+ "Interpolate numeric quoted variable inside double-quotes"
+ (let ((eshell-test-value 123))
+ (should (equal (eshell-test-command-result
+ "type-of \"$'eshell-test-value'\"")
+ 'string))
+ (should (equal (eshell-test-command-result
+ "type-of \"$\\\"eshell-test-value\\\"\"")
+ 'string))))
+
+(ert-deftest esh-var-test/quoted-interp-convert-quoted-var-split-indices ()
+ "Interpolate quoted string variable with indices inside double-quotes"
+ (let ((eshell-test-value "000 010 020 030 040"))
+ (should (equal (eshell-test-command-result
+ "echo \"$eshell-test-value[0]\"")
+ "000"))
+ (should (equal (eshell-test-command-result
+ "echo \"$eshell-test-value[0 2]\"")
+ "(\"000\" \"020\")"))))
+
+(ert-deftest esh-var-test/quoted-interp-convert-cmd-string-newline ()
+ "Interpolate trailing-newline command result inside double-quotes"
+ (should (equal (eshell-test-command-result "echo \"${echo \\\"foo\n\\\"}\"")
+ "foo"))
+ (should (equal (eshell-test-command-result "echo \"${echo \\\"foo\n\n\\\"}\"")
+ "foo")))
+
+(ert-deftest esh-var-test/quoted-interp-convert-cmd-multiline ()
+ "Interpolate multi-line command result inside double-quotes"
+ (should (equal (eshell-test-command-result
+ "echo \"${echo \\\"foo\nbar\\\"}\"")
+ "foo\nbar")))
+
+(ert-deftest esh-var-test/quoted-interp-convert-cmd-number ()
+ "Interpolate numeric command result inside double-quotes"
+ (should (equal (eshell-test-command-result "echo \"${echo \\\"1\\\"}\"")
+ "1")))
+
+(ert-deftest esh-var-test/quoted-interp-convert-cmd-split-indices ()
+ "Interpolate command result with indices inside double-quotes"
+ (should (equal (eshell-test-command-result
+ "echo \"${echo \\\"000 010 020\\\"}[0]\"")
+ "000")))
+
+
+;; Built-in variables
+
+(ert-deftest esh-var-test/lines-var ()
+ "$LINES should equal (window-body-height nil 'remap)"
+ (should (equal (eshell-test-command-result "echo $LINES")
+ (window-body-height nil 'remap))))
+
+(ert-deftest esh-var-test/columns-var ()
+ "$COLUMNS should equal (window-body-width nil 'remap)"
+ (should (equal (eshell-test-command-result "echo $COLUMNS")
+ (window-body-width nil 'remap))))
+
+(ert-deftest esh-var-test/inside-emacs-var ()
+ "Test presence of \"INSIDE_EMACS\" in subprocesses"
+ (with-temp-eshell
+ (eshell-command-result-p "env"
+ (format "INSIDE_EMACS=%s,eshell"
+ emacs-version))))
+
+(ert-deftest esh-var-test/inside-emacs-var-split-indices ()
+ "Test using \"INSIDE_EMACS\" with split indices"
+ (with-temp-eshell
+ (eshell-command-result-p "echo $INSIDE_EMACS[, 1]"
+ "eshell")))
+
+(ert-deftest esh-var-test/last-result-var ()
+ "Test using the \"last result\" ($$) variable"
+ (with-temp-eshell
+ (eshell-command-result-p "+ 1 2; + $$ 2"
+ "3\n5\n")))
+
+(ert-deftest esh-var-test/last-result-var2 ()
+ "Test using the \"last result\" ($$) variable twice"
+ (with-temp-eshell
+ (eshell-command-result-p "+ 1 2; + $$ $$"
+ "3\n6\n")))
+
+(ert-deftest esh-var-test/last-result-var-split-indices ()
+ "Test using the \"last result\" ($$) variable with split indices"
+ (with-temp-eshell
+ (eshell-command-result-p
+ "string-join (list \"01\" \"02\") :; + $$[: 1] 3"
+ "01:02\n5\n")
+ (eshell-command-result-p
+ "string-join (list \"01\" \"02\") :; echo \"$$[: 1]\""
+ "01:02\n02\n")))
+
+(ert-deftest esh-var-test/last-arg-var ()
+ "Test using the \"last arg\" ($_) variable"
+ (with-temp-eshell
+ (eshell-command-result-p "+ 1 2; + $_ 4"
+ "3\n6\n")))
+
+(ert-deftest esh-var-test/last-arg-var-indices ()
+ "Test using the \"last arg\" ($_) variable with indices"
+ (with-temp-eshell
+ (eshell-command-result-p "+ 1 2; + $_[0] 4"
+ "3\n5\n")
+ (eshell-command-result-p "+ 1 2; + $_[1] 4"
+ "3\n6\n")))
+
+(ert-deftest esh-var-test/last-arg-var-split-indices ()
+ "Test using the \"last arg\" ($_) variable with split indices"
+ (with-temp-eshell
+ (eshell-command-result-p "concat 01:02 03:04; + $_[0][: 1] 5"
+ "01:0203:04\n7\n")
+ (eshell-command-result-p "concat 01:02 03:04; echo \"$_[0][: 1]\""
+ "01:0203:04\n02\n")))
+
+;; esh-var-tests.el ends here
diff --git a/test/lisp/eshell/eshell-tests-helpers.el b/test/lisp/eshell/eshell-tests-helpers.el
new file mode 100644
index 00000000000..4ad76ca6978
--- /dev/null
+++ b/test/lisp/eshell/eshell-tests-helpers.el
@@ -0,0 +1,97 @@
+;;; eshell-tests-helpers.el --- Eshell test suite helpers -*- lexical-binding:t -*-
+
+;; Copyright (C) 1999-2022 Free Software Foundation, Inc.
+
+;; Author: John Wiegley <johnw@gnu.org>
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Eshell test suite helpers.
+
+;;; Code:
+
+(require 'ert)
+(require 'ert-x)
+(require 'esh-mode)
+(require 'eshell)
+
+(defvar eshell-history-file-name nil)
+
+(defvar eshell-test--max-subprocess-time 5
+ "The maximum amount of time to wait for a subprocess to finish, in seconds.
+See `eshell-wait-for-subprocess'.")
+
+(defmacro with-temp-eshell (&rest body)
+ "Evaluate BODY in a temporary Eshell buffer."
+ `(save-current-buffer
+ (ert-with-temp-directory eshell-directory-name
+ (let* (;; We want no history file, so prevent Eshell from falling
+ ;; back on $HISTFILE.
+ (process-environment (cons "HISTFILE" process-environment))
+ (eshell-history-file-name nil)
+ (eshell-buffer (eshell t)))
+ (unwind-protect
+ (with-current-buffer eshell-buffer
+ ,@body)
+ (let (kill-buffer-query-functions)
+ (kill-buffer eshell-buffer)))))))
+
+(defun eshell-wait-for-subprocess (&optional all)
+ "Wait until there is no interactive subprocess running in Eshell.
+If ALL is non-nil, wait until there are no Eshell subprocesses at
+all running.
+
+If this takes longer than `eshell-test--max-subprocess-time',
+raise an error."
+ (let ((start (current-time)))
+ (while (if all eshell-process-list (eshell-interactive-process-p))
+ (when (> (float-time (time-since start))
+ eshell-test--max-subprocess-time)
+ (error "timed out waiting for subprocess(es)"))
+ (sit-for 0.1))))
+
+(defun eshell-insert-command (text &optional func)
+ "Insert a command at the end of the buffer."
+ (goto-char eshell-last-output-end)
+ (insert-and-inherit text)
+ (funcall (or func 'eshell-send-input)))
+
+(defun eshell-match-result (regexp)
+ "Check that output of last command matches REGEXP."
+ (should
+ (string-match-p
+ regexp (buffer-substring-no-properties
+ (eshell-beginning-of-output) (eshell-end-of-output)))))
+
+(defun eshell-command-result-p (text regexp &optional func)
+ "Insert a command at the end of the buffer."
+ (eshell-insert-command text func)
+ (eshell-wait-for-subprocess)
+ (eshell-match-result regexp))
+
+(defvar eshell-history-file-name)
+
+(defun eshell-test-command-result (command)
+ "Like `eshell-command-result', but not using HOME."
+ (ert-with-temp-directory eshell-directory-name
+ (let ((eshell-history-file-name nil))
+ (eshell-command-result command))))
+
+(provide 'eshell-tests-helpers)
+
+;;; eshell-tests-helpers.el ends here
diff --git a/test/lisp/eshell/eshell-tests.el b/test/lisp/eshell/eshell-tests.el
index fe4fba294fd..5dc18775485 100644
--- a/test/lisp/eshell/eshell-tests.el
+++ b/test/lisp/eshell/eshell-tests.el
@@ -26,50 +26,13 @@
;;; Code:
(require 'ert)
+(require 'ert-x)
(require 'esh-mode)
(require 'eshell)
-
-(defmacro with-temp-eshell (&rest body)
- "Evaluate BODY in a temporary Eshell buffer."
- `(let* ((eshell-directory-name (make-temp-file "eshell" t))
- ;; We want no history file, so prevent Eshell from falling
- ;; back on $HISTFILE.
- (process-environment (cons "HISTFILE" process-environment))
- (eshell-history-file-name nil)
- (eshell-buffer (eshell t)))
- (unwind-protect
- (with-current-buffer eshell-buffer
- ,@body)
- (let (kill-buffer-query-functions)
- (kill-buffer eshell-buffer)
- (delete-directory eshell-directory-name t)))))
-
-(defun eshell-insert-command (text &optional func)
- "Insert a command at the end of the buffer."
- (goto-char eshell-last-output-end)
- (insert-and-inherit text)
- (funcall (or func 'eshell-send-input)))
-
-(defun eshell-match-result (regexp)
- "Check that text after `eshell-last-input-end' matches REGEXP."
- (goto-char eshell-last-input-end)
- (should (string-match-p regexp (buffer-substring-no-properties
- (point) (point-max)))))
-
-(defun eshell-command-result-p (text regexp &optional func)
- "Insert a command at the end of the buffer."
- (eshell-insert-command text func)
- (eshell-match-result regexp))
-
-(defvar eshell-history-file-name)
-
-(defun eshell-test-command-result (command)
- "Like `eshell-command-result', but not using HOME."
- (let ((eshell-directory-name (make-temp-file "eshell" t))
- (eshell-history-file-name nil))
- (unwind-protect
- (eshell-command-result command)
- (delete-directory eshell-directory-name t))))
+(require 'eshell-tests-helpers
+ (expand-file-name "eshell-tests-helpers"
+ (file-name-directory (or load-file-name
+ default-directory))))
;;; Tests:
@@ -81,6 +44,10 @@
"Test `eshell-command-result' with an elisp command."
(should (equal (eshell-test-command-result "(+ 1 2)") 3)))
+(ert-deftest eshell-test/lisp-command-with-quote ()
+ "Test `eshell-command-result' with an elisp command containing a quote."
+ (should (equal (eshell-test-command-result "(eq 'foo nil)") nil)))
+
(ert-deftest eshell-test/for-loop ()
"Test `eshell-command-result' with a for loop.."
(let ((process-environment (cons "foo" process-environment)))
@@ -122,66 +89,94 @@ Test that trailing arguments outside the subcommand are ignored.
e.g. \"{(+ 1 2)} 3\" => 3"
(should (equal (eshell-test-command-result "{(+ 1 2)} 3") 3)))
-(ert-deftest eshell-test/interp-cmd ()
- "Interpolate command result"
- (should (equal (eshell-test-command-result "+ ${+ 1 2} 3") 6)))
-
-(ert-deftest eshell-test/interp-lisp ()
- "Interpolate Lisp form evaluation"
- (should (equal (eshell-test-command-result "+ $(+ 1 2) 3") 6)))
-
-(ert-deftest eshell-test/interp-temp-cmd ()
- "Interpolate command result redirected to temp file"
- (should (equal (eshell-test-command-result "cat $<echo hi>") "hi")))
-
-(ert-deftest eshell-test/interp-concat ()
- "Interpolate and concat command"
- (should (equal (eshell-test-command-result "+ ${+ 1 2}3 3") 36)))
-
-(ert-deftest eshell-test/interp-concat-lisp ()
- "Interpolate and concat Lisp form"
- (should (equal (eshell-test-command-result "+ $(+ 1 2)3 3") 36)))
-
-(ert-deftest eshell-test/interp-concat2 ()
- "Interpolate and concat two commands"
- (should (equal (eshell-test-command-result "+ ${+ 1 2}${+ 1 2} 3") 36)))
-
-(ert-deftest eshell-test/interp-concat-lisp2 ()
- "Interpolate and concat two Lisp forms"
- (should (equal (eshell-test-command-result "+ $(+ 1 2)$(+ 1 2) 3") 36)))
-
-(ert-deftest eshell-test/window-height ()
- "$LINES should equal (window-height)"
- (should (eshell-test-command-result "= $LINES (window-height)")))
-
-(ert-deftest eshell-test/window-width ()
- "$COLUMNS should equal (window-width)"
- (should (eshell-test-command-result "= $COLUMNS (window-width)")))
-
-(ert-deftest eshell-test/last-result-var ()
- "Test using the \"last result\" ($$) variable"
+(ert-deftest eshell-test/pipe-headproc ()
+ "Check that piping a non-process to a process command waits for the process"
+ (skip-unless (executable-find "cat"))
(with-temp-eshell
- (eshell-command-result-p "+ 1 2; + $$ 2"
- "3\n5\n")))
+ (eshell-command-result-p "echo hi | *cat"
+ "hi")))
-(ert-deftest eshell-test/last-result-var2 ()
- "Test using the \"last result\" ($$) variable twice"
+(ert-deftest eshell-test/pipe-tailproc ()
+ "Check that piping a process to a non-process command waits for the process"
+ (skip-unless (executable-find "echo"))
(with-temp-eshell
- (eshell-command-result-p "+ 1 2; + $$ $$"
- "3\n6\n")))
+ (eshell-command-result-p "*echo hi | echo bye"
+ "bye\nhi\n")))
-(ert-deftest eshell-test/last-arg-var ()
- "Test using the \"last arg\" ($_) variable"
+(ert-deftest eshell-test/pipe-headproc-stdin ()
+ "Check that standard input is sent to the head process in a pipeline"
+ (skip-unless (and (executable-find "tr")
+ (executable-find "rev")))
+ (with-temp-eshell
+ (eshell-insert-command "tr a-z A-Z | rev")
+ (eshell-insert-command "hello")
+ (eshell-send-eof-to-process)
+ (eshell-wait-for-subprocess)
+ (eshell-match-result "OLLEH\n")))
+
+(ert-deftest eshell-test/pipe-subcommand ()
+ "Check that piping with an asynchronous subcommand works"
+ (skip-unless (and (executable-find "echo")
+ (executable-find "cat")))
(with-temp-eshell
- (eshell-command-result-p "+ 1 2; + $_ 4"
- "3\n6\n")))
+ (eshell-command-result-p "echo ${*echo hi} | *cat"
+ "hi")))
-(ert-deftest eshell-test/inside-emacs-var ()
- "Test presence of \"INSIDE_EMACS\" in subprocesses"
+(ert-deftest eshell-test/pipe-subcommand-with-pipe ()
+ "Check that piping with an asynchronous subcommand with its own pipe works"
+ (skip-unless (and (executable-find "echo")
+ (executable-find "cat")))
(with-temp-eshell
- (eshell-command-result-p "env"
- (format "INSIDE_EMACS=%s,eshell"
- emacs-version))))
+ (eshell-command-result-p "echo ${*echo hi | *cat} | *cat"
+ "hi")))
+
+(ert-deftest eshell-test/subcommand-reset-in-pipeline ()
+ "Check that subcommands reset `eshell-in-pipeline-p'."
+ (skip-unless (executable-find "cat"))
+ (dolist (template '("echo {%s} | *cat"
+ "echo ${%s} | *cat"
+ "*cat $<%s> | *cat"))
+ (should (equal (eshell-test-command-result
+ (format template "echo $eshell-in-pipeline-p"))
+ nil))
+ (should (equal (eshell-test-command-result
+ (format template "echo | echo $eshell-in-pipeline-p"))
+ "last"))
+ (should (equal (eshell-test-command-result
+ (format template "echo $eshell-in-pipeline-p | echo"))
+ "first"))
+ (should (equal (eshell-test-command-result
+ (format template
+ "echo | echo $eshell-in-pipeline-p | echo"))
+ "t"))))
+
+(ert-deftest eshell-test/lisp-reset-in-pipeline ()
+ "Check that interpolated Lisp forms reset `eshell-in-pipeline-p'."
+ (skip-unless (executable-find "cat"))
+ (dolist (template '("echo (%s) | *cat"
+ "echo $(%s) | *cat"))
+ (should (equal (eshell-test-command-result
+ (format template "format \"%s\" eshell-in-pipeline-p"))
+ "nil"))))
+
+(ert-deftest eshell-test/redirect-buffer ()
+ "Check that piping to a buffer works"
+ (with-temp-buffer
+ (rename-buffer "eshell-temp-buffer" t)
+ (let ((bufname (buffer-name)))
+ (with-temp-eshell
+ (eshell-insert-command (format "echo hi > #<%s>" bufname)))
+ (should (equal (buffer-string) "hi")))))
+
+(ert-deftest eshell-test/redirect-buffer-escaped ()
+ "Check that piping to a buffer with escaped characters works"
+ (with-temp-buffer
+ (rename-buffer "eshell\\temp\\buffer" t)
+ (let ((bufname (buffer-name)))
+ (with-temp-eshell
+ (eshell-insert-command (format "echo hi > #<%s>"
+ (string-replace "\\" "\\\\" bufname))))
+ (should (equal (buffer-string) "hi")))))
(ert-deftest eshell-test/escape-nonspecial ()
"Test that \"\\c\" and \"c\" are equivalent when \"c\" is not a
@@ -210,9 +205,9 @@ chars"
"Test that the backslash is not preserved for escaped special
chars"
(with-temp-eshell
- (eshell-command-result-p "echo \"h\\\\i\""
+ (eshell-command-result-p "echo \"\\\"hi\\\\\""
;; Backslashes are doubled for regexp.
- "h\\\\i\n")))
+ "\\\"hi\\\\\n")))
(ert-deftest eshell-test/command-running-p ()
"Modeline should show no command running"
@@ -253,9 +248,8 @@ chars"
(with-temp-eshell
(eshell-insert-command "echo alpha")
(eshell-kill-output)
- (eshell-match-result (regexp-quote "*** output flushed ***\n"))
- (should (forward-line))
- (should (= (point) eshell-last-output-start))))
+ (eshell-match-result
+ (concat "^" (regexp-quote "*** output flushed ***\n") "$"))))
(ert-deftest eshell-test/run-old-command ()
"Re-run an old command"
diff --git a/test/lisp/ffap-tests.el b/test/lisp/ffap-tests.el
index 7c6b708f0a3..4b580b5af52 100644
--- a/test/lisp/ffap-tests.el
+++ b/test/lisp/ffap-tests.el
@@ -25,30 +25,29 @@
(require 'cl-lib)
(require 'ert)
+(require 'ert-x)
(require 'ffap)
(ert-deftest ffap-tests-25243 ()
"Test for https://debbugs.gnu.org/25243 ."
- (let ((file (make-temp-file "test-Bug#25243")))
- (unwind-protect
- (with-temp-file file
- (let ((str "diff --git b/lisp/ffap.el a/lisp/ffap.el
+ (ert-with-temp-file file
+ :suffix "-bug25243"
+ (let ((str "diff --git b/lisp/ffap.el a/lisp/ffap.el
index 3d7cebadcf..ad4b70d737 100644
--- b/lisp/ffap.el
+++ a/lisp/ffap.el
@@ -203,6 +203,9 @@ ffap-foo-at-bar-prefix
"))
- (transient-mark-mode 1)
- (when (natnump ffap-max-region-length)
- (insert
- (concat
- str
- (make-string ffap-max-region-length #xa)
- (format "%s ENDS HERE" file)))
- (call-interactively 'mark-whole-buffer)
- (should (equal "" (ffap-string-at-point)))
- (should (equal '(1 1) ffap-string-at-point-region)))))
- (and (file-exists-p file) (delete-file file)))))
+ (transient-mark-mode 1)
+ (when (natnump ffap-max-region-length)
+ (insert
+ (concat
+ str
+ (make-string ffap-max-region-length #xa)
+ (format "%s ENDS HERE" file)))
+ (call-interactively 'mark-whole-buffer)
+ (should (equal "" (ffap-string-at-point)))
+ (should (equal '(1 1) ffap-string-at-point-region))))))
(ert-deftest ffap-gopher-at-point ()
(with-temp-buffer
@@ -74,7 +73,7 @@ left alone when opening a URL in an external browser."
(urls nil)
(ffap-url-fetcher (lambda (url) (push url urls) nil)))
(should-not (ffap-other-window "https://www.gnu.org"))
- (should (compare-window-configurations (current-window-configuration) old))
+ (should (window-configuration-equal-p (current-window-configuration) old))
(should (equal urls '("https://www.gnu.org")))))
(defun ffap-test-string (space string)
@@ -133,7 +132,7 @@ left alone when opening a URL in an external browser."
;; Macros in BODY are expanded when the test is defined, not when it
;; is run. If a macro (possibly with side effects) is to be tested,
;; it has to be wrapped in `(eval (quote ...))'.
- (eval (quote (ido-everywhere)))
+ (eval (quote (ido-everywhere)) t)
(let ((read-file-name-function (lambda (&rest args)
(expand-file-name
(nth 4 args)
@@ -142,6 +141,23 @@ left alone when opening a URL in an external browser."
(let (kill-buffer-query-functions)
(kill-buffer (call-interactively #'find-file-at-point)))))))
+(ert-deftest ffap-test-path ()
+ (skip-unless (file-exists-p "/bin"))
+ (skip-unless (file-exists-p "/usr/bin"))
+ (with-temp-buffer
+ (insert "/usr/bin:/bin")
+ (goto-char (point-min))
+ (should (equal (ffap-file-at-point) "/usr/bin")))
+ (with-temp-buffer
+ (insert "/usr/bin:/bin")
+ (goto-char (point-min))
+ (search-forward ":")
+ (should (equal (ffap-file-at-point) "/bin")))
+ (with-temp-buffer
+ (insert ":/bin")
+ (goto-char (point-min))
+ (should (equal (ffap-file-at-point) nil))))
+
(provide 'ffap-tests)
;;; ffap-tests.el ends here
diff --git a/test/lisp/filenotify-tests.el b/test/lisp/filenotify-tests.el
index eabcbd51427..4ed1786a8ef 100644
--- a/test/lisp/filenotify-tests.el
+++ b/test/lisp/filenotify-tests.el
@@ -52,34 +52,9 @@
;;; Code:
-(require 'ert)
+(require 'tramp)
(require 'ert-x)
(require 'filenotify)
-(require 'tramp)
-
-;; There is no default value on w32 systems, which could work out of the box.
-(defconst file-notify-test-remote-temporary-file-directory
- (cond
- ((getenv "REMOTE_TEMPORARY_FILE_DIRECTORY"))
- ((eq system-type 'windows-nt) null-device)
- (t (add-to-list
- 'tramp-methods
- '("mock"
- (tramp-login-program "sh")
- (tramp-login-args (("-i")))
- (tramp-remote-shell "/bin/sh")
- (tramp-remote-shell-args ("-c"))
- (tramp-connection-timeout 10)))
- (add-to-list
- 'tramp-default-host-alist
- `("\\`mock\\'" nil ,(system-name)))
- ;; Emacs' Makefile sets $HOME to a nonexistent value. Needed in
- ;; batch mode only, therefore. `temporary-file-directory' might
- ;; be quoted, so we unquote it just in case.
- (unless (and (null noninteractive) (file-directory-p "~/"))
- (setenv "HOME" (file-name-unquote temporary-file-directory)))
- (format "/mock::%s" temporary-file-directory)))
- "Temporary directory for Tramp tests.")
;; Filter suppressed remote file-notify libraries.
(when (stringp (getenv "REMOTE_FILE_NOTIFY_LIBRARY"))
@@ -162,9 +137,7 @@ Return nil when any other file notification watch is still active."
(defun file-notify--test-cleanup ()
"Cleanup after a test."
- (file-notify-rm-watch file-notify--test-desc)
- (file-notify-rm-watch file-notify--test-desc1)
- (file-notify-rm-watch file-notify--test-desc2)
+ (file-notify-rm-all-watches)
(ignore-errors
(delete-file (file-newest-backup file-notify--test-tmpfile)))
@@ -205,10 +178,6 @@ Return nil when any other file notification watch is still active."
tramp-allow-unsafe-temporary-files
(or tramp-allow-unsafe-temporary-files noninteractive))
-;; This should happen on hydra only.
-(when (getenv "EMACS_HYDRA_CI")
- (add-to-list 'tramp-remote-path 'tramp-own-remote-path))
-
(defun file-notify--test-add-watch (file flags callback)
"Like `file-notify-add-watch', but also passing FILE to CALLBACK."
(file-notify-add-watch file flags
@@ -234,12 +203,12 @@ being the result.")
(let (desc)
(ignore-errors
(and
- (file-remote-p file-notify-test-remote-temporary-file-directory)
- (file-directory-p file-notify-test-remote-temporary-file-directory)
- (file-writable-p file-notify-test-remote-temporary-file-directory)
+ (file-remote-p ert-remote-temporary-file-directory)
+ (file-directory-p ert-remote-temporary-file-directory)
+ (file-writable-p ert-remote-temporary-file-directory)
(setq desc
(file-notify-add-watch
- file-notify-test-remote-temporary-file-directory
+ ert-remote-temporary-file-directory
'(change) #'ignore))))
(setq file-notify--test-remote-enabled-checked (cons t desc))
(when desc (file-notify-rm-watch desc))))
@@ -299,8 +268,7 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'."
`(ert-deftest ,(intern (concat (symbol-name test) "-remote")) ()
,docstring
:tags (if ,unstable '(:expensive-test :unstable) '(:expensive-test))
- (let* ((temporary-file-directory
- file-notify-test-remote-temporary-file-directory)
+ (let* ((temporary-file-directory ert-remote-temporary-file-directory)
(ert-test (ert-get-test ',test))
vc-handled-backends)
(skip-unless (file-notify--test-remote-enabled))
@@ -421,7 +389,7 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'."
;; This test is inspired by Bug#26126 and Bug#26127.
(ert-deftest file-notify-test02-rm-watch ()
- "Check `file-notify-rm-watch'."
+ "Check `file-notify-rm-watch' and `file-notify-rm-all-watches'."
(skip-unless (file-notify--test-local-enabled))
(unwind-protect
@@ -517,6 +485,31 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'."
(file-notify--test-cleanup-p))))
;; Cleanup.
+ (file-notify--test-cleanup))
+
+ (unwind-protect
+ ;; Check `file-notify-rm-all-watches'.
+ (progn
+ (setq file-notify--test-tmpfile (file-notify--test-make-temp-name)
+ file-notify--test-tmpfile1 (file-notify--test-make-temp-name))
+ (write-region "any text" nil file-notify--test-tmpfile nil 'no-message)
+ (write-region "any text" nil file-notify--test-tmpfile1 nil 'no-message)
+ (should
+ (setq file-notify--test-desc
+ (file-notify-add-watch
+ file-notify--test-tmpfile '(change) #'ignore)))
+ (should
+ (setq file-notify--test-desc1
+ (file-notify-add-watch
+ file-notify--test-tmpfile1 '(change) #'ignore)))
+ (file-notify-rm-all-watches)
+ (delete-file file-notify--test-tmpfile)
+ (delete-file file-notify--test-tmpfile1)
+
+ ;; The environment shall be cleaned up.
+ (file-notify--test-cleanup-p))
+
+ ;; Cleanup.
(file-notify--test-cleanup)))
(file-notify--deftest-remote file-notify-test02-rm-watch
diff --git a/test/lisp/files-resources/compile-utf8.el b/test/lisp/files-resources/compile-utf8.el
new file mode 100644
index 00000000000..1f804dcf8dc
--- /dev/null
+++ b/test/lisp/files-resources/compile-utf8.el
@@ -0,0 +1,12 @@
+;; -*- lexical-binding: t; -*-
+(defun zot ()
+ "Yes."
+ nil)
+
+(defun foo ()
+ "Yés."
+ nil)
+
+(defun bar ()
+ "Nó."
+ nil)
diff --git a/test/lisp/files-resources/file-mode b/test/lisp/files-resources/file-mode
new file mode 100644
index 00000000000..92ac4c30ef5
--- /dev/null
+++ b/test/lisp/files-resources/file-mode
@@ -0,0 +1,3 @@
+Local variables:
+mode: text
+end:
diff --git a/test/lisp/files-resources/file-mode-multiple b/test/lisp/files-resources/file-mode-multiple
new file mode 100644
index 00000000000..ac051ccbcbd
--- /dev/null
+++ b/test/lisp/files-resources/file-mode-multiple
@@ -0,0 +1,5 @@
+Local variables:
+mode: text
+mode: test-mode-undef
+mode: outline
+end:
diff --git a/test/lisp/files-resources/file-mode-prop-line b/test/lisp/files-resources/file-mode-prop-line
new file mode 100644
index 00000000000..e0e7ad24d71
--- /dev/null
+++ b/test/lisp/files-resources/file-mode-prop-line
@@ -0,0 +1 @@
+-*- mode: notexist; mode: text -*-
diff --git a/test/lisp/files-tests.el b/test/lisp/files-tests.el
index be9339a8f5b..54ada088003 100644
--- a/test/lisp/files-tests.el
+++ b/test/lisp/files-tests.el
@@ -136,7 +136,7 @@ form.")
;; Prevent any dir-locals file interfering with the tests.
(enable-dir-local-variables nil))
(hack-local-variables)
- (eval (nth 2 test-settings)))))
+ (eval (nth 2 test-settings) t))))
(ert-deftest files-tests-local-variables ()
"Test the file-local variables implementation."
@@ -176,15 +176,14 @@ form.")
;; If called interactively, environment variable
;; $EMACS_TEST_DIRECTORY does not exist.
(skip-unless (file-exists-p files-test-bug-18141-file))
- (let ((tempfile (make-temp-file "files-test-bug-18141" nil ".gz")))
- (unwind-protect
- (progn
- (copy-file files-test-bug-18141-file tempfile t)
- (with-current-buffer (find-file-noselect tempfile)
- (set-buffer-modified-p t)
- (save-buffer)
- (should (eq buffer-file-coding-system 'iso-2022-7bit-unix))))
- (delete-file tempfile))))
+ (ert-with-temp-file tempfile
+ :prefix "emacs-test-files-bug-18141"
+ :suffix ".gz"
+ (copy-file files-test-bug-18141-file tempfile t)
+ (with-current-buffer (find-file-noselect tempfile)
+ (set-buffer-modified-p t)
+ (save-buffer)
+ (should (eq buffer-file-coding-system 'iso-2022-7bit-unix)))))
(ert-deftest files-tests-make-temp-file-empty-prefix ()
"Test make-temp-file with an empty prefix."
@@ -264,7 +263,7 @@ form.")
nil))
(kill-emacs-args nil)
((symbol-function #'kill-emacs)
- (lambda (&optional arg) (push arg kill-emacs-args)))
+ (lambda (&rest args) (push args kill-emacs-args)))
(process
(make-process
:name "sleep"
@@ -275,7 +274,7 @@ form.")
(save-buffers-kill-emacs)
(kill-process process)
(should-not yes-or-no-p-prompts)
- (should (equal kill-emacs-args '(nil)))))
+ (should (equal kill-emacs-args '((nil nil))))))
(ert-deftest files-tests-read-file-in-~ ()
"Test file prompting in directory named `~'.
@@ -283,22 +282,20 @@ If we are in a directory named `~', the default value should not
be $HOME."
(cl-letf (((symbol-function 'completing-read)
(lambda (_prompt _coll &optional _pred _req init _hist def _)
- (or def init)))
- (dir (make-temp-file "read-file-name-test" t)))
- (unwind-protect
- (let ((subdir (expand-file-name "./~/" dir)))
- (make-directory subdir t)
- (with-temp-buffer
- (setq default-directory subdir)
- (should-not (equal
- (expand-file-name (read-file-name "File: "))
- (expand-file-name "~/")))
- ;; Don't overquote either!
- (setq default-directory (concat "/:" subdir))
- (should-not (equal
- (expand-file-name (read-file-name "File: "))
- (concat "/:/:" subdir)))))
- (delete-directory dir 'recursive))))
+ (or def init))))
+ (ert-with-temp-directory dir
+ (let ((subdir (expand-file-name "./~/" dir)))
+ (make-directory subdir t)
+ (with-temp-buffer
+ (setq default-directory subdir)
+ (should-not (equal
+ (expand-file-name (read-file-name "File: "))
+ (expand-file-name "~/")))
+ ;; Don't overquote either!
+ (setq default-directory (concat "/:" subdir))
+ (should-not (equal
+ (expand-file-name (read-file-name "File: "))
+ (concat "/:/:" subdir))))))))
(ert-deftest files-tests-file-name-non-special-quote-unquote ()
(let (;; Just in case it is quoted, who knows.
@@ -341,14 +338,6 @@ be $HOME."
(progn ,@body)
(advice-remove #',symbol ,function)))))
-(defmacro files-tests--with-temp-file (name &rest body)
- (declare (indent 1) (debug (symbolp body)))
- (cl-check-type name symbol)
- `(let ((,name (make-temp-file "emacs")))
- (unwind-protect
- (progn ,@body)
- (delete-file ,name))))
-
(ert-deftest files-tests-file-name-non-special--buffers ()
"Check that Bug#25951 is fixed.
We call `verify-visited-file-modtime' on a buffer visiting a file
@@ -357,7 +346,7 @@ the buffer current and a nil argument, second passing the buffer
object explicitly. In both cases no error should be raised and
the `file-name-non-special' handler for quoted file names should
be invoked with the right arguments."
- (files-tests--with-temp-file temp-file-name
+ (ert-with-temp-file temp-file-name
(with-temp-buffer
(let* ((buffer-visiting-file (current-buffer))
(actual-args ())
@@ -404,6 +393,8 @@ After evaluating BODY, the temporary file or directory is deleted."
(cl-check-type name symbol)
(cl-check-type non-special-name symbol)
`(let* ((temporary-file-directory (file-truename temporary-file-directory))
+ (temporary-file-directory
+ (file-name-as-directory (make-temp-file "files-tests" t)))
(,name (make-temp-file "files-tests" ,dir-flag))
(,non-special-name (file-name-quote ,name)))
(unwind-protect
@@ -413,7 +404,9 @@ After evaluating BODY, the temporary file or directory is deleted."
(delete-file ,name)))
(when (file-exists-p ,non-special-name)
(if ,dir-flag (delete-directory ,non-special-name t)
- (delete-file ,non-special-name))))))
+ (delete-file ,non-special-name)))
+ (when (file-exists-p temporary-file-directory)
+ (delete-directory temporary-file-directory t)))))
(defconst files-tests--special-file-name-extension ".special"
"Trailing string for test file name handler.")
@@ -455,14 +448,16 @@ unquoted file names."
(cl-check-type name symbol)
(cl-check-type non-special-name symbol)
`(let* ((temporary-file-directory (file-truename temporary-file-directory))
+ (temporary-file-directory
+ (file-name-as-directory (make-temp-file "files-tests" t)))
(file-name-handler-alist
`((,files-tests--special-file-name-regexp
. files-tests--special-file-name-handler)
. ,file-name-handler-alist))
- (,name (concat
+ (,name (concat
(make-temp-file "files-tests" ,dir-flag)
files-tests--special-file-name-extension))
- (,non-special-name (file-name-quote ,name)))
+ (,non-special-name (file-name-quote ,name)))
(unwind-protect
(progn ,@body)
(when (file-exists-p ,name)
@@ -470,12 +465,23 @@ unquoted file names."
(delete-file ,name)))
(when (file-exists-p ,non-special-name)
(if ,dir-flag (delete-directory ,non-special-name t)
- (delete-file ,non-special-name))))))
+ (delete-file ,non-special-name)))
+ (when (file-exists-p temporary-file-directory)
+ (delete-directory temporary-file-directory t)))))
(defun files-tests--new-name (name part)
(let (file-name-handler-alist)
(concat (file-name-sans-extension name) part (file-name-extension name t))))
+(ert-deftest files-tests-file-name-non-special-abbreviate-file-name ()
+ (let* ((homedir temporary-file-directory)
+ (process-environment (cons (format "HOME=%s" homedir)
+ process-environment))
+ (abbreviated-home-dir nil))
+ ;; Check that abbreviation doesn't occur for quoted file names.
+ (should (equal (concat "/:" homedir "foo/bar")
+ (abbreviate-file-name (concat "/:" homedir "foo/bar"))))))
+
(ert-deftest files-tests-file-name-non-special-access-file ()
(files-tests--with-temp-non-special (tmpfile nospecial)
;; Both versions of the file name work.
@@ -933,7 +939,7 @@ unquoted file names."
(files-tests--with-temp-non-special (tmpfile nospecial)
(should (load nospecial nil t)))
(files-tests--with-temp-non-special-and-file-name-handler (tmpfile nospecial)
- (should (load nospecial nil t))))
+ (should-error (load nospecial nil t))))
(ert-deftest files-tests-file-name-non-special-make-auto-save-file-name ()
(files-tests--with-temp-non-special (tmpfile nospecial)
@@ -1239,26 +1245,26 @@ works as expected if the default directory is quoted."
(insert-directory-wildcard-in-dir-p (car path-res)))))))
(ert-deftest files-tests-make-directory ()
- (let* ((dir (make-temp-file "files-mkdir-test" t))
- (dirname (file-name-as-directory dir))
- (file (concat dirname "file"))
- (subdir1 (concat dirname "subdir1"))
- (subdir2 (concat dirname "subdir2"))
- (a/b (concat dirname "a/b")))
- (write-region "" nil file)
- (should-error (make-directory "/"))
- (should-not (make-directory "/" t))
- (should-error (make-directory dir))
- (should-not (make-directory dir t))
- (should-error (make-directory dirname))
- (should-not (make-directory dirname t))
- (should-error (make-directory file))
- (should-error (make-directory file t))
- (should-not (make-directory subdir1))
- (should-not (make-directory subdir2 t))
- (should-error (make-directory a/b))
- (should-not (make-directory a/b t))
- (delete-directory dir 'recursive)))
+ (ert-with-temp-directory dir
+ (let* ((dirname (file-name-as-directory dir))
+ (file (concat dirname "file"))
+ (subdir1 (concat dirname "subdir1"))
+ (subdir2 (concat dirname "subdir2"))
+ (a/b (concat dirname "a/b")))
+ (write-region "" nil file)
+ (should-error (make-directory "/"))
+ (should-not (make-directory "/" t))
+ (should-error (make-directory dir))
+ (should-not (make-directory dir t))
+ (should-error (make-directory dirname))
+ (should-not (make-directory dirname t))
+ (should-error (make-directory file))
+ (should-error (make-directory file t))
+ (should-not (make-directory subdir1))
+ (should-not (make-directory subdir2 t))
+ (should-error (make-directory a/b))
+ (should-not (make-directory a/b t))
+ (delete-directory dir 'recursive))))
(ert-deftest files-tests-file-modes-symbolic-to-number ()
(let ((alist (list (cons "a=rwx" #o777)
@@ -1318,7 +1324,7 @@ name (Bug#28412)."
(set-buffer-modified-p t)
(should-error (save-buffer) :type 'error))
;; Then a buffer visiting a file: should save normally.
- (files-tests--with-temp-file temp-file-name
+ (ert-with-temp-file temp-file-name
(with-current-buffer (find-file-noselect temp-file-name)
(setq write-contents-functions nil)
(insert "p")
@@ -1326,21 +1332,21 @@ name (Bug#28412)."
(should (eq (buffer-size) 1))))))
(ert-deftest files-tests-copy-directory ()
- (let* ((dir (make-temp-file "files-mkdir-test" t))
- (dirname (file-name-as-directory dir))
- (source (concat dirname "source"))
- (dest (concat dirname "dest/new/directory/"))
- (file (concat (file-name-as-directory source) "file"))
- (source2 (concat dirname "source2"))
- (dest2 (concat dirname "dest/new2")))
- (make-directory source)
- (write-region "" nil file)
- (copy-directory source dest t t t)
- (should (file-exists-p (concat dest "file")))
- (make-directory (concat (file-name-as-directory source2) "a") t)
- (copy-directory source2 dest2)
- (should (file-directory-p (concat (file-name-as-directory dest2) "a")))
- (delete-directory dir 'recursive)))
+ (ert-with-temp-directory dir
+ (let* ((dirname (file-name-as-directory dir))
+ (source (concat dirname "source"))
+ (dest (concat dirname "dest/new/directory/"))
+ (file (concat (file-name-as-directory source) "file"))
+ (source2 (concat dirname "source2"))
+ (dest2 (concat dirname "dest/new2")))
+ (make-directory source)
+ (write-region "" nil file)
+ (copy-directory source dest t t t)
+ (should (file-exists-p (concat dest "file")))
+ (make-directory (concat (file-name-as-directory source2) "a") t)
+ (copy-directory source2 dest2)
+ (should (file-directory-p (concat (file-name-as-directory dest2) "a")))
+ (delete-directory dir 'recursive))))
(ert-deftest files-tests-abbreviate-file-name-homedir ()
;; Check homedir abbreviation.
@@ -1392,43 +1398,43 @@ See <https://debbugs.gnu.org/19657#20>."
(ert-deftest files-tests-executable-find ()
"Test that `executable-find' works also with a relative or remote PATH.
See <https://debbugs.gnu.org/35241>."
- (let ((tmpfile (make-temp-file "files-test" nil (car exec-suffixes))))
- (unwind-protect
- (progn
- (set-file-modes tmpfile #o777)
- (let ((exec-path `(,temporary-file-directory)))
- (should
- (equal tmpfile
- (executable-find (file-name-nondirectory tmpfile)))))
- ;; An empty element of `exec-path' means `default-directory'.
- (let ((default-directory temporary-file-directory)
- (exec-path nil))
- (should
- (equal tmpfile
- (executable-find (file-name-nondirectory tmpfile)))))
- ;; The remote file name shall be quoted, and handled like a
- ;; non-existing directory.
- (let ((default-directory "/ssh::")
- (exec-path (append exec-path `("." ,temporary-file-directory))))
- (should
- (equal tmpfile
- (executable-find (file-name-nondirectory tmpfile))))))
- (delete-file tmpfile))))
-
-(ert-deftest files-tests-dont-rewrite-precious-files ()
+ (ert-with-temp-file tmpfile
+ :suffix (car exec-suffixes)
+ (set-file-modes tmpfile #o755)
+ (let ((exec-path `(,temporary-file-directory)))
+ (should
+ (equal tmpfile
+ (executable-find (file-name-nondirectory tmpfile)))))
+ ;; An empty element of `exec-path' means `default-directory'.
+ (let ((default-directory temporary-file-directory)
+ (exec-path nil))
+ (should
+ (equal tmpfile
+ (executable-find (file-name-nondirectory tmpfile)))))
+ ;; The remote file name shall be quoted, and handled like a
+ ;; non-existing directory.
+ (let ((default-directory "/ssh::")
+ (exec-path (append exec-path `("." ,temporary-file-directory))))
+ (should
+ (equal tmpfile
+ (executable-find (file-name-nondirectory tmpfile)))))))
+
+;; Note: we call this test "...-zzdont..." so that it runs near the
+;; end, because otherwise the advice it adds to write-region doesn't
+;; get removed(??) and breaks the revert-file tests on MS-Windows.
+(ert-deftest files-tests-zzdont-rewrite-precious-files ()
"Test that `file-precious-flag' forces files to be saved by
renaming only, rather than modified in-place."
- (let* ((temp-file-name (make-temp-file "files-tests"))
- (advice (lambda (_start _end filename &rest _r)
- (should-not (string= filename temp-file-name)))))
- (unwind-protect
- (with-current-buffer (find-file-noselect temp-file-name)
- (advice-add #'write-region :before advice)
- (setq-local file-precious-flag t)
- (insert "foobar")
- (should (null (save-buffer))))
- (ignore-errors (advice-remove #'write-region advice))
- (ignore-errors (delete-file temp-file-name)))))
+ (ert-with-temp-file temp-file-name
+ (let* ((advice (lambda (_start _end filename &rest _r)
+ (should-not (string= filename temp-file-name)))))
+ (unwind-protect
+ (with-current-buffer (find-file-noselect temp-file-name)
+ (advice-add #'write-region :before advice)
+ (setq-local file-precious-flag t)
+ (insert "foobar")
+ (should (null (save-buffer))))
+ (ignore-errors (advice-remove #'write-region advice))))))
(ert-deftest files-test-file-size-human-readable ()
(should (equal (file-size-human-readable 13) "13"))
@@ -1462,7 +1468,7 @@ renaming only, rather than modified in-place."
(should (equal (file-size-human-readable-iec 0) "0 B"))
(should (equal (file-size-human-readable-iec 1) "1 B"))
(should (equal (file-size-human-readable-iec 9621) "9.4 KiB"))
- (should (equal (file-size-human-readable-iec 72528034765) "67.5 GiB")))
+ (should (equal (file-size-human-readable-iec 72528034765) "68 GiB")))
(ert-deftest files-test-magic-mode-alist-re-baseline ()
"Test magic-mode-alist with RE, expected behavior for match."
@@ -1542,7 +1548,7 @@ The door of all subtleties!
(ert-deftest files-tests-revert-buffer ()
"Test that revert-buffer is successful."
- (files-tests--with-temp-file temp-file-name
+ (ert-with-temp-file temp-file-name
(with-temp-buffer
(insert files-tests-lao)
(write-file temp-file-name)
@@ -1555,7 +1561,7 @@ The door of all subtleties!
(ert-deftest files-tests-revert-buffer-with-fine-grain ()
"Test that revert-buffer-with-fine-grain is successful."
- (files-tests--with-temp-file temp-file-name
+ (ert-with-temp-file temp-file-name
(with-temp-buffer
(insert files-tests-lao)
(write-file temp-file-name)
@@ -1584,6 +1590,14 @@ The door of all subtleties!
(should-error (file-name-with-extension "Jack" "."))
(should-error (file-name-with-extension "/is/a/directory/" "css")))
+(ert-deftest files-tests-file-name-base ()
+ (should (equal (file-name-base "") ""))
+ (should (equal (file-name-base "/foo/") ""))
+ (should (equal (file-name-base "/foo") "foo"))
+ (should (equal (file-name-base "/foo/bar") "bar"))
+ (should (equal (file-name-base "foo") "foo"))
+ (should (equal (file-name-base "foo/bar") "bar")))
+
(ert-deftest files-test-dir-locals-auto-mode-alist ()
"Test an `auto-mode-alist' entry in `.dir-locals.el'"
(find-file (ert-resource-file "whatever.quux"))
@@ -1611,40 +1625,39 @@ on BUF-1 and BUF-2 after the `save-some-buffers' call.
The test is repeated with `save-some-buffers-default-predicate'
let-bound to PRED and passing nil as second arg of
`save-some-buffers'."
- (let* ((dir (make-temp-file "testdir" 'dir))
- (file-1 (expand-file-name "subdir-1/file.foo" dir))
- (file-2 (expand-file-name "subdir-2/file.bar" dir))
- (inhibit-message t)
- buf-1 buf-2)
- (unwind-protect
- (progn
- (make-empty-file file-1 'parens)
- (make-empty-file file-2 'parens)
- (setq buf-1 (find-file file-1)
- buf-2 (find-file file-2))
- (dolist (buf (list buf-1 buf-2))
- (with-current-buffer buf (insert "foobar\n")))
- ;; Run the test.
- (with-current-buffer buf-1
- (let ((save-some-buffers-default-predicate def-pred-bind))
- (save-some-buffers t pred))
- (should (eq exp-1 (buffer-modified-p buf-1)))
- (should (eq exp-2 (buffer-modified-p buf-2))))
- ;; Set both buffers as modified to run another test.
- (dolist (buf (list buf-1 buf-2))
- (with-current-buffer buf (set-buffer-modified-p t)))
- ;; The result of this test must be identical as the previous one.
- (with-current-buffer buf-1
- (let ((save-some-buffers-default-predicate (or pred def-pred-bind)))
- (save-some-buffers t nil))
- (should (eq exp-1 (buffer-modified-p buf-1)))
- (should (eq exp-2 (buffer-modified-p buf-2)))))
- ;; Clean up.
- (dolist (buf (list buf-1 buf-2))
- (with-current-buffer buf
- (set-buffer-modified-p nil)
- (kill-buffer buf)))
- (delete-directory dir 'recursive))))
+ (ert-with-temp-directory dir
+ (let* ((file-1 (expand-file-name "subdir-1/file.foo" dir))
+ (file-2 (expand-file-name "subdir-2/file.bar" dir))
+ (inhibit-message t)
+ buf-1 buf-2)
+ (unwind-protect
+ (progn
+ (make-empty-file file-1 'parens)
+ (make-empty-file file-2 'parens)
+ (setq buf-1 (find-file file-1)
+ buf-2 (find-file file-2))
+ (dolist (buf (list buf-1 buf-2))
+ (with-current-buffer buf (insert "foobar\n")))
+ ;; Run the test.
+ (with-current-buffer buf-1
+ (let ((save-some-buffers-default-predicate def-pred-bind))
+ (save-some-buffers t pred))
+ (should (eq exp-1 (buffer-modified-p buf-1)))
+ (should (eq exp-2 (buffer-modified-p buf-2))))
+ ;; Set both buffers as modified to run another test.
+ (dolist (buf (list buf-1 buf-2))
+ (with-current-buffer buf (set-buffer-modified-p t)))
+ ;; The result of this test must be identical as the previous one.
+ (with-current-buffer buf-1
+ (let ((save-some-buffers-default-predicate (or pred def-pred-bind)))
+ (save-some-buffers t nil))
+ (should (eq exp-1 (buffer-modified-p buf-1)))
+ (should (eq exp-2 (buffer-modified-p buf-2)))))
+ ;; Clean up.
+ (dolist (buf (list buf-1 buf-2))
+ (with-current-buffer buf
+ (set-buffer-modified-p nil)
+ (kill-buffer buf)))))))
(ert-deftest files-tests-save-some-buffers ()
"Test `save-some-buffers'.
@@ -1671,7 +1684,7 @@ PRED is nil."
(pcase-dolist (`(,pred ,def-pred-bind ,exp-1 ,exp-2) args-results)
(files-tests--save-some-buffers pred def-pred-bind exp-1 exp-2))))
-(defmacro files-tests--with-buffer-offer-save (buffers-offer fn-test fn-binders args-results)
+(defun files-tests--with-buffer-offer-save (buffers-offer fn-test args-results)
"Helper macro to test `save-some-buffers' and `save-buffers-kill-emacs'.
This macro creates several non-file-visiting buffers in different
@@ -1685,52 +1698,52 @@ FN-TEST is the function to test: either `save-some-buffers' or
`save-some-buffers-default-predicate' let-bound to a value
specified inside ARGS-RESULTS.
-FN-BINDERS is a list of elements (FUNCTION . BINDING), where FUNCTION
-is a function symbol that this macro temporary binds to BINDING during
-the FN-TEST call.
+During the call to FN-TEST,`read-event' is overridden with a function that
+just returns `n' and `kill-emacs' is overridden to do nothing.
ARGS-RESULTS is a list of elements (FN-ARGS CALLERS-DIR EXPECTED), where
FN-ARGS are the arguments for FN-TEST;
CALLERS-DIR specifies the value to let-bind
\`save-some-buffers-default-predicate';
EXPECTED is the expected result of the test."
- (declare (debug (form symbol form form)))
- (let ((dir (gensym "dir"))
- (buffers (gensym "buffers")))
- `(let* ((,dir (make-temp-file "testdir" 'dir))
- (inhibit-message t)
- (use-dialog-box nil)
- ,buffers)
- (pcase-dolist (`(,bufsym ,offer-save) ,buffers-offer)
- (let* ((buf (generate-new-buffer (symbol-name bufsym)))
- (subdir (expand-file-name
- (format "subdir-%s" (buffer-name buf))
- ,dir)))
- (make-directory subdir 'parens)
- (push buf ,buffers)
- (with-current-buffer buf
- (cd subdir)
- (setq buffer-offer-save offer-save)
- (insert "foobar\n"))))
- (setq ,buffers (nreverse ,buffers))
- (let ((nb-saved-buffers 0))
- (unwind-protect
- (pcase-dolist (`(,fn-test-args ,callers-dir ,expected)
- ,args-results)
- (setq nb-saved-buffers 0)
- (with-current-buffer (car ,buffers)
- (cl-letf
- (,@(mapcar (lambda (pair) `((symbol-function ,(car pair)) ,(cdr pair)))
- fn-binders)
- (save-some-buffers-default-predicate callers-dir))
- (apply #',fn-test fn-test-args)
- (should (equal nb-saved-buffers expected)))))
- ;; Clean up.
- (dolist (buf ,buffers)
- (with-current-buffer buf
- (set-buffer-modified-p nil)
- (kill-buffer buf)))
- (delete-directory ,dir 'recursive))))))
+ (let* ((dir (make-temp-file "testdir" 'dir))
+ (inhibit-message t)
+ (use-dialog-box nil)
+ buffers)
+ (pcase-dolist (`(,bufsym ,offer-save) buffers-offer)
+ (let* ((buf (generate-new-buffer (symbol-name bufsym)))
+ (subdir (expand-file-name
+ (format "subdir-%s" (buffer-name buf))
+ dir)))
+ (make-directory subdir 'parens)
+ (push buf buffers)
+ (with-current-buffer buf
+ (cd subdir)
+ (setq buffer-offer-save offer-save)
+ (insert "foobar\n"))))
+ (setq buffers (nreverse buffers))
+ (let ((nb-saved-buffers 0))
+ (unwind-protect
+ (pcase-dolist (`(,fn-test-args ,callers-dir ,expected)
+ args-results)
+ (setq nb-saved-buffers 0)
+ (with-current-buffer (car buffers)
+ (cl-letf
+ (((symbol-function 'read-event)
+ ;; Increase counter and answer 'n' when prompted
+ ;; to save a buffer.
+ (lambda (&rest _) (cl-incf nb-saved-buffers) ?n))
+ ;; Do not kill Emacs.
+ ((symbol-function 'kill-emacs) #'ignore)
+ (save-some-buffers-default-predicate callers-dir))
+ (apply fn-test fn-test-args)
+ (should (equal nb-saved-buffers expected)))))
+ ;; Clean up.
+ (dolist (buf buffers)
+ (with-current-buffer buf
+ (set-buffer-modified-p nil)
+ (kill-buffer buf)))
+ (delete-directory dir 'recursive)))))
(defmacro files-tests-with-all-permutations (permutation list &rest body)
"Execute BODY forms for all permutations of LIST.
@@ -1782,9 +1795,7 @@ PRED is nil."
(args-res `(((nil ,pred) ,callers-dir ,res))))
(files-tests--with-buffer-offer-save
buffers-offer
- save-some-buffers
- ;; Increase counter and answer 'n' when prompted to save a buffer.
- (('read-event . (lambda (&rest _) (cl-incf nb-saved-buffers) ?n)))
+ #'save-some-buffers
args-res)))))))
(ert-deftest files-tests-save-buffers-kill-emacs--asks-to-save-buffers ()
@@ -1799,14 +1810,62 @@ Prompt users for any modified buffer with `buffer-offer-save' non-nil."
buffers-offer-init
(files-tests--with-buffer-offer-save
buffers-offer
- save-buffers-kill-emacs
- ;; Increase counter and answer 'n' when prompted to save a buffer.
- (('read-event . (lambda (&rest _) (cl-incf nb-saved-buffers) ?n))
- ('kill-emacs . #'ignore)) ; Do not kill Emacs.
+ #'save-buffers-kill-emacs
`((nil nil ,nb-might-save)
;; `save-some-buffers-default-predicate' (i.e. the 2nd element) is ignored.
(nil save-some-buffers-root ,nb-might-save))))))
+(ert-deftest test-file-name-split ()
+ (should (equal (file-name-split "foo/bar") '("foo" "bar")))
+ (should (equal (file-name-split "/foo/bar") '("" "foo" "bar")))
+ (should (equal (file-name-split "/foo/bar/zot") '("" "foo" "bar" "zot")))
+ (should (equal (file-name-split "/foo/bar/") '("" "foo" "bar" "")))
+ (should (equal (file-name-split "foo/bar/") '("foo" "bar" ""))))
+
+(ert-deftest files-test-set-mode ()
+ (find-file (ert-resource-file "file-mode"))
+ (should (eq major-mode 'text-mode))
+ (emacs-lisp-mode)
+ ;; Check that the mode cookie doesn't override the explicit setting.
+ (should (eq major-mode 'emacs-lisp-mode)))
+
+(ert-deftest files-test-set-mode-multiple ()
+ (find-file (ert-resource-file "file-mode-multiple"))
+ (should (eq major-mode 'outline-mode)))
+
+(ert-deftest files-test-set-mode-prop-line ()
+ (find-file (ert-resource-file "file-mode-prop-line"))
+ (should (eq major-mode 'text-mode)))
+
+(ert-deftest files-load-elc-gz-file ()
+ (skip-unless (executable-find "gzip"))
+ (ert-with-temp-directory dir
+ (let* ((pref (expand-file-name "compile-utf8" dir))
+ (el (concat pref ".el")))
+ (copy-file (ert-resource-file "compile-utf8.el") el)
+ (push dir load-path)
+ (should (load pref t))
+ (should (fboundp 'foo))
+ (should (documentation 'foo))
+ (should (documentation 'bar))
+ (should (documentation 'zot))
+
+ (byte-compile-file el)
+ (fmakunbound 'foo)
+ (should (load (concat pref ".elc") t))
+ (should (fboundp 'foo))
+ (should (documentation 'foo))
+ (should (documentation 'bar))
+ (should (documentation 'zot))
+
+ (dired-compress-file (concat pref ".elc"))
+ (fmakunbound 'foo)
+ (should (load (concat pref ".elc.gz") t))
+ (should (fboundp 'foo))
+ ;; This fails due to bug#12598.
+ (should (documentation 'foo))
+ (should (documentation 'bar))
+ (should (documentation 'zot)))))
(provide 'files-tests)
;;; files-tests.el ends here
diff --git a/test/lisp/files-x-tests.el b/test/lisp/files-x-tests.el
index 60787e1cd3d..7ee2f0c1a65 100644
--- a/test/lisp/files-x-tests.el
+++ b/test/lisp/files-x-tests.el
@@ -325,6 +325,9 @@
(should-not (boundp 'remote-shell-file-name))
(should (string-equal (symbol-value 'remote-null-device) "null"))
+ (connection-local-set-profiles
+ files-x-test--application 'remote-bash)
+
(with-connection-local-variables
;; All connection-local variables are set. They apply in
;; reverse order in `connection-local-variables-alist'.
@@ -347,6 +350,21 @@
(should
(string-equal (symbol-value 'remote-shell-file-name) "/bin/ksh"))
(should
+ (string-equal (symbol-value 'remote-null-device) "/dev/null"))
+
+ ;; Run another instance of `with-connection-local-variables'
+ ;; with a different application.
+ (let ((connection-local-default-application (cadr files-x-test--application)))
+ (with-connection-local-variables
+ ;; The proper variable values are set.
+ (should
+ (string-equal (symbol-value 'remote-shell-file-name) "/bin/bash"))
+ (should
+ (string-equal (symbol-value 'remote-null-device) "/dev/null"))))
+ ;; The variable values are reset.
+ (should
+ (string-equal (symbol-value 'remote-shell-file-name) "/bin/ksh"))
+ (should
(string-equal (symbol-value 'remote-null-device) "/dev/null")))
;; Everything is rewound. The old variable values are reset.
diff --git a/test/lisp/format-spec-tests.el b/test/lisp/format-spec-tests.el
index 0062a7d4cb6..4a3cc74c334 100644
--- a/test/lisp/format-spec-tests.el
+++ b/test/lisp/format-spec-tests.el
@@ -56,7 +56,7 @@
(ert-deftest format-spec-do-flags-truncate ()
"Test `format-spec--do-flags' truncation."
- (let (flags)
+ (let ((flags nil))
(should (equal (format-spec--do-flags "" flags nil 0) ""))
(should (equal (format-spec--do-flags "" flags nil 1) ""))
(should (equal (format-spec--do-flags "a" flags nil 0) ""))
@@ -75,7 +75,7 @@
(ert-deftest format-spec-do-flags-pad ()
"Test `format-spec--do-flags' padding."
- (let (flags)
+ (let ((flags nil))
(should (equal (format-spec--do-flags "" flags 0 nil) ""))
(should (equal (format-spec--do-flags "" flags 1 nil) " "))
(should (equal (format-spec--do-flags "a" flags 0 nil) "a"))
diff --git a/test/lisp/gnus/gnus-group-tests.el b/test/lisp/gnus/gnus-group-tests.el
new file mode 100644
index 00000000000..4ae5fea3eb7
--- /dev/null
+++ b/test/lisp/gnus/gnus-group-tests.el
@@ -0,0 +1,52 @@
+;;; gnus-group-tests.el --- Tests for gnus-group.el -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021-2022 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'gnus-group)
+(require 'ert)
+
+(ert-deftest gnus-short-group-name ()
+ (map-apply
+ (lambda (input expected)
+ (should (string-equal (gnus-short-group-name input) expected)))
+ '(("nnimap+email@example.com:archives/2020/03" . "email@example:a/2/03")
+ ("nndiary+diary:birthdays" . "diary:birthdays")
+ ("nnimap+email@example.com:test" . "email@example:test")
+ ("nnimap+email@example.com:234" . "email@example:234")
+
+ ;; This is a very aggressive shortening of the left hand side.
+ ("nnimap+email@banana.salesman.example.com:234" . "email@banana:234")
+ ("nntp+some.where.edu:soc.motss" . "some:s.motss")
+ ("nntp+news.gmane.org:gmane.emacs.gnus.general" . "news:g.e.g.general")
+ ("nntp+news.gnus.org:gmane.text.docbook.apps" . "news:g.t.d.apps")
+
+ ;; nnimap groups.
+ ("nnimap+email@example.com:[Invoices]/Bananas" . "email@example:I/Bananas")
+ ("nnimap+email@banana.salesman.example.com:[Invoices]/Bananas"
+ . "email@banana:I/Bananas")
+
+ ;; The "n" from "nnspool" is perhaps not optimal.
+ ("nnspool+alt.binaries.pictures.furniture" . "n.b.p.furniture"))))
+
+;;; gnus-group-tests.el ends here
diff --git a/test/lisp/gnus/gnus-icalendar-tests.el b/test/lisp/gnus/gnus-icalendar-tests.el
index 0118bc354c4..348ddf9f056 100644
--- a/test/lisp/gnus/gnus-icalendar-tests.el
+++ b/test/lisp/gnus/gnus-icalendar-tests.el
@@ -216,7 +216,7 @@ RRULE:FREQ=WEEKLY;BYDAY=FR,MO,TH,TU,WE
DTSTAMP:20200915T120627Z
ORGANIZER;CN=anon@anoncompany.com:mailto:anon@anoncompany.com
UID:7b6g3m7iftuo90ei4ul00feqn_R20200915T120000@google.com
-ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;RSVP=TRUE
+ATTENDEE;CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED;RSVP=TRUE
;CN=participant@anoncompany.com;X-NUM-GUESTS=0:mailto:participant@anoncompany.com
CREATED:20200325T095723Z
DESCRIPTION:Coffee talk
diff --git a/test/lisp/gnus/mml-sec-tests.el b/test/lisp/gnus/mml-sec-tests.el
index 182d82b9618..f308a617645 100644
--- a/test/lisp/gnus/mml-sec-tests.el
+++ b/test/lisp/gnus/mml-sec-tests.el
@@ -605,6 +605,9 @@ In this test, the encryption key needs to fixed among multiple ones."
(ert-deftest mml-secure-en-decrypt-3 ()
"Encrypt message; then decrypt and test for expected result.
In this test, encrypt-to-self variables are set to t."
+ ;; Random failures with "wrong-type-argument stringp nil".
+ ;; Seems unlikely to be specific to hydra.nixos.org...
+ :tags (if (getenv "EMACS_HYDRA_CI") '(:unstable))
(skip-unless (test-conf))
(skip-unless (ignore-errors (epg-find-configuration 'CMS)))
;; sub@example.org with multiple candidate keys,
diff --git a/test/lisp/help-fns-tests.el b/test/lisp/help-fns-tests.el
index 4002501ddee..e3fed60b4cb 100644
--- a/test/lisp/help-fns-tests.el
+++ b/test/lisp/help-fns-tests.el
@@ -25,6 +25,7 @@
(require 'ert)
(require 'help-fns)
+(require 'subr-x)
(autoload 'help-fns-test--macro "foo" nil nil t)
@@ -148,7 +149,7 @@ Return first line of the output of (describe-function-1 FUNC)."
(ert-deftest help-fns-test-describe-keymap/value ()
(describe-keymap minibuffer-local-must-match-map)
(with-current-buffer "*Help*"
- (should (looking-at "^key"))))
+ (should (looking-at "\nKey"))))
(ert-deftest help-fns-test-describe-keymap/not-keymap ()
(should-error (describe-keymap nil))
@@ -158,7 +159,7 @@ Return first line of the output of (describe-function-1 FUNC)."
(let ((foobar minibuffer-local-must-match-map))
(describe-keymap foobar)
(with-current-buffer "*Help*"
- (should (looking-at "^key")))))
+ (should (looking-at "\nKey")))))
(ert-deftest help-fns-test-describe-keymap/dynamically-bound-no-file ()
(setq help-fns-test--describe-keymap-foo minibuffer-local-must-match-map)
@@ -177,4 +178,13 @@ Return first line of the output of (describe-function-1 FUNC)."
(should-not (find-lisp-object-file-name help-fns--test-var 'defface))
(should-not (find-lisp-object-file-name help-fns--test-var 1))))
+(ert-deftest help-fns--analyze-function-recursive ()
+ (defalias 'help-fns--a 'help-fns--b)
+ (should (equal (help-fns--analyze-function 'help-fns--a)
+ '(help-fns--a help-fns--b t help-fns--b)))
+ ;; Make a loop and see that it doesn't infloop.
+ (defalias 'help-fns--b 'help-fns--a)
+ (should (equal (help-fns--analyze-function 'help-fns--a)
+ '(help-fns--a help-fns--b t help-fns--b))))
+
;;; help-fns-tests.el ends here
diff --git a/test/lisp/help-mode-tests.el b/test/lisp/help-mode-tests.el
index c0c1cf8b530..04241f31383 100644
--- a/test/lisp/help-mode-tests.el
+++ b/test/lisp/help-mode-tests.el
@@ -41,11 +41,6 @@
(should (equal (buffer-name (current-buffer))
(help-buffer))))))
-(ert-deftest help-mode-tests-help-buffer-current-buffer-error ()
- (with-temp-buffer
- (let ((help-xref-following t))
- (should-error (help-buffer)))))
-
(ert-deftest help-mode-tests-make-xrefs ()
(with-temp-buffer
(insert "car is a built-in function in ‘C source code’.
@@ -81,7 +76,7 @@ Lisp concepts such as car, cdr, cons cell and list.")
(insert (format fmt fn))
(goto-char (point-min))
(re-search-forward help-xref-symbol-regexp)
- (help-xref-button 8 'help-function)
+ (help-xref-button 9 'help-function)
(should-not (button-at (1- beg)))
(should-not (button-at (+ beg (length (symbol-name fn)))))
(should (eq (button-type (button-at beg)) 'help-function))))))
diff --git a/test/lisp/help-tests.el b/test/lisp/help-tests.el
index 3d4293cd380..5c935965f78 100644
--- a/test/lisp/help-tests.el
+++ b/test/lisp/help-tests.el
@@ -65,7 +65,7 @@
result))))
(test-re
(lambda (orig regexp)
- (should (string-match (concat "^" regexp "$")
+ (should (string-match (concat "\\`" regexp "\\'")
(substitute-command-keys orig))))))
,@body))
@@ -88,41 +88,87 @@
(test "\\[emacs-version]\\[next-line]" "M-x emacs-versionC-n")
(test-re "\\[emacs-version]`foo'" "M-x emacs-version[`'‘]foo['’]")))
-(ert-deftest help-tests-substitute-command-keys/keymaps ()
+(ert-deftest help-tests-substitute-command-keys/literal-key-sequence ()
+ "Literal replacement."
+ (with-substitute-command-keys-test
+ (test "\\`C-m'" "C-m")
+ (test "\\`C-m'\\`C-j'" "C-mC-j")
+ (test "foo\\`C-m'bar\\`C-j'baz" "fooC-mbarC-jbaz")))
+
+(ert-deftest help-tests-substitute-command-keys/literal-key-sequence-ignore-invalid ()
+ "Ignore any invalid literal key sequence."
(with-substitute-command-keys-test
- (test "\\{minibuffer-local-must-match-map}"
- "\
-key binding
---- -------
+ (test-re "ab\\`'cd" "ab\\\\[`'‘]['’]cd")
+ (test-re "\\`c-c'" "\\\\[`'‘]c-c['’]")
+ (test-re "\\`<foo bar baz>'" "\\\\[`'‘]<foo bar baz>['’]")))
+
+(ert-deftest help-tests-substitute-key-bindings/help-key-binding-face ()
+ (let ((A (substitute-command-keys "\\[next-line]"))
+ (B (substitute-command-keys "\\`f'")))
+ (should (eq (get-text-property 0 'face A) 'help-key-binding))
+ (should (eq (get-text-property 0 'face B) 'help-key-binding))))
+
+(ert-deftest help-tests-substitute-key-bindings/help-key-binding-no-face ()
+ (let ((A (substitute-command-keys "\\[next-line]" t))
+ (B (substitute-command-keys "\\`f'" t)))
+ (should (eq (get-text-property 0 'face A) nil))
+ (should (eq (get-text-property 0 'face B) nil))
+ (should (equal A "C-n"))
+ (should (equal B "f"))))
+
+(defvar-keymap help-tests--test-keymap
+ :doc "Just some keymap for testing."
+ "C-g" #'abort-minibuffers
+ "TAB" #'minibuffer-complete
+ "C-j" #'minibuffer-complete-and-exit
+ "RET" #'minibuffer-complete-and-exit
+ "SPC" #'minibuffer-complete-word
+ "?" #'minibuffer-completion-help
+ "C-<tab>" #'file-cache-minibuffer-complete
+ "<XF86Back>" #'previous-history-element
+ "<XF86Forward>" #'next-history-element
+ "<backtab>" #'minibuffer-complete
+ "<down>" #'next-line-or-history-element
+ "<next>" #'next-history-element
+ "<prior>" #'switch-to-completions
+ "<up>" #'previous-line-or-history-element
+ "M-v" #'switch-to-completions
+ "M-<" #'minibuffer-beginning-of-buffer
+ "M-n" #'next-history-element
+ "M-p" #'previous-history-element
+ "M-r" #'previous-matching-history-element
+ "M-s" #'next-matching-history-element
+ "M-g M-c" #'switch-to-completions)
+(ert-deftest help-tests-substitute-command-keys/keymaps ()
+ (with-substitute-command-keys-test
+ (test-re "\\{help-tests--test-keymap}"
+ "
+Key Binding
+-+
C-g abort-minibuffers
TAB minibuffer-complete
C-j minibuffer-complete-and-exit
RET minibuffer-complete-and-exit
-ESC Prefix Command
SPC minibuffer-complete-word
-? minibuffer-completion-help
+\\? minibuffer-completion-help
C-<tab> file-cache-minibuffer-complete
<XF86Back> previous-history-element
<XF86Forward> next-history-element
+<backtab> minibuffer-complete
<down> next-line-or-history-element
<next> next-history-element
<prior> switch-to-completions
<up> previous-line-or-history-element
-M-g Prefix Command
-M-v switch-to-completions
-
-M-g ESC Prefix Command
-
M-< minibuffer-beginning-of-buffer
M-n next-history-element
M-p previous-history-element
M-r previous-matching-history-element
M-s next-matching-history-element
+M-v switch-to-completions
M-g M-c switch-to-completions
-
")))
(ert-deftest help-tests-substitute-command-keys/keymap-change ()
@@ -130,12 +176,11 @@ M-g M-c switch-to-completions
(test "\\<minibuffer-local-must-match-map>\\[abort-recursive-edit]" "C-]")
(test "\\<emacs-lisp-mode-map>\\[eval-defun]" "C-M-x")))
-(defvar help-tests-remap-map
- (let ((map (make-keymap)))
- (define-key map (kbd "x") 'foo)
- (define-key map (kbd "y") 'bar)
- (define-key map [remap foo] 'bar)
- map))
+(defvar-keymap help-tests-remap-map
+ :full t
+ "x" 'foo
+ "y" 'bar
+ "<remap> <foo>" 'bar)
(ert-deftest help-tests-substitute-command-keys/remap ()
(should (equal (substitute-command-keys "\\<help-tests-remap-map>\\[foo]") "y"))
@@ -180,7 +225,7 @@ M-g M-c switch-to-completions
(let ((text-quoting-style 'grave))
(test "\\=`x\\='" "`x'"))))
-(ert-deftest help-tests-substitute-command-keys/no-change ()
+(ert-deftest help-tests-substitute-command-keys/no-change-2 ()
(with-substitute-command-keys-test
(test "\\[foobar" "\\[foobar")
(test "\\=" "\\=")))
@@ -199,30 +244,28 @@ M-g M-c switch-to-completions
(goto-char (point-min))
(should (looking-at "Type RET on"))))
-(defvar help-tests-major-mode-map
- (let ((map (make-keymap)))
- (define-key map "x" 'foo-original)
- (define-key map "1" 'foo-range)
- (define-key map "2" 'foo-range)
- (define-key map "3" 'foo-range)
- (define-key map "4" 'foo-range)
- (define-key map (kbd "C-e") 'foo-something)
- (define-key map '[F1] 'foo-function-key1)
- (define-key map "(" 'short-range)
- (define-key map ")" 'short-range)
- (define-key map "a" 'foo-other-range)
- (define-key map "b" 'foo-other-range)
- (define-key map "c" 'foo-other-range)
- map))
+(defvar-keymap help-tests-major-mode-map
+ :full t
+ "x" 'foo-original
+ "1" 'foo-range
+ "2" 'foo-range
+ "3" 'foo-range
+ "4" 'foo-range
+ "C-e" 'foo-something
+ "<f1>" 'foo-function-key1
+ "(" 'short-range
+ ")" 'short-range
+ "a" 'foo-other-range
+ "b" 'foo-other-range
+ "c" 'foo-other-range)
(define-derived-mode help-tests-major-mode nil
"Major mode for testing shadowing.")
-(defvar help-tests-minor-mode-map
- (let ((map (make-keymap)))
- (define-key map "x" 'foo-shadow)
- (define-key map (kbd "C-e") 'foo-shadow)
- map))
+(defvar-keymap help-tests-minor-mode-map
+ :full t
+ "x" 'foo-shadow
+ "C-e" 'foo-shadow)
(define-minor-mode help-tests-minor-mode
"Minor mode for testing shadowing.")
@@ -249,19 +292,17 @@ M-g M-c switch-to-completions
(with-substitute-command-keys-test
(with-temp-buffer
(help-tests-major-mode)
- (test "\\{help-tests-major-mode-map}"
- "\
-key binding
---- -------
-
-( .. ) short-range
+ (test-re "\\{help-tests-major-mode-map}"
+ "
+Key Binding
+-+
1 .. 4 foo-range
a .. c foo-other-range
C-e foo-something
+( .. ) short-range
x foo-original
<F1> foo-function-key1
-
"))))
(ert-deftest help-tests-substitute-command-keys/shadow ()
@@ -269,21 +310,19 @@ x foo-original
(with-temp-buffer
(help-tests-major-mode)
(help-tests-minor-mode)
- (test "\\{help-tests-major-mode-map}"
- "\
-key binding
---- -------
-
-( .. ) short-range
+ (test-re "\\{help-tests-major-mode-map}"
+ "
+Key Binding
+-+
1 .. 4 foo-range
a .. c foo-other-range
C-e foo-something
(this binding is currently shadowed)
+( .. ) short-range
x foo-original
(this binding is currently shadowed)
<F1> foo-function-key1
-
"))))
(ert-deftest help-tests-substitute-command-keys/command-remap ()
@@ -292,15 +331,11 @@ x foo-original
(with-temp-buffer
(help-tests-major-mode)
(define-key help-tests-major-mode-map [remap foo] 'bar)
- (test "\\{help-tests-major-mode-map}"
- "\
-key binding
---- -------
-
-<remap> Prefix Command
-
+ (test-re "\\{help-tests-major-mode-map}"
+ "
+Key Binding
+-+
<remap> <foo> bar
-
")))))
(ert-deftest help-tests-describe-map-tree/no-menu-t ()
@@ -312,12 +347,11 @@ key binding
:enable mark-active
:help "Help text"))))))
(describe-map-tree map nil nil nil nil t nil nil nil)
- (should (equal (buffer-string) "key binding
---- -------
-
-C-a foo
-
-")))))
+ (should (string-match "
+Key Binding
+-+
+C-a foo\n"
+ (buffer-string))))))
(ert-deftest help-tests-describe-map-tree/no-menu-nil ()
(with-temp-buffer
@@ -328,15 +362,13 @@ C-a foo
:enable mark-active
:help "Help text"))))))
(describe-map-tree map nil nil nil nil nil nil nil nil)
- (should (equal (buffer-string) "key binding
---- -------
-
+ (should (string-match "
+Key Binding
+-+
C-a foo
-<menu-bar> Prefix Command
-<menu-bar> <foo> foo
-
-")))))
+<menu-bar> <foo> foo\n"
+ (buffer-string))))))
(ert-deftest help-tests-describe-map-tree/mention-shadow-t ()
(with-temp-buffer
@@ -345,14 +377,13 @@ C-a foo
(2 . bar))))
(shadow-maps '((keymap . ((1 . baz))))))
(describe-map-tree map t shadow-maps nil nil t nil nil t)
- (should (equal (buffer-string) "key binding
---- -------
-
+ (should (string-match "
+Key Binding
+-+
C-a foo
(this binding is currently shadowed)
-C-b bar
-
-")))))
+C-b bar\n"
+ (buffer-string))))))
(ert-deftest help-tests-describe-map-tree/mention-shadow-nil ()
(with-temp-buffer
@@ -361,12 +392,11 @@ C-b bar
(2 . bar))))
(shadow-maps '((keymap . ((1 . baz))))))
(describe-map-tree map t shadow-maps nil nil t nil nil nil)
- (should (equal (buffer-string) "key binding
---- -------
-
-C-b bar
-
-")))))
+ (should (string-match "
+Key Binding
+-+
+C-b bar\n"
+ (buffer-string))))))
(ert-deftest help-tests-describe-map-tree/partial-t ()
(with-temp-buffer
@@ -374,12 +404,11 @@ C-b bar
(map '(keymap . ((1 . foo)
(2 . undefined)))))
(describe-map-tree map t nil nil nil nil nil nil nil)
- (should (equal (buffer-string) "key binding
---- -------
-
-C-a foo
-
-")))))
+ (should (string-match "
+Key Binding
+-+
+C-a foo\n"
+ (buffer-string))))))
(ert-deftest help-tests-describe-map-tree/partial-nil ()
(with-temp-buffer
@@ -387,13 +416,12 @@ C-a foo
(map '(keymap . ((1 . foo)
(2 . undefined)))))
(describe-map-tree map nil nil nil nil nil nil nil nil)
- (should (equal (buffer-string) "key binding
---- -------
-
+ (should (string-match "
+Key Binding
+-+
C-a foo
-C-b undefined
-
-")))))
+C-b undefined\n"
+ (buffer-string))))))
(defvar help-tests--was-in-buffer nil)
diff --git a/test/lisp/hi-lock-tests.el b/test/lisp/hi-lock-tests.el
index 71983c713d2..760b319a926 100644
--- a/test/lisp/hi-lock-tests.el
+++ b/test/lisp/hi-lock-tests.el
@@ -30,10 +30,9 @@
(let ((faces hi-lock-face-defaults))
(with-temp-buffer
(insert "a A b B\n")
- (cl-letf (((symbol-function 'completing-read)
- (lambda (_prompt _coll
- &optional _x _y _z _hist defaults _inherit)
- (car defaults))))
+ (cl-letf (((symbol-function 'read-face-name)
+ (lambda (_prompt &optional defaults)
+ (intern (car defaults)))))
(dotimes (_ 2)
(let ((face (hi-lock-read-face-name)))
(hi-lock-set-pattern "a" face))))
@@ -43,10 +42,9 @@
(let ((faces hi-lock-face-defaults))
(with-temp-buffer
(insert "foo bar")
- (cl-letf (((symbol-function 'completing-read)
- (lambda (_prompt _coll
- &optional _x _y _z _hist defaults _inherit)
- (car defaults))))
+ (cl-letf (((symbol-function 'read-face-name)
+ (lambda (_prompt &optional defaults)
+ (intern (car defaults)))))
(hi-lock-set-pattern "9999" (hi-lock-read-face-name)) ; No match
(hi-lock-set-pattern "foo" (hi-lock-read-face-name)))
;; Only one match, then we have used just 1 face
diff --git a/test/lisp/hl-line-tests.el b/test/lisp/hl-line-tests.el
new file mode 100644
index 00000000000..888351addac
--- /dev/null
+++ b/test/lisp/hl-line-tests.el
@@ -0,0 +1,114 @@
+;;; hl-line-tests.el --- Test suite for hl-line. -*- lexical-binding: t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Code:
+(require 'ert)
+(require 'hl-line)
+
+(defsubst hl-line-tests-verify (_label on-p)
+ (if on-p
+ (cl-some (apply-partially #'eq hl-line-overlay)
+ (overlays-at (point)))
+ (not (cl-some (apply-partially #'eq hl-line-overlay)
+ (overlays-at (point))))))
+
+(ert-deftest hl-line-tests-sticky-across-frames ()
+ (skip-unless (display-graphic-p))
+ (customize-set-variable 'global-hl-line-sticky-flag t)
+ (call-interactively #'global-hl-line-mode)
+ (let ((first-frame (selected-frame))
+ (first-buffer "foo")
+ (second-buffer "bar")
+ second-frame)
+ (unwind-protect
+ (progn
+ (switch-to-buffer first-buffer)
+ (save-excursion
+ (insert (buffer-name)))
+ (run-hooks 'post-command-hook)
+ (should (hl-line-tests-verify 111 t))
+ (select-frame (setq second-frame (make-frame)))
+ (switch-to-buffer second-buffer)
+ (save-excursion
+ (insert (buffer-name)))
+ (run-hooks 'post-command-hook)
+ (should (hl-line-tests-verify 762 t))
+ (with-current-buffer first-buffer
+ (should (hl-line-tests-verify 534 t)))
+ (call-interactively #'global-hl-line-mode)
+ (should (hl-line-tests-verify 125 nil))
+ (with-current-buffer first-buffer
+ (should (hl-line-tests-verify 892 nil)))
+
+ ;; now do unsticky
+ (customize-set-variable 'hl-line-sticky-flag nil)
+ (call-interactively #'global-hl-line-mode)
+ (run-hooks 'post-command-hook)
+ (should (hl-line-tests-verify 467 t))
+ (with-current-buffer first-buffer
+ (should (hl-line-tests-verify 765 nil)))
+ (select-frame first-frame)
+ (should (equal (buffer-name) first-buffer))
+ (run-hooks 'post-command-hook)
+ (should (hl-line-tests-verify 423 t))
+ (with-current-buffer second-buffer
+ (should (hl-line-tests-verify 897 nil))))
+ (let (kill-buffer-query-functions)
+ (ignore-errors (kill-buffer first-buffer))
+ (ignore-errors (kill-buffer second-buffer))
+ (ignore-errors (delete-frame second-frame))))))
+
+(ert-deftest hl-line-tests-sticky ()
+ (customize-set-variable 'hl-line-sticky-flag t)
+ (let ((first-buffer "foo")
+ (second-buffer "bar"))
+ (unwind-protect
+ (progn
+ (switch-to-buffer first-buffer)
+ (hl-line-mode 1)
+ (save-excursion
+ (insert (buffer-name)))
+ (run-hooks 'post-command-hook)
+ (should (hl-line-tests-verify 123 t))
+ (switch-to-buffer second-buffer)
+ (hl-line-mode 1)
+ (save-excursion
+ (insert (buffer-name)))
+ (run-hooks 'post-command-hook)
+ (should (hl-line-tests-verify 56 t))
+ (with-current-buffer first-buffer
+ (should (hl-line-tests-verify 67 t)))
+
+ ;; now do unsticky
+ (customize-set-variable 'hl-line-sticky-flag nil)
+ (should (hl-line-tests-verify 234 t))
+ (with-current-buffer first-buffer
+ (should (hl-line-tests-verify 231 nil)))
+ (switch-to-buffer first-buffer)
+ (run-hooks 'post-command-hook)
+ (should (hl-line-tests-verify 257 t))
+ (with-current-buffer second-buffer
+ (should (hl-line-tests-verify 999 nil)))))
+ (let (kill-buffer-query-functions)
+ (ignore-errors (kill-buffer first-buffer))
+ (ignore-errors (kill-buffer second-buffer)))))
+
+(provide 'hl-line-tests)
+
+;;; hl-line-tests.el ends here
diff --git a/test/lisp/htmlfontify-tests.el b/test/lisp/htmlfontify-tests.el
index fdfe996b033..5c1f053066b 100644
--- a/test/lisp/htmlfontify-tests.el
+++ b/test/lisp/htmlfontify-tests.el
@@ -21,15 +21,6 @@
(require 'ert)
(require 'htmlfontify)
-(ert-deftest htmlfontify-autoload ()
- "Tests to see whether reftex-auc has been autoloaded"
- (should
- (fboundp 'htmlfontify-load-rgb-file))
- (should
- (autoloadp
- (symbol-function
- 'htmlfontify-load-rgb-file))))
-
(ert-deftest htmlfontify-bug25468 ()
"Tests that htmlfontify can be loaded even if no shell is
available (Bug#25468)."
diff --git a/test/lisp/ibuffer-tests.el b/test/lisp/ibuffer-tests.el
index 252d2c5d7f7..343e2ae50b1 100644
--- a/test/lisp/ibuffer-tests.el
+++ b/test/lisp/ibuffer-tests.el
@@ -785,7 +785,7 @@
(funcall tag
(funcall description
'starred-name)
- ": " "nil"))
+ "" ""))
(funcall tag
(funcall description 'directory)
": " "\\<org\\>")))))
@@ -806,7 +806,7 @@
(funcall tag "AND"
(funcall tag
(funcall description 'starred-name)
- ": " "nil")
+ "" "")
(funcall tag
(funcall description 'name)
": " "elisp"))
diff --git a/test/lisp/image-dired-tests.el b/test/lisp/image-dired-tests.el
new file mode 100644
index 00000000000..00df72487fd
--- /dev/null
+++ b/test/lisp/image-dired-tests.el
@@ -0,0 +1,37 @@
+;;; image-dired-tests.el --- Tests for image-dired.el -*- lexical-binding: t -*-
+
+;; Copyright (C) 2021-2022 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'ert)
+(require 'image-dired)
+
+(defun image-dired-test-image-file (name)
+ (expand-file-name
+ name (expand-file-name "data/image"
+ (or (getenv "EMACS_TEST_DIRECTORY")
+ "../"))))
+
+(ert-deftest image-dired-tests-get-exif-file-name ()
+ (skip-unless (image-type-available-p 'jpeg))
+ (let ((img (image-dired-test-image-file "black.jpg")))
+ (should (equal (image-dired-get-exif-file-name img)
+ "2019_09_21_16_22_13_black.jpg"))))
+
+;;; image-dired-tests.el ends here
diff --git a/test/lisp/image-tests.el b/test/lisp/image-tests.el
index d1ce890d795..bc8c3636c3c 100644
--- a/test/lisp/image-tests.el
+++ b/test/lisp/image-tests.el
@@ -28,6 +28,27 @@
(expand-file-name "images" data-directory)
"Directory containing Emacs images.")
+(defconst image-tests--files
+ `((gif . ,(expand-file-name "test/data/image/black.gif"
+ source-directory))
+ (jpeg . ,(expand-file-name "test/data/image/black.jpg"
+ source-directory))
+ (pbm . ,(expand-file-name "splash.pbm"
+ image-tests--emacs-images-directory))
+ (png . ,(expand-file-name "splash.png"
+ image-tests--emacs-images-directory))
+ (svg . ,(expand-file-name "splash.svg"
+ image-tests--emacs-images-directory))
+ (tiff . ,(expand-file-name
+ "nextstep/GNUstep/Emacs.base/Resources/emacs.tiff"
+ source-directory))
+ (webp . ,(expand-file-name "test/data/image/black.webp"
+ source-directory))
+ (xbm . ,(expand-file-name "gnus/gnus.xbm"
+ image-tests--emacs-images-directory))
+ (xpm . ,(expand-file-name "splash.xpm"
+ image-tests--emacs-images-directory))))
+
(ert-deftest image--set-property ()
"Test `image--set-property' behavior."
(let ((image (list 'image)))
@@ -49,25 +70,67 @@
(should (equal image '(image)))))
(ert-deftest image-find-image ()
- (find-image '((:type xpm :file "undo.xpm")))
- (find-image '((:type png :file "newsticker/rss-feed.png" :ascent center))))
+ (should (listp (find-image '((:type xpm :file "undo.xpm")))))
+ (should (listp (find-image '((:type png :file "newsticker/rss-feed.png" :ascent center)))))
+ (should-not (find-image '((:type png :file "does-not-exist-foo-bar.png")))))
+
+(ert-deftest image-supported-file-p/built-in ()
+ ;; (skip-unless (image-type-available-p 'pbm)) ; Always built-in
+ (skip-unless (display-images-p)) ; (except in nox builds).
+ (should (eq (image-supported-file-p "foo.pbm") 'pbm)))
+
+(ert-deftest image-supported-file-p/optional ()
+ (if (image-type-available-p 'jpeg)
+ (should (eq (image-supported-file-p "foo.jpg") 'jpeg))
+ (should-not (image-supported-file-p "foo.jpg"))))
+
+(ert-deftest image-supported-file-p/unsupported-returns-nil ()
+ (should-not (image-supported-file-p "foo.some-unsupported-format")))
(ert-deftest image-type-from-file-name ()
- (should (eq (image-type-from-file-name "foo.jpg") 'jpeg))
- (should (eq (image-type-from-file-name "foo.png") 'png)))
+ (with-suppressed-warnings ((obsolete image-type-from-file-name))
+ (should (eq (image-type-from-file-name "foo.jpg") 'jpeg))
+ (should (eq (image-type-from-file-name "foo.png") 'png))
+ (should (eq (image-type-from-file-name "foo.webp") 'webp))))
(ert-deftest image-type/from-filename ()
;; On emba, `image-types' and `image-load-path' do not exist.
(skip-unless (and (bound-and-true-p image-types)
- (bound-and-true-p image-load-path)))
+ (bound-and-true-p image-load-path)
+ (image-type-available-p 'jpeg)))
(should (eq (image-type "foo.jpg") 'jpeg)))
-(ert-deftest image-type-from-file-header-test ()
+(defun image-tests--type-from-file-header (type)
"Test image-type-from-file-header."
- (should (eq (if (image-type-available-p 'svg) 'svg)
- (image-type-from-file-header
- (expand-file-name "splash.svg"
- image-tests--emacs-images-directory)))))
+ (should (eq (if (image-type-available-p type) type)
+ (image-type-from-file-header (cdr (assq type image-tests--files))))))
+
+(ert-deftest image-type-from-file-header-test/gif ()
+ (image-tests--type-from-file-header 'gif))
+
+(ert-deftest image-type-from-file-header-test/jpeg ()
+ (image-tests--type-from-file-header 'jpeg))
+
+(ert-deftest image-type-from-file-header-test/pbm ()
+ (image-tests--type-from-file-header 'pbm))
+
+(ert-deftest image-type-from-file-header-test/png ()
+ (image-tests--type-from-file-header 'png))
+
+(ert-deftest image-type-from-file-header-test/svg ()
+ (image-tests--type-from-file-header 'svg))
+
+(ert-deftest image-type-from-file-header-test/tiff ()
+ (image-tests--type-from-file-header 'tiff))
+
+(ert-deftest image-type-from-file-header-test/webp ()
+ (image-tests--type-from-file-header 'webp))
+
+(ert-deftest image-type-from-file-header-test/xbm ()
+ (image-tests--type-from-file-header 'xbm))
+
+(ert-deftest image-type-from-file-header-test/xpm ()
+ (image-tests--type-from-file-header 'xpm))
(ert-deftest image-rotate ()
"Test `image-rotate'."
diff --git a/test/lisp/image/exif-tests.el b/test/lisp/image/exif-tests.el
index 18a9b5a3de0..d62eef4798d 100644
--- a/test/lisp/image/exif-tests.el
+++ b/test/lisp/image/exif-tests.el
@@ -28,24 +28,19 @@
(or (getenv "EMACS_TEST_DIRECTORY")
"../../"))))
-(defun exif-elem (exif elem)
- (plist-get (seq-find (lambda (e)
- (eq elem (plist-get e :tag-name)))
- exif)
- :value))
-
(ert-deftest test-exif-parse ()
(let ((exif (exif-parse-file (test-image-file "black.jpg"))))
- (should (equal (exif-elem exif 'make) "Panasonic"))
- (should (equal (exif-elem exif 'orientation) 1))
- (should (equal (exif-elem exif 'x-resolution) '(180 . 1)))))
+ (should (equal (exif-field 'make exif) "Panasonic"))
+ (should (equal (exif-field 'orientation exif) 1))
+ (should (equal (exif-field 'x-resolution exif) '(180 . 1)))
+ (should (equal (exif-field 'date-time exif) "2019:09:21 16:22:13"))))
(ert-deftest test-exif-parse-short ()
(let ((exif (exif-parse-file (test-image-file "black-short.jpg"))))
- (should (equal (exif-elem exif 'make) "thr"))
- (should (equal (exif-elem exif 'model) "four"))
- (should (equal (exif-elem exif 'software) "em"))
- (should (equal (exif-elem exif 'artist) "z"))))
+ (should (equal (exif-field 'make exif) "thr"))
+ (should (equal (exif-field 'model exif) "four"))
+ (should (equal (exif-field 'software exif) "em"))
+ (should (equal (exif-field 'artist exif) "z"))))
(ert-deftest test-exit-direct-ascii-value ()
(should (equal (exif--direct-ascii-value 28005 2 t) (string ?e ?m 0)))
diff --git a/test/lisp/info-tests.el b/test/lisp/info-tests.el
new file mode 100644
index 00000000000..11ac25555de
--- /dev/null
+++ b/test/lisp/info-tests.el
@@ -0,0 +1,39 @@
+;;; info-tests.el --- Tests for info.el -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021-2022 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'info)
+(require 'ert)
+(require 'ert-x)
+
+(ert-deftest test-info-urls ()
+ (should (equal (Info-url-for-node "(emacs)Minibuffer")
+ "https://www.gnu.org/software/emacs/manual/html_node/emacs/Minibuffer.html"))
+ (should (equal (Info-url-for-node "(emacs)Minibuffer File")
+ "https://www.gnu.org/software/emacs/manual/html_node/emacs/Minibuffer-File.html"))
+ (should (equal (Info-url-for-node "(elisp)Backups and Auto-Saving")
+ "https://www.gnu.org/software/emacs/manual/html_node/elisp/Backups-and-Auto_002dSaving.html"))
+ (should-error (Info-url-for-node "(gnus)Minibuffer File")))
+
+;;; info-tests.el ends here
diff --git a/test/lisp/info-xref-tests.el b/test/lisp/info-xref-tests.el
index ba1ebac5dc7..acfd6e82f16 100644
--- a/test/lisp/info-xref-tests.el
+++ b/test/lisp/info-xref-tests.el
@@ -22,6 +22,7 @@
;;; Code:
(require 'ert)
+(require 'ert-x)
(require 'info-xref)
(defun info-xref-test-internal (body result)
@@ -96,15 +97,17 @@ text.
(ert-deftest info-xref-test-makeinfo ()
"Test that info-xref can parse basic makeinfo output."
(skip-unless (executable-find "makeinfo"))
- (let ((tempfile (make-temp-file "info-xref-test" nil ".texi"))
- (tempfile2 (make-temp-file "info-xref-test2" nil ".texi"))
- (errflag t))
- (unwind-protect
- (progn
- ;; tempfile contains xrefs to various things, including tempfile2.
- (info-xref-test-write-file
- tempfile
- (concat "\
+ (ert-with-temp-file tempfile
+ :suffix ".texi"
+ (ert-with-temp-file tempfile2
+ :suffix ".texi"
+ (let ((errflag t))
+ (unwind-protect
+ (progn
+ ;; tempfile contains xrefs to various things, including tempfile2.
+ (info-xref-test-write-file
+ tempfile
+ (concat "\
@xref{nodename,,,missing,Missing Manual}.
@xref{nodename,crossref,title,missing,Missing Manual}.
@@ -114,35 +117,36 @@ text.
@xref{Chapter One,Something}.
"
- (format "@xref{Chapter One,,,%s,Present Manual}.\n"
- (file-name-sans-extension (file-name-nondirectory
- tempfile2)))))
- ;; Something for tempfile to xref to.
- (info-xref-test-write-file tempfile2 "")
- (require 'info)
- (save-window-excursion
- (let ((Info-directory-list
- (list
- (or (file-name-directory tempfile) ".")))
- Info-additional-directory-list)
- (info-xref-check (format "%s.info" (file-name-sans-extension
- tempfile))))
- (should (equal (list info-xref-bad info-xref-good
- info-xref-unavail)
- '(0 1 2)))
- (setq errflag nil)
- ;; If there was an error, we can leave this around.
- (kill-buffer info-xref-output-buffer)))
- ;; Useful diagnostic in case of problems.
- (if errflag
- (with-temp-buffer
- (call-process "makeinfo" nil t nil "--version")
- (message "%s" (buffer-string))))
- (mapc 'delete-file (list tempfile tempfile2
- (format "%s.info" (file-name-sans-extension
- tempfile))
- (format "%s.info" (file-name-sans-extension
- tempfile2)))))))
+ (format "@xref{Chapter One,,,%s,Present Manual}.\n"
+ (file-name-sans-extension (file-name-nondirectory
+ tempfile2)))))
+ ;; Something for tempfile to xref to.
+ (info-xref-test-write-file tempfile2 "")
+ (require 'info)
+ (save-window-excursion
+ (let ((Info-directory-list
+ (list
+ (or (file-name-directory tempfile) ".")))
+ Info-additional-directory-list)
+ (info-xref-check (format "%s.info" (file-name-sans-extension
+ tempfile))))
+ (should (equal (list info-xref-bad info-xref-good
+ info-xref-unavail)
+ '(0 1 2)))
+ (setq errflag nil)
+ ;; If there was an error, we can leave this around.
+ (kill-buffer info-xref-output-buffer)))
+ ;; Useful diagnostic in case of problems.
+ (if errflag
+ (with-temp-buffer
+ (call-process "makeinfo" nil t nil "--version")
+ (message "%s" (buffer-string))))
+ (ignore-errors
+ (delete-file (format "%s.info" (file-name-sans-extension
+ tempfile))))
+ (ignore-errors
+ (delete-file (format "%s.info" (file-name-sans-extension
+ tempfile2)))))))))
(ert-deftest info-xref-test-emacs-manuals ()
"Test that all internal links in the Emacs manuals work."
diff --git a/test/lisp/international/textsec-tests.el b/test/lisp/international/textsec-tests.el
new file mode 100644
index 00000000000..6b0773dc407
--- /dev/null
+++ b/test/lisp/international/textsec-tests.el
@@ -0,0 +1,214 @@
+;;; textsec-tests.el --- Tests for textsec.el -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'textsec)
+(require 'ert)
+(require 'ert-x)
+
+(ert-deftest test-scripts ()
+ (should (equal (textsec-scripts "Circle")
+ '((latin) (latin) (latin) (latin) (latin) (latin))))
+ (should (textsec-single-script-p "Circle"))
+
+ (should (equal (textsec-scripts "СігсӀе")
+ '((cyrillic) (cyrillic) (cyrillic)
+ (cyrillic) (cyrillic) (cyrillic))))
+ (should (textsec-single-script-p "СігсӀе"))
+
+ (should (equal (textsec-scripts "Сirсlе")
+ '((cyrillic) (latin) (latin) (cyrillic) (latin) (cyrillic))))
+ (should-not (textsec-single-script-p "Сirсlе"))
+
+ (should (equal (textsec-scripts "Circ1e")
+ '((latin) (latin) (latin) (latin) (common) (latin))))
+ (should (textsec-single-script-p "Circ1e"))
+
+ (should (equal (textsec-scripts "C𝗂𝗋𝖼𝗅𝖾")
+ '((latin) (common) (common) (common) (common) (common))))
+ (should (textsec-single-script-p "C𝗂𝗋𝖼𝗅𝖾"))
+
+ (should (equal (textsec-scripts "𝖢𝗂𝗋𝖼𝗅𝖾")
+ '((common) (common) (common) (common) (common) (common))))
+ (should (textsec-single-script-p "𝖢𝗂𝗋𝖼𝗅𝖾"))
+
+ (should (equal (textsec-scripts "〆切")
+ '((common han) (han))))
+ (should (textsec-single-script-p "〆切"))
+
+ (should (equal (textsec-scripts "ねガ")
+ '((hiragana) (katakana))))
+ (should (textsec-single-script-p "ねガ")))
+
+(ert-deftest test-minimal-scripts ()
+ (should (equal (textsec-covering-scripts "Circle")
+ '(latin)))
+ (should (equal (textsec-covering-scripts "Сirсlе")
+ '(cyrillic latin)))
+ (should (equal (textsec-covering-scripts "〆切")
+ '(han))))
+
+(ert-deftest test-restriction-level ()
+ (should (eq (textsec-restriction-level "foo")
+ 'ascii-only))
+ (should (eq (textsec-restriction-level "C𝗂𝗋𝖼𝗅𝖾")
+ 'single-script))
+ (should (eq (textsec-restriction-level "切foo")
+ 'highly-restrictive))
+ (should (eq (textsec-restriction-level "հfoo")
+ 'moderately-retrictive))
+ (should (eq (textsec-restriction-level "Сirсlе")
+ 'unrestricted)))
+
+(ert-deftest test-mixed-numbers ()
+ (should-not (textsec-mixed-numbers-p "foo"))
+ (should-not (textsec-mixed-numbers-p "8foo8"))
+ (should-not (textsec-mixed-numbers-p "foo20@foo.org"))
+ (should (textsec-mixed-numbers-p "8foo৪")))
+
+(ert-deftest test-resolved ()
+ (should (equal (textsec-resolved-script-set "ljeto")
+ '(latin)))
+ (should-not (textsec-resolved-script-set "Сirсlе")))
+
+(ert-deftest test-confusable ()
+ (should (equal (textsec-unconfuse-string "ljeto") "ljeto"))
+ (should (textsec-ascii-confusable-p "ljeto"))
+ (should-not (textsec-ascii-confusable-p "ljeto"))
+ (should (equal (textsec-unconfuse-string "~") "〜"))
+ (should-not (textsec-ascii-confusable-p "~"))
+
+ (should (textsec-single-script-confusable-p "ljeto" "ljeto"))
+ (should-not (textsec-single-script-confusable-p "paypal" "pаypаl"))
+ (should-not (textsec-single-script-confusable-p "scope""ѕсоре"))
+
+ (should-not (textsec-mixed-script-confusable-p "ljeto" "ljeto"))
+ (should (textsec-mixed-script-confusable-p "paypal" "pаypаl"))
+ (should (textsec-mixed-script-confusable-p "scope""ѕсоре"))
+
+ (should-not (textsec-whole-script-confusable-p "ljeto" "ljeto"))
+ (should-not (textsec-whole-script-confusable-p "paypal" "pаypаl"))
+ (should (textsec-whole-script-confusable-p "scope""ѕсоре")))
+
+(ert-deftest test-suspiction-domain ()
+ (should (textsec-domain-suspicious-p "foo/bar.org"))
+ (should-not (textsec-domain-suspicious-p "foo.org"))
+ (should (textsec-domain-suspicious-p "f\N{LEFT-TO-RIGHT ISOLATE}oo.org"))
+
+ (should (textsec-domain-suspicious-p "Сгсе.ru"))
+ (should-not (textsec-domain-suspicious-p "фСгсе.ru"))
+
+ (should-not (textsec-domain-suspicious-p
+ "21a:34aa:c782:3ad2:1bf8:73f8:141:66e8"))
+ (should (textsec-domain-suspicious-p
+ "21a:34aa:c782:3ad2:1bf8:73f8:141:66e8:66e8"))
+ (should-not (textsec-domain-suspicious-p
+ "[21a:34aa:c782:3ad2:1bf8:73f8:141:66e8]"))
+ (should (textsec-domain-suspicious-p
+ "[21a:34aa:c782:3ad2:1bf8:73f8:141:66e8"))
+ (should-not (textsec-domain-suspicious-p "138.25.106.12"))
+ (should-not (textsec-domain-suspicious-p "2001:db8::ff00:42:8329"))
+ (should-not (textsec-domain-suspicious-p "::ffff:129.55.2.201")))
+
+(ert-deftest test-suspicious-local ()
+ (should-not (textsec-local-address-suspicious-p "larsi"))
+ (should (textsec-local-address-suspicious-p ".larsi"))
+ (should (textsec-local-address-suspicious-p "larsi."))
+ (should-not (textsec-local-address-suspicious-p "la.rsi"))
+ (should (textsec-local-address-suspicious-p "lar..si"))
+
+ (should-not (textsec-local-address-suspicious-p "LÅRSI"))
+ (should (textsec-local-address-suspicious-p "LÅRSI"))
+
+ (should (textsec-local-address-suspicious-p "larsi8৪")))
+
+(ert-deftest test-suspicious-name ()
+ (should-not (textsec-name-suspicious-p "Lars Ingebrigtsen"))
+ (should (textsec-name-suspicious-p "LÅRS INGEBRIGTSEN"))
+ (should-not (textsec-name-suspicious-p "LÅRS INGEBRIGTSEN"))
+
+ (should (textsec-name-suspicious-p
+ "Lars Ingebrigtsen\N{LEFT-TO-RIGHT OVERRIDE}"))
+ (should (textsec-name-suspicious-p
+ "Lars Ingebrigtsen\N{LEFT-TO-RIGHT OVERRIDE}f"))
+ (should-not (textsec-name-suspicious-p
+ "Lars Ingebrigtsen\N{LEFT-TO-RIGHT MARK}"))
+ (should-not (textsec-name-suspicious-p "אבגד ⁧שונה⁩ מרגיל"))
+
+ (should (textsec-name-suspicious-p
+ "\N{COMBINING GRAVE ACCENT}\N{COMBINING GRAVE ACCENT}Lars Ingebrigtsen"))
+ (should-not (textsec-name-suspicious-p
+ "\N{COMBINING GRAVE ACCENT}\N{COMBINING ENCLOSING CIRCLE}Lars Ingebrigtsen"))
+ (should (textsec-name-suspicious-p
+ "\N{COMBINING GRAVE ACCENT}\N{COMBINING ENCLOSING CIRCLE}\N{COMBINING GRAVE ACCENT}\N{COMBINING ENCLOSING CIRCLE}\N{COMBINING GRAVE ACCENT}Lars Ingebrigtsen")))
+
+(ert-deftest test-suspicious-email ()
+ (should-not
+ (textsec-email-address-header-suspicious-p
+ "Lars Ingebrigtsen <larsi@gnus.org>"))
+ (should
+ (textsec-email-address-header-suspicious-p
+ "LÅrs Ingebrigtsen <larsi@gnus.org>"))
+ (should
+ (textsec-email-address-header-suspicious-p
+ "Lars Ingebrigtsen <.larsi@gnus.org>"))
+ (should
+ (textsec-email-address-header-suspicious-p
+ "Lars Ingebrigtsen <larsi@gn\N{LEFT-TO-RIGHT ISOLATE}us.org>"))
+
+ (should
+ (textsec-email-address-header-suspicious-p
+ "Lars Ingebrigtsen <larsi@\N{RIGHT-TO-LEFT OVERRIDE}gnus.org>"))
+
+ (should-not (textsec-email-address-header-suspicious-p
+ "דגבא <foo@bar.com>"))
+
+ (should (textsec-email-address-suspicious-p
+ "Bob_Norbolwits@GCSsafetyACE.com​")))
+
+(ert-deftest test-suspicious-url ()
+ (should-not (textsec-url-suspicious-p "http://example.ru/bar"))
+ (should (textsec-url-suspicious-p "http://Сгсе.ru/bar")))
+
+(ert-deftest test-suspicious-link ()
+ (should-not (textsec-link-suspicious-p
+ (cons "https://gnu.org/" "Hello")))
+ (should-not (textsec-link-suspicious-p
+ (cons "https://gnu.org/" "https://gnu.org/")))
+ (should-not (textsec-link-suspicious-p
+ (cons "https://gnu.org/" "https://www.gnu.org/")))
+ (should-not (textsec-link-suspicious-p
+ (cons "https://www.gnu.org/" "https://gnu.org/")))
+ (should (textsec-link-suspicious-p
+ (cons "https://www.gnu.org/" "https://org/")))
+ (should (textsec-link-suspicious-p
+ (cons "https://www.gnu.org/" "https://fsf.org/")))
+ (should (textsec-link-suspicious-p
+ (cons "https://www.gnu.org/" "http://fsf.org/")))
+
+ (should (textsec-link-suspicious-p
+ (cons "https://www.gn\N{LEFT-TO-RIGHT ISOLATE}u.org/"
+ "https://gn\N{LEFT-TO-RIGHT ISOLATE}u.org"))))
+
+;;; textsec-tests.el ends here
diff --git a/test/lisp/isearch-tests.el b/test/lisp/isearch-tests.el
index 4600757d940..8cb5e5e4542 100644
--- a/test/lisp/isearch-tests.el
+++ b/test/lisp/isearch-tests.el
@@ -38,5 +38,85 @@
;; Bug #21091: let `isearch-done' work without `isearch-update'.
(isearch-done))
+
+;; Search functions.
+
+(defun isearch--test-search-within-boundaries (pairs)
+ (goto-char (point-min))
+ (let ((isearch-forward t)
+ (isearch-regexp nil))
+ (dolist (pos (append pairs nil))
+ (should (eq (cdr pos) (isearch-search-string "foo" nil t)))
+ (should (equal (match-string 0) "foo"))
+ (when (car pos) (should (eq (car pos) (match-beginning 0))))))
+
+ (goto-char (point-max))
+ (let ((isearch-forward nil)
+ (isearch-regexp nil))
+ (dolist (pos (append (reverse pairs) nil))
+ (should (eq (car pos) (isearch-search-string "foo" nil t)))
+ (should (equal (match-string 0) "foo"))
+ (when (cdr pos) (should (eq (cdr pos) (match-end 0))))))
+
+ (goto-char (point-min))
+ (let ((isearch-forward t)
+ (isearch-regexp t))
+ (dolist (pos (append pairs nil))
+ (should (eq (cdr pos) (isearch-search-string ".*" nil t)))
+ (should (equal (match-string 0) "foo"))
+ (when (car pos) (should (eq (car pos) (match-beginning 0))))))
+
+ (goto-char (point-min))
+ (let ((isearch-forward t)
+ (isearch-regexp t))
+ (dolist (pos (append pairs nil))
+ (should (eq (cdr pos) (isearch-search-string "^.*" nil t)))
+ (should (equal (match-string 0) "foo"))
+ (when (car pos) (should (eq (car pos) (match-beginning 0))))))
+
+ (goto-char (point-min))
+ (let ((isearch-forward t)
+ (isearch-regexp t))
+ (dolist (pos (append pairs nil))
+ (should (eq (cdr pos) (isearch-search-string ".*$" nil t)))
+ (should (equal (match-string 0) "foo"))
+ (when (car pos) (should (eq (car pos) (match-beginning 0))))))
+
+ (goto-char (point-max))
+ (let ((isearch-forward nil)
+ (isearch-regexp t))
+ (dolist (pos (append (reverse pairs) nil))
+ (should (eq (car pos) (isearch-search-string "^.*" nil t)))
+ (should (equal (match-string 0) "foo"))
+ (when (cdr pos) (should (eq (cdr pos) (match-end 0))))))
+
+ (goto-char (point-max))
+ (let ((isearch-forward nil)
+ (isearch-regexp t))
+ (dolist (pos (append (reverse pairs) nil))
+ (should (eq (car pos) (isearch-search-string "foo$" nil t)))
+ (should (equal (match-string 0) "foo"))
+ (when (cdr pos) (should (eq (cdr pos) (match-end 0)))))))
+
+(ert-deftest isearch--test-search-fun-in-text-property ()
+ (let* ((pairs '((4 . 7) (11 . 14) (21 . 24)))
+ (isearch-search-fun-function
+ (lambda () (isearch-search-fun-in-text-property nil 'dired-filename))))
+ (with-temp-buffer
+ (insert "foo" (propertize "foo" 'dired-filename t) "foo\n")
+ (insert (propertize "foo" 'dired-filename t) "foo\n")
+ (insert "foo" (propertize "foo" 'dired-filename t) "\n")
+ (isearch--test-search-within-boundaries pairs))))
+
+(ert-deftest isearch--test-search-fun-in-noncontiguous-region ()
+ (let* ((pairs '((4 . 7) (11 . 14) (21 . 24)))
+ (isearch-search-fun-function
+ (lambda () (isearch-search-fun-in-noncontiguous-region nil pairs))))
+ (with-temp-buffer
+ (insert "foofoofoo\n")
+ (insert "foofoo\n")
+ (insert "foofoo\n")
+ (isearch--test-search-within-boundaries pairs))))
+
(provide 'isearch-tests)
;;; isearch-tests.el ends here
diff --git a/test/lisp/json-tests.el b/test/lisp/json-tests.el
index ef7805a3416..ab1f19fb6e7 100644
--- a/test/lisp/json-tests.el
+++ b/test/lisp/json-tests.el
@@ -510,8 +510,8 @@ Point is moved to beginning of the buffer."
(let ((json-key-type 'string))
(setq obj (json-add-to-object obj "g" 7))
(setq obj (json-add-to-object obj "h" 8))
- (should (= (lax-plist-get obj "g") 7))
- (should (= (lax-plist-get obj "h") 8)))))
+ (should (= (plist-get obj "g" #'equal) 7))
+ (should (= (plist-get obj "h" #'equal) 8)))))
(ert-deftest test-json-add-to-hash-table ()
(let* ((json-object-type 'hash-table)
diff --git a/test/lisp/kmacro-tests.el b/test/lisp/kmacro-tests.el
index e1eabeb9591..75d700070aa 100644
--- a/test/lisp/kmacro-tests.el
+++ b/test/lisp/kmacro-tests.el
@@ -91,33 +91,30 @@ body in KEYS-AND-BODY."
,docstring ,@keys
(kmacro-tests-with-kmacro-clean-slate ,@body))))
-(defvar kmacro-tests-keymap
- (let ((map (make-sparse-keymap)))
- (dotimes (i 26)
- (define-key map (string (+ ?a i)) 'self-insert-command))
- (dotimes (i 10)
- (define-key map (string (+ ?0 i)) 'self-insert-command))
- ;; Define a few key sequences of different lengths.
- (dolist (item '(("\C-a" . beginning-of-line)
- ("\C-b" . backward-char)
- ("\C-e" . end-of-line)
- ("\C-f" . forward-char)
- ("\C-r" . isearch-backward)
- ("\C-u" . universal-argument)
- ("\C-w" . kill-region)
- ("\C-SPC" . set-mark-command)
- ("\M-w" . kill-ring-save)
- ("\M-x" . execute-extended-command)
- ("\C-cd" . downcase-word)
- ("\C-cxu" . upcase-word)
- ("\C-cxq" . quoted-insert)
- ("\C-cxi" . kmacro-insert-counter)
- ("\C-x\C-k" . kmacro-keymap)))
- (define-key map (car item) (cdr item)))
- map)
- "Keymap to use for testing keyboard macros.
+(defvar-keymap kmacro-tests-keymap
+ :doc "Keymap to use for testing keyboard macros.
This is used to obtain consistent results even if tests are run
-in an environment with rebound keys.")
+in an environment with rebound keys."
+ ;; Define a few key sequences of different lengths.
+ "C-a" 'beginning-of-line
+ "C-b" 'backward-char
+ "C-e" 'end-of-line
+ "C-f" 'forward-char
+ "C-r" 'isearch-backward
+ "C-u" 'universal-argument
+ "C-w" 'kill-region
+ "C-SPC" 'set-mark-command
+ "M-w" 'kill-ring-save
+ "M-x" 'execute-extended-command
+ "C-c d" 'downcase-word
+ "C-c x u" 'upcase-word
+ "C-c x q" 'quoted-insert
+ "C-c x i" 'kmacro-insert-counter
+ "C-x C-k" 'kmacro-keymap)
+(dotimes (i 26)
+ (keymap-set kmacro-tests-keymap (string (+ ?a i)) 'self-insert-command))
+(dotimes (i 10)
+ (keymap-set kmacro-tests-keymap (string (+ ?0 i)) 'self-insert-command))
(defvar kmacro-tests-events nil
"Input events used by the kmacro test in progress.")
@@ -583,8 +580,10 @@ This is a regression test for: Bug#3412, Bug#11817."
;; Check the bound key and run it and verify correct counter
;; and format.
(should (equal (string-to-vector "\C-cxi")
- (car (kmacro-extract-lambda
- (key-binding "\C-x\C-kA")))))
+ (car (with-suppressed-warnings
+ ((obsolete kmacro-extract-lambda))
+ (kmacro-extract-lambda
+ (key-binding "\C-x\C-kA"))))))
(kmacro-tests-should-insert "<5>"
(funcall (key-binding "\C-x\C-kA")))))
@@ -608,7 +607,7 @@ This is a regression test for: Bug#3412, Bug#11817."
(dotimes (i 2)
(kmacro-tests-define-macro (make-vector (1+ i) (+ ?a i)))
(kmacro-name-last-macro 'kmacro-tests-symbol-for-test)
- (should (fboundp 'kmacro-tests-symbol-for-test)))
+ (should (commandp 'kmacro-tests-symbol-for-test)))
;; Now run the function bound to the symbol. Result should be the
;; second macro.
@@ -825,6 +824,15 @@ This is a regression for item 7 in Bug#24991."
:macro-result "x")
(kmacro-tests-simulate-command '(beginning-of-line))))
+(ert-deftest kmacro-tests--cl-print ()
+ (should (equal (cl-prin1-to-string
+ (kmacro [?a ?b backspace backspace]))
+ "#f(kmacro \"a b <backspace> <backspace>\")"))
+ (should (equal (cl-prin1-to-string
+ (with-suppressed-warnings ((obsolete kmacro-lambda-form))
+ (kmacro-lambda-form [?a ?b backspace backspace] 1 "%d")))
+ "#f(kmacro \"a b <backspace> <backspace>\" 1 \"%d\")")))
+
(cl-defun kmacro-tests-run-step-edit
(macro &key events sequences result macro-result)
"Set up and run a test of `kmacro-step-edit-macro'.
diff --git a/test/lisp/loadhist-resources/loadhist--bar.el b/test/lisp/loadhist-resources/loadhist--bar.el
new file mode 100644
index 00000000000..5c8914ed573
--- /dev/null
+++ b/test/lisp/loadhist-resources/loadhist--bar.el
@@ -0,0 +1,27 @@
+;;; loadhist--bar.el --- Dummy package for loadhist-tests -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+
+;; Author: Stefan Monnier <monnier@iro.umontreal.ca>
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(autoload 'loadhist--foo-inc "loadhist--foo")
+
+(defun loadhist--bar-dec (x) (1- x))
+
+(provide 'loadhist--bar)
+;;; loadhist--bar.el ends here
diff --git a/test/lisp/loadhist-resources/loadhist--foo.el b/test/lisp/loadhist-resources/loadhist--foo.el
new file mode 100644
index 00000000000..3574c220135
--- /dev/null
+++ b/test/lisp/loadhist-resources/loadhist--foo.el
@@ -0,0 +1,29 @@
+;;; loadhist--foo.el --- Dummy package for loadhist-tests -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+
+;; Author: Stefan Monnier <monnier@iro.umontreal.ca>
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;; Code:
+
+(autoload 'loadhist--bar-dec "loadhist--bar")
+
+(defun loadhist--foo-inc (x) (1+ x))
+
+(provide 'loadhist--foo)
+;;; loadhist--foo.el ends here
diff --git a/test/lisp/loadhist-tests.el b/test/lisp/loadhist-tests.el
index a941ac06320..ef5fc164d34 100644
--- a/test/lisp/loadhist-tests.el
+++ b/test/lisp/loadhist-tests.el
@@ -54,4 +54,51 @@
(should-error (unload-feature 'dired))
(unload-feature 'dired-x))
+(defvar loadhist--tests-dir (file-name-directory (macroexp-file-name)))
+
+(ert-deftest loadhist-tests-unload-feature-nested ()
+ (add-to-list 'load-path (expand-file-name
+ "loadhist-resources/"
+ loadhist--tests-dir))
+ (declare-function loadhist--foo-inc "loadhist--foo")
+ (declare-function loadhist--bar-dec "loadhist--dec")
+ (load "loadhist--foo" nil t)
+ (should (and (functionp 'loadhist--bar-dec) (functionp 'loadhist--foo-inc)))
+ (should (autoloadp (symbol-function 'loadhist--bar-dec)))
+ (load "loadhist--bar" nil t)
+ (should (and (functionp 'loadhist--bar-dec) (functionp 'loadhist--foo-inc)))
+ (should (not (autoloadp (symbol-function 'loadhist--bar-dec))))
+ (should (not (autoloadp (symbol-function 'loadhist--foo-inc))))
+ (should (equal (list 40 42)
+ (list (loadhist--bar-dec 41) (loadhist--foo-inc 41))))
+ (unload-feature 'loadhist--bar)
+ (should (and (functionp 'loadhist--bar-dec) (functionp 'loadhist--foo-inc)))
+ (should (autoloadp (symbol-function 'loadhist--bar-dec)))
+ (should (not (autoloadp (symbol-function 'loadhist--foo-inc))))
+ (unload-feature 'loadhist--foo)
+ (should (null (symbol-function 'loadhist--bar-dec)))
+ (should (null (symbol-function 'loadhist--foo-inc)))
+ (should (null (get 'loadhist--bar-dec 'function-history)))
+ (should (null (get 'loadhist--foo-inc 'function-history))))
+
+(ert-deftest loadhist-tests-unload-feature-notnested ()
+ (add-to-list 'load-path (expand-file-name
+ "loadhist-resources/"
+ loadhist--tests-dir))
+ (load "loadhist--foo" nil t)
+ (load "loadhist--bar" nil t)
+ (should (equal (list 40 42)
+ (list (loadhist--bar-dec 41) (loadhist--foo-inc 41))))
+ (unload-feature 'loadhist--foo)
+ (should (functionp 'loadhist--bar-dec))
+ (should (not (autoloadp (symbol-function 'loadhist--bar-dec))))
+ (should (let ((f (symbol-function 'loadhist--foo-inc)))
+ ;; Both choices seem acceptable.
+ (or (null f) (autoloadp f))))
+ (unload-feature 'loadhist--bar)
+ (should (null (symbol-function 'loadhist--bar-dec)))
+ (should (null (symbol-function 'loadhist--foo-inc)))
+ (should (null (get 'loadhist--bar-dec 'function-history)))
+ (should (null (get 'loadhist--foo-inc 'function-history))))
+
;;; loadhist-tests.el ends here
diff --git a/test/lisp/ls-lisp-tests.el b/test/lisp/ls-lisp-tests.el
index 2cfd3576a94..39843defc2e 100644
--- a/test/lisp/ls-lisp-tests.el
+++ b/test/lisp/ls-lisp-tests.el
@@ -25,6 +25,7 @@
;;; Code:
(require 'ert)
+(require 'ert-x)
(require 'ls-lisp)
(require 'dired)
@@ -53,28 +54,29 @@
(kill-buffer buf)
(setq buf (dired (nconc (list dir) files)))
(should (looking-at "src"))
- (next-line) ; File names must be aligned.
+ (with-suppressed-warnings ((interactive-only next-line))
+ (next-line)) ; File names must be aligned.
(should (looking-at "src")))
(when (buffer-live-p buf) (kill-buffer buf)))))
(ert-deftest ls-lisp-test-bug27631 ()
"Test for https://debbugs.gnu.org/27631 ."
- (let* ((dir (make-temp-file "bug27631" 'dir))
- (dir1 (expand-file-name "dir1" dir))
- (dir2 (expand-file-name "dir2" dir))
- (default-directory dir)
- ls-lisp-use-insert-directory-program buf)
- (unwind-protect
- (progn
- (make-directory dir1)
- (make-directory dir2)
- (with-temp-file (expand-file-name "a.txt" dir1))
- (with-temp-file (expand-file-name "b.txt" dir2))
- (setq buf (dired (expand-file-name "dir*/*.txt" dir)))
- (dired-toggle-marks)
- (should (cdr (dired-get-marked-files))))
- (delete-directory dir 'recursive)
- (when (buffer-live-p buf) (kill-buffer buf)))))
+ (ert-with-temp-directory dir
+ :suffix "bug27631"
+ (let* ((dir1 (expand-file-name "dir1" dir))
+ (dir2 (expand-file-name "dir2" dir))
+ (default-directory dir)
+ ls-lisp-use-insert-directory-program buf)
+ (unwind-protect
+ (progn
+ (make-directory dir1)
+ (make-directory dir2)
+ (with-temp-file (expand-file-name "a.txt" dir1))
+ (with-temp-file (expand-file-name "b.txt" dir2))
+ (setq buf (dired (expand-file-name "dir*/*.txt" dir)))
+ (dired-toggle-marks)
+ (should (cdr (dired-get-marked-files))))
+ (when (buffer-live-p buf) (kill-buffer buf))))))
(ert-deftest ls-lisp-test-bug27693 ()
"Test for https://debbugs.gnu.org/27693 ."
@@ -91,5 +93,44 @@
(should (looking-back "[[:space:]]" (1- (point)))))
(when (buffer-live-p buf) (kill-buffer buf)))))
+(ert-deftest ls-lisp-test-bug55787 ()
+ "Test proper sorting by version."
+ (let ((files1 (vector "34 klmn-300dpi.jpg"
+ "34 klmn-300dpi.png"
+ "054_xyz.jpg"
+ "054_xyz.png"
+ "91 opqrs.jpg"
+ "91 opqrs.png"
+ "0717-abcd.jpg"
+ "0717-abcd.png"
+ "1935 uv.jpg"
+ "1935 uv.png"
+ "FFFF_fghk.jpg"
+ "FFFF_fghk.png"
+ "hhhh.jpg"
+ "hhhh.png"))
+ (files2 (vector "01.0" "10" "010" "01.2")))
+ (should (equal (sort files1
+ (lambda (x y)
+ (ls-lisp-version-lessp x y)))
+ '["0717-abcd.jpg"
+ "0717-abcd.png"
+ "054_xyz.jpg"
+ "054_xyz.png"
+ "34 klmn-300dpi.jpg"
+ "34 klmn-300dpi.png"
+ "91 opqrs.jpg"
+ "91 opqrs.png"
+ "1935 uv.jpg"
+ "1935 uv.png"
+ "FFFF_fghk.jpg"
+ "FFFF_fghk.png"
+ "hhhh.jpg"
+ "hhhh.png"]))
+ (should (equal (sort files2
+ (lambda (x y)
+ (ls-lisp-version-lessp x y)))
+ '["01.0" "01.2" "010" "10"]))))
+
(provide 'ls-lisp-tests)
;;; ls-lisp-tests.el ends here
diff --git a/test/lisp/mail/ietf-drums-date-tests.el b/test/lisp/mail/ietf-drums-date-tests.el
new file mode 100644
index 00000000000..781d72d3529
--- /dev/null
+++ b/test/lisp/mail/ietf-drums-date-tests.el
@@ -0,0 +1,172 @@
+;;; ietf-drums-date-tests.el --- Test suite for ietf-drums-date.el -*- lexical-binding:t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+
+;; Author: Bob Rogers <rogers@rgrjr.com>
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'ert)
+(require 'ietf-drums)
+(require 'ietf-drums-date)
+
+(ert-deftest ietf-drums-date-tests ()
+ "Test basic ietf-drums-parse-date-string functionality."
+
+ ;; Test tokenization.
+ (should (equal (ietf-drums-date--tokenize-string " ") '()))
+ (should (equal (ietf-drums-date--tokenize-string " a b") '("a" "b")))
+ (should (equal (ietf-drums-date--tokenize-string "a bbc dde")
+ '("a" "bbc" "dde")))
+ (should (equal (ietf-drums-date--tokenize-string " , a 27 b,, c 14:32 ")
+ '("a" 27 "b" "c" "14:32")))
+ ;; Some folding whitespace tests.
+ (should (equal (ietf-drums-date--tokenize-string " a b (end) c" t)
+ '("a" "b")))
+ (should (equal (ietf-drums-date--tokenize-string "(quux)a (foo (bar)) b(baz)")
+ '("a" "b")))
+ (should (equal (ietf-drums-date--tokenize-string "a b\\cde")
+ ;; Strictly incorrect, but strictly unnecessary syntax.
+ '("a" "b\\cde")))
+ (should (equal (ietf-drums-date--tokenize-string "a b\\ de")
+ '("a" "b\\ de")))
+ (should (equal (ietf-drums-date--tokenize-string "a \\de \\(f")
+ '("a" "\\de" "\\(f")))
+
+ ;; Start with some compatible RFC822 dates.
+ (dolist (case '(("Mon, 22 Feb 2016 19:35:42 +0100"
+ (42 35 19 22 2 2016 1 -1 3600))
+ ("22 Feb 2016 19:35:42 +0100"
+ (42 35 19 22 2 2016 nil -1 3600))
+ ("Mon, 22 February 2016 19:35:42 +0100"
+ (42 35 19 22 2 2016 1 -1 3600))
+ ("Mon, 22 feb 2016 19:35:42 +0100"
+ (42 35 19 22 2 2016 1 -1 3600))
+ ("Monday, 22 february 2016 19:35:42 +0100"
+ (42 35 19 22 2 2016 1 -1 3600))
+ ("Monday, 22 february 2016 19:35:42 PST"
+ (42 35 19 22 2 2016 1 nil -28800))
+ ("Friday, 21 Sep 2018 13:47:58 PDT"
+ (58 47 13 21 9 2018 5 t -25200))
+ ("Friday, 21 Sep 2018 13:47:58 EDT"
+ (58 47 13 21 9 2018 5 t -14400))
+ ("Mon, 22 Feb 2016 19:35:42"
+ (42 35 19 22 2 2016 1 -1 nil))
+ ("Friday, 21 Sep 2018 13:47:58"
+ (58 47 13 21 9 2018 5 -1 nil))))
+ (let* ((input (car case))
+ (parsed (cadr case)))
+ ;; The input should parse the same without RFC822.
+ (should (equal (ietf-drums-parse-date-string input) parsed))
+ (should (equal (ietf-drums-parse-date-string input nil t) parsed))
+ ;; Check the encoded date (the official output, though the
+ ;; decoded-time is easier to debug).
+ (should (time-equal-p (ietf-drums-parse-date input)
+ (encode-time parsed)))))
+
+ ;; Two-digit years are not allowed by the "modern" format.
+ (should (equal (ietf-drums-parse-date-string "22 Feb 16 19:35:42 +0100")
+ '(42 35 19 22 2 2016 nil -1 3600)))
+ (should (equal (ietf-drums-parse-date-string "22 Feb 16 19:35:42 +0100" nil t)
+ '(nil nil nil 22 2 nil nil -1 nil)))
+ (should (equal (should-error (ietf-drums-parse-date-string
+ "22 Feb 16 19:35:42 +0100" t t))
+ '(date-parse-error "Four-digit years are required" 16)))
+ (should (equal (ietf-drums-parse-date-string "22 Feb 96 19:35:42 +0100")
+ '(42 35 19 22 2 1996 nil -1 3600)))
+ (should (equal (ietf-drums-parse-date-string "22 Feb 96 19:35:42 +0100" nil t)
+ '(nil nil nil 22 2 nil nil -1 nil)))
+ (should (equal (should-error (ietf-drums-parse-date-string
+ "22 Feb 96 19:35:42 +0100" t t))
+ '(date-parse-error "Four-digit years are required" 96)))
+
+ ;; Try some dates with comments.
+ (should (equal (ietf-drums-parse-date-string
+ "22 Feb (today) 16 19:35:42 +0100")
+ '(42 35 19 22 2 2016 nil -1 3600)))
+ (should (equal (ietf-drums-parse-date-string
+ "22 Feb (today) 16 19:35:42 +0100" nil t)
+ '(nil nil nil 22 2 nil nil -1 nil)))
+ (should (equal (should-error (ietf-drums-parse-date-string
+ "22 Feb (today) 16 19:35:42 +0100" t t))
+ '(date-parse-error "Expected a year" nil)))
+ (should (equal (ietf-drums-parse-date-string
+ "22 Feb 96 (long ago) 19:35:42 +0100")
+ '(42 35 19 22 2 1996 nil -1 3600)))
+ (should (equal (ietf-drums-parse-date-string
+ "Friday, 21 Sep(comment \\) with \\( parens)18 19:35:42")
+ '(42 35 19 21 9 2018 5 -1 nil)))
+ (should (equal (ietf-drums-parse-date-string
+ "Friday, 21 Sep 18 19:35:42 (unterminated comment")
+ '(42 35 19 21 9 2018 5 -1 nil)))
+
+ ;; Test some RFC822 error cases
+ (dolist (test '(("33 1 2022" ("Slot out of range" day 33 1 31))
+ ("0 1 2022" ("Slot out of range" day 0 1 31))
+ ("1 1 2020 2021" ("Expected an alphabetic month" 1))
+ ("1 Jan 2020 2021" ("Expected a time" 2021))
+ ("1 Jan 2020 20:21 2000" ("Expected a timezone" 2000))
+ ("1 Jan 2020 20:21 +0200 33" ("Extra token(s)" 33))))
+ (should (equal (should-error (ietf-drums-parse-date-string (car test) t))
+ (cons 'date-parse-error (cadr test)))))
+
+ (dolist (test '(("22 Feb 196" nil ;; bad year
+ ("Four-digit years are required" 196))
+ ("22 Feb 16 19:35:24" t ;; two-digit year
+ ("Four-digit years are required" 16))
+ ("22 Feb 96 19:35:42" t ;; two-digit year
+ ("Four-digit years are required" 96))
+ ("2 Feb 2021 1996" nil
+ ("Expected a time" 1996))
+ ("22 Fub 1996" nil
+ ("Expected an alphabetic month" "fub"))
+ ("1 Jan 2020 30" nil
+ ("Expected a time" 30))
+ ("1 Jan 2020 16:47 15:15" nil
+ ("Expected a timezone" "15:15"))
+ ("1 Jan 2020 16:47 +0800 -0800" t
+ ("Extra token(s)" "-0800"))
+ ;; Range tests
+ ("32 Dec 2021" nil
+ ("Slot out of range" day 32 1 31))
+ ("0 Dec 2021" nil
+ ("Slot out of range" day 0 1 31))
+ ("3 13 2021" nil
+ ("Expected an alphabetic month" 13))
+ ("3 Dec 0000" t
+ ("Four-digit years are required" 0))
+ ("3 Dec 20021" nil
+ ("Slot out of range" year 20021 1 9999))
+ ("1 Jan 2020 24:21:14" nil
+ ("Slot out of range" hour "24:21:14" 0 23))
+ ("1 Jan 2020 14:60:21" nil
+ ("Slot out of range" minute "14:60:21" 0 59))
+ ("1 Jan 2020 14:21:61" nil
+ ("Slot out of range" second "14:21:61" 0 60))))
+ (should (equal (should-error
+ (ietf-drums-parse-date-string (car test) t (cadr test)))
+ (cons 'date-parse-error (caddr test)))))
+ (should (equal (ietf-drums-parse-date-string
+ "1 Jan 2020 14:21:60") ;; a leap second!
+ '(60 21 14 1 1 2020 nil -1 nil))))
+
+(provide 'ietf-drums-date-tests)
+
+;;; ietf-drums-date-tests.el ends here
diff --git a/test/lisp/mail/ietf-drums-tests.el b/test/lisp/mail/ietf-drums-tests.el
new file mode 100644
index 00000000000..b13937bf736
--- /dev/null
+++ b/test/lisp/mail/ietf-drums-tests.el
@@ -0,0 +1,178 @@
+;;; ietf-drums-tests.el --- Test suite for ietf-drums.el -*- lexical-binding:t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+
+;; Author: Bob Rogers <rogers@rgrjr.com>
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'ert)
+(require 'ietf-drums)
+
+(ert-deftest ietf-drums-tests ()
+ "Test ietf-drums functionality."
+
+ ;; ietf-drums-remove-comments
+ (should (equal (ietf-drums-remove-comments "random string") "random string"))
+ (should (equal (ietf-drums-remove-comments "random \"non comment\" string")
+ "random \"non comment\" string"))
+ (should (equal (ietf-drums-remove-comments "random (comment) string")
+ "random string"))
+ (should (equal (ietf-drums-remove-comments "random (comment) (string)")
+ "random "))
+ (should (equal (ietf-drums-remove-comments
+ "random (first) (second (and)) (third) not fourth")
+ "random not fourth"))
+ ;; Test some unterminated comments.
+ (should (equal (ietf-drums-remove-comments "test an (unterminated comment")
+ "test an "))
+ (should (equal (ietf-drums-remove-comments "test an \"unterminated quote")
+ ;; returns the string unchanged (and doesn't barf).
+ "test an \"unterminated quote"))
+ (should (equal (ietf-drums-remove-comments
+ ;; note that double-quote is not special.
+ "test (unterminated comments with \"quoted (\" )stuff")
+ "test "))
+
+ ;; ietf-drums-remove-whitespace
+ (should (equal (ietf-drums-remove-whitespace "random string")
+ "randomstring"))
+ (should (equal (ietf-drums-remove-whitespace "random (comment) string")
+ "random(comment)string"))
+ (should (equal (ietf-drums-remove-whitespace "random \"non comment\" string")
+ "random\"non comment\"string"))
+ (should (equal (ietf-drums-remove-whitespace "random (comment)\r\n(string)")
+ "random(comment)(string)"))
+ (should (equal (ietf-drums-remove-whitespace
+ "random (first) (second (and)) (third) not fourth")
+ "random(first)(second (and))(third)notfourth"))
+ ;; Test some unterminated comments and quotes.
+ (should (equal (ietf-drums-remove-whitespace
+ "random (first) (second (and)) (third unterminated")
+ "random(first)(second (and))(third unterminated"))
+ (should (equal (ietf-drums-remove-whitespace "random \"non terminated string")
+ "random\"non terminated string"))
+
+ ;; ietf-drums-strip
+ (should (equal (ietf-drums-strip "random string") "randomstring"))
+ (should (equal (ietf-drums-strip "random \"non comment\" string")
+ "random\"non comment\"string"))
+ (should (equal (ietf-drums-strip "random (comment) string")
+ "randomstring"))
+ (should (equal (ietf-drums-strip "random (comment) (string)")
+ "random"))
+ (should (equal (ietf-drums-strip
+ "random (first) (second (and)) (third) not fourth")
+ "randomnotfourth"))
+
+ ;; ietf-drums-strip-cte
+ (should (equal (ietf-drums-strip-cte "random \"non comment\" string")
+ ;; [the " " is still in there because it was quoted
+ ;; through the "strip". -- rgr, 5-Feb-22.]
+ "randomnon commentstring"))
+ (should (equal (ietf-drums-strip-cte "ran(d)do<m@>[s;t:r],,in=g")
+ "randomstring"))
+
+ ;; ietf-drums-quote-string
+ (should (equal (ietf-drums-quote-string "Bob") "Bob"))
+ (should (equal (ietf-drums-quote-string "Foo Bar") "\"Foo Bar\""))
+
+ ;; ietf-drums-get-comment
+ (should (equal (ietf-drums-get-comment "random string") nil))
+ (should (equal (ietf-drums-get-comment "random (comment) string") "comment"))
+ (should (equal (ietf-drums-get-comment "random \"non comment\" string") nil))
+ (should (equal (ietf-drums-get-comment "\"still (non) comment\" string")
+ nil))
+ (should (equal (ietf-drums-get-comment "random (comment)\r\nstring")
+ "comment"))
+ (should (equal (ietf-drums-get-comment "random (comment) (string)") "string"))
+ (should (equal (ietf-drums-get-comment
+ "random (first) (second (and)) (third) not fourth")
+ "third"))
+
+ ;; ietf-drums-make-address
+ (should (equal (ietf-drums-make-address "Bob Rogers" "rogers@rgrjr.com")
+ "\"Bob Rogers\" <rogers@rgrjr.com>"))
+ (should (equal (ietf-drums-make-address nil "rogers@rgrjr.com")
+ "rogers@rgrjr.com"))
+
+ ;; ietf-drums-parse-address
+ (should (equal (ietf-drums-parse-address "foo@example.com")
+ '("foo@example.com")))
+ (should (equal (ietf-drums-parse-address "<foo@example.com>")
+ '("foo@example.com")))
+ (should (equal (ietf-drums-parse-address "'foo' <foo@example.com>")
+ '("foo@example.com" . "'foo'")))
+ (should (equal (ietf-drums-parse-address "foo <foo@example.com>")
+ '("foo@example.com" . "foo")))
+ (should (equal (ietf-drums-parse-address "foo <foo@example.com> bar")
+ ;; [contrary to RFC2822, which wants the display-name
+ ;; before the address. -- rgr, 5-Feb-22.]
+ '("foo@example.com" . "foo bar")))
+ (should (equal (ietf-drums-parse-address " <foo@example.com> foo ")
+ ;; [ditto. -- rgr, 5-Feb-22.]
+ '("foo@example.com" . "foo")))
+ (should (equal (ietf-drums-parse-address "foo@example.com (foo)")
+ '("foo@example.com" . "foo")))
+ (should (equal (ietf-drums-parse-address "Bar Baz <barbaz@example.com>")
+ '("barbaz@example.com" . "Bar Baz")))
+ (should (equal (ietf-drums-parse-address "barbaz@example.com (Bar Baz)")
+ '("barbaz@example.com" . "Bar Baz")))
+ (should (equal (ietf-drums-parse-address
+ "Bar Baz (ignored) <barbaz@example.com>")
+ '("barbaz@example.com" . "Bar Baz")))
+ (should (equal (ietf-drums-parse-address "<barbaz@example.com> Bar Baz")
+ '("barbaz@example.com" . "Bar Baz")))
+ (should (equal (ietf-drums-parse-address
+ "(Bar Baz not ignored) barbaz@example.com")
+ ;; [not strictly RFC2822, which expects the name
+ ;; comment after the address. -- rgr, 5-Feb-22.]
+ '("barbaz@example.com" . "Bar Baz not ignored")))
+ (should (equal (ietf-drums-parse-address
+ "(ignored) <barbaz@example.com> (Bar Baz not ignored)")
+ '("barbaz@example.com" . "Bar Baz not ignored")))
+ (should (equal (ietf-drums-parse-address
+ "(ignored) barbaz@example.com (Bar Baz not ignored)")
+ '("barbaz@example.com" . "Bar Baz not ignored")))
+ ;; Test for RFC2047 token decoding.
+ (should (equal (ietf-drums-parse-address
+ "=?utf-8?B?0JfQtNGA0LDMgdCy0YHRgtCy0YPQudGC0LUh?= <foo@goo.ru>"
+ t)
+ '("foo@goo.ru" . "Здра́вствуйте!")))
+
+ ;; ietf-drums-parse-addresses
+ ;; Note that it's not worth getting too elaborate here, as the heavy
+ ;; lifting is all done by ietf-drums-parse-address.
+ (should (equal (ietf-drums-parse-addresses "foo@example.com")
+ '(("foo@example.com"))))
+ (should (equal (ietf-drums-parse-addresses
+ "foo@example.com, bar@example.com")
+ '(("foo@example.com") ("bar@example.com"))))
+ (should (equal (ietf-drums-parse-addresses
+ "foo@example.com, quux, bar@example.com")
+ '(("foo@example.com") ("bar@example.com"))))
+ (should (equal (ietf-drums-parse-addresses
+ "foo@example.com, Quux Dude <quux@noop.org>, bar@example.com")
+ '(("foo@example.com") ("quux@noop.org" . "Quux Dude")
+ ("bar@example.com")))))
+
+(provide 'ietf-drums-tests)
+
+;;; ietf-drums-tests.el ends here
diff --git a/test/lisp/mail/mail-extr-tests.el b/test/lisp/mail/mail-extr-tests.el
new file mode 100644
index 00000000000..a8f0c605cb0
--- /dev/null
+++ b/test/lisp/mail/mail-extr-tests.el
@@ -0,0 +1,41 @@
+;;; mail-extr-tests.el --- Tests for mail-extr.el -*- lexical-binding: t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'ert)
+(require 'mail-extr)
+
+(defconst mail-extract-test-cases
+ '(("foo@example.org" . (nil "foo@example.org"))
+ ("J. Random Hacker <foo@example.org>" . ("J. Random Hacker" "foo@example.org"))
+ ("\"J. Random Hacker\" <foo@example.org>" . ("J. Random Hacker" "foo@example.org"))
+ ("Ååå Äää <foo@example.org>" . ("Ååå Äää" "foo@example.org"))))
+
+(ert-deftest mail-extract-address-components ()
+ (dolist (test mail-extract-test-cases)
+ (should (equal (mail-extract-address-components (car test)) (cdr test)))))
+
+(ert-deftest what-domain ()
+ (should (equal (what-domain "cu") "CU: Cuba")))
+
+(provide 'mail-extr-tests)
+;;; mail-extr-tests.el ends here
diff --git a/test/lisp/mail/mail-utils-tests.el b/test/lisp/mail/mail-utils-tests.el
index 4b2d2d7e005..29a9b9eeb96 100644
--- a/test/lisp/mail/mail-utils-tests.el
+++ b/test/lisp/mail/mail-utils-tests.el
@@ -85,7 +85,8 @@
"foo@example.org\\|bar@example.org\\|baz@example.org")))
(ert-deftest mail-utils-tests-mail-rfc822-time-zone ()
- (should (stringp (mail-rfc822-time-zone (current-time)))))
+ (with-suppressed-warnings ((obsolete mail-rfc822-time-zone))
+ (should (stringp (mail-rfc822-time-zone (current-time))))))
(ert-deftest mail-utils-test-mail-rfc822-date/contains-year ()
(should (string-match (rx " 20" digit digit " ")
diff --git a/test/lisp/mail/undigest-tests.el b/test/lisp/mail/undigest-tests.el
new file mode 100644
index 00000000000..d52c9f9c5ab
--- /dev/null
+++ b/test/lisp/mail/undigest-tests.el
@@ -0,0 +1,359 @@
+;;; undigest-tests.el --- Tests for undigest.el -*- lexical-binding:t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'ert)
+(require 'ert-x)
+(require 'rmail)
+(require 'undigest)
+
+;;; Variables:
+;; Some digests for testing.
+(defvar rmail-rfc934-digest "From tester Fri Jan 24 00:00:00 2022
+From: Digester <digester@digester.com>
+To: Undigester <undigester@undigester.com>
+Date: ddd, dd mmm yy hh:mm:ss zzz
+Subject: Testing you
+
+Testing the undigester.
+
+------- Message sep
+
+From: NN1 <nn1@nn1.com>
+To: Digester <digester@digester.com>
+Date: ddd, dd mmm yy hh:mm:ss zzz
+Subject: Message one
+
+This is message one.
+
+------- Message sep
+
+From: NN2 <nn2@nn2.com>
+To: Digester <digester@digester.com>
+Date: ddd, dd mmm yy hh:mm:ss zzz
+Subject: Message two
+
+This is message two.
+"
+
+ "RFC 934 digest.")
+
+(defvar rmail-rfc1153-digest-strict "From tester Fri Jan 24 00:00:00 2022
+Date: ddd, dd mmm yy hh:mm:ss zzz
+From: Digester <digester@digester.com>
+To: Undigester <undigester@undigester.com>
+Date: ddd, dd mmm yy hh:mm:ss zzz
+Subject: Testing you
+
+Some mailing list information.
+
+Today's Topics:
+
+ 1. Message One Subject (Sender)
+ 2. Message Two Subject (Sender)
+
+----------------------------------------------------------------------
+
+Date: ddd, dd mmm yy hh:mm:ss zzz
+From: NN1 <nn1@nn1.com>
+Subject: Message One Subject
+
+This is message one.
+
+------------------------------
+
+Date: ddd, dd mmm yy hh:mm:ss zzz
+From: NN2 <nn2@nn2.com>
+Subject: Message Two Subject
+
+This is message two.
+
+------------------------------
+
+End of Digest.
+************************************
+"
+ "RFC 1153 strict style digest.")
+
+(defvar rmail-rfc1153-digest-less-strict "From tester Fri Jan 24 00:00:00 2022
+From: Digester <digester@digester.com>
+To: Undigester <undigester@undigester.com>
+Date: ddd, dd mmm yy hh:mm:ss zzz
+Subject: Testing you
+
+Some mailing list information.
+
+Today's Topics:
+
+ 1. Message One Subject (Sender)
+ 2. Message Two Subject (Sender)
+
+----------------------------------------------------------------------
+
+Date: ddd, dd mmm yy hh:mm:ss zzz
+From: NN1 <nn1@nn1.com>
+Subject: Message One Subject
+
+This is message one.
+
+------------------------------
+
+Date: ddd, dd mmm yy hh:mm:ss zzz
+From: NN2 <nn2@nn2.com>
+Subject: Message Two Subject
+
+This is message two.
+
+------------------------------
+
+Subject: Digest Footer
+
+End of Sbcl-help Digest, Vol 158, Issue 4
+*****************************************
+"
+ "RFC 1153 style digest, with a Subject header.")
+
+(defvar rmail-rfc1153-digest-sloppy "From tester Fri Jan 24 00:00:00 2022
+From: Digester <digester@digester.com>
+To: Undigester <undigester@undigester.com>
+Date: ddd, dd mmm yy hh:mm:ss zzz
+Subject: Testing you
+
+Some mailing list information.
+
+Today's Topics:
+
+ 1. Message One Subject (Sender)
+ 2. Message Two Subject (Sender)
+
+----------------------------------------------------------------------
+
+Date: ddd, dd mmm yy hh:mm:ss zzz
+From: NN1 <nn1@nn1.com>
+Subject: Message One Subject
+
+This is message one.
+
+------------------------------
+
+Date: ddd, dd mmm yy hh:mm:ss zzz
+From: NN2 <nn2@nn2.com>
+Subject: Message Two Subject
+
+This is message two.
+
+------------------------------
+
+Subject: Digest Footer
+
+______________________________________________
+Some blurb.
+
+End of Digest.
+************************************
+"
+ "RFC 1153 sloppy style digest.")
+
+(defvar rmail-rfc1521-mime-digest "From tester Fri Jan 24 00:00:00 2022
+From: Digester <digester@digester.com>
+To: Undigester <undigester@undigester.com>
+Date: ddd, dd mmm yy hh:mm:ss zzz
+Subject: Test digest
+MIME-Version: 1.0
+Content-Type: multipart/digest; boundary=\"----- =_aaaaaaaaaa0\"
+
+------- =_aaaaaaaaaa0
+Content-Type: message/rfc822
+
+From: NN1 <nn1@nn1.com>
+To: Digester <digester@digester.com>
+Date: ddd, dd mmm yy hh:mm:ss zzz
+Subject: Message one
+
+Message one.
+
+------- =_aaaaaaaaaa0
+
+From: NN2 <nn2@nn2.com>
+To: Digester <digester@digester.com>
+Date: ddd, dd mmm yy hh:mm:ss zzz
+Subject: Message two
+
+Message two.
+
+------- =_aaaaaaaaaa0
+"
+ "RFC 1521 style MIME digest.")
+
+(defvar rmail-multipart-mixed-digest
+ "From tester Fri Jan 24 00:00:00 2022
+From: Digester <digester@digester.com>
+To: Undigester <undigester@undigester.com>
+Date: ddd, dd mmm yy hh:mm:ss zzz
+Subject: Test digest
+Content-Type: multipart/mixed; boundary=\"===============2529375068597856000==\"
+MIME-Version: 1.0
+
+--===============2529375068597856000==
+Content-Type: text/plain;
+MIME-Version: 1.0
+Content-Description: Today's Topics
+
+Some message.
+
+--===============2529375068597856000==
+Content-Type: multipart/digest; boundary=\"===============6060050777038710134==\"
+MIME-Version: 1.0
+
+--===============6060050777038710134==
+Content-Type: message/rfc822
+MIME-Version: 1.0
+
+From: NN1 <nn1@nn1.com>
+To: Digester <digester@digester.com>
+Date: ddd, dd mmm yy hh:mm:ss zzz
+Subject: Message one
+
+Message one.
+
+--===============6060050777038710134==
+Content-Type: message/rfc822
+MIME-Version: 1.0
+
+From: NN2 <nn2@nn2.com>
+To: Digester <digester@digester.com>
+Date: ddd, dd mmm yy hh:mm:ss zzz
+Subject: Message two
+
+Message two.
+
+--===============6060050777038710134==--
+
+--===============2529375068597856000==
+Content-Type: text/plain;
+MIME-Version: 1.0
+Content-Description: Digest Footer
+
+The footer.
+
+--===============2529375068597856000==--"
+ "RFC 1521 digest inside a multipart/mixed message.")
+
+;;; Utils:
+(defun rmail-message-content (message)
+ "Return the content of the message numbered MESSAGE."
+ (rmail-show-message message)
+ (let ((beg (rmail-msgbeg rmail-current-message))
+ (end (rmail-msgend rmail-current-message)))
+ (with-current-buffer rmail-view-buffer
+ (save-excursion
+ (goto-char beg)
+ (search-forward "\n\n" end nil)
+ (buffer-substring-no-properties (match-end 0) end)))))
+
+;;; Tests:
+(ert-deftest rmail-undigest-test-rfc934-digest ()
+ "Test that we can undigest a RFC 934 digest."
+ (ert-with-temp-file file
+ :text rmail-rfc934-digest
+ ;; Rmail reads mbox files literally, so we must make sure the
+ ;; temporary mbox file has Unix-style EOLs.
+ :coding 'undecided-unix
+ (rmail file)
+ (undigestify-rmail-message)
+ (should (= rmail-total-messages 4))
+ (should (string= (rmail-message-content 2) "Testing the undigester.\n\n"))
+ (should (string= (rmail-message-content 3) "This is message one.\n\n"))
+ (should (string= (rmail-message-content 4) "This is message two.\n"))))
+
+(ert-deftest rmail-undigest-test-rfc1153-digest-strict ()
+ "Test that we can undigest a strict RFC 1153 digest."
+ :expected-result :failed
+ (ert-with-temp-file file
+ :text rmail-rfc1153-digest-strict
+ ;; Rmail reads mbox files literally, so we must make sure the
+ ;; temporary mbox file has Unix-style EOLs.
+ :coding 'undecided-unix
+ (rmail file)
+ (should
+ (ignore-errors
+ ;; This throws an error, because the Trailer is not recognized
+ ;; as a valid RFC 822 (or later) message.
+ (undigestify-rmail-message)
+ (should (string= (rmail-message-content 2) "Testing the undigester.\n\n"))
+ (should (string= (rmail-message-content 3) "This is message one.\n\n"))
+ (should (string= (rmail-message-content 4) "This is message two.\n"))
+ t))))
+
+(ert-deftest rmail-undigest-test-rfc1153-less-strict-digest ()
+ "Test that we can undigest a RFC 1153 with a Subject header in its footer."
+ (ert-with-temp-file file
+ :text rmail-rfc1153-digest-less-strict
+ ;; Rmail reads mbox files literally, so we must make sure the
+ ;; temporary mbox file has Unix-style EOLs.
+ :coding 'undecided-unix
+ (rmail file)
+ (undigestify-rmail-message)
+ (should (= rmail-total-messages 5))
+ (should (string= (rmail-message-content 3) "This is message one.\n\n"))
+ (should (string= (rmail-message-content 4) "This is message two.\n\n"))))
+
+(ert-deftest rmail-undigest-test-rfc1153-sloppy-digest ()
+ "Test that we can undigest a sloppy RFC 1153 digest."
+ (ert-with-temp-file file
+ :text rmail-rfc1153-digest-sloppy
+ ;; Rmail reads mbox files literally, so we must make sure the
+ ;; temporary mbox file has Unix-style EOLs.
+ :coding 'undecided-unix
+ (rmail file)
+ (undigestify-rmail-message)
+ (should (= rmail-total-messages 5))
+ (should (string= (rmail-message-content 3) "This is message one.\n\n"))
+ (should (string= (rmail-message-content 4) "This is message two.\n\n"))))
+
+;; This fails because `rmail-digest-parse-mime' combines the preamble with the
+;; first message of the digest. And then, it doesn't get rid of the last
+;; separator.
+(ert-deftest rmail-undigest-test-rfc1521-mime-digest ()
+ "Test that we can undigest a RFC 1521 MIME digest."
+ :expected-result :failed
+ (ert-with-temp-file file
+ :text rmail-rfc1521-mime-digest
+ ;; Rmail reads mbox files literally, so we must make sure the
+ ;; temporary mbox file has Unix-style EOLs.
+ :coding 'undecided-unix
+ (rmail file)
+ (undigestify-rmail-message)
+ (should (= rmail-total-messages 3))
+ (should (string= (rmail-message-content 2) "Message one.\n\n"))
+ (should (string= (rmail-message-content 3) "Message two.\n\n"))))
+
+(ert-deftest rmail-undigest-test-multipart-mixed-digest ()
+ "Test that we can undigest a digest inside a multipart/mixed digest."
+ (ert-with-temp-file file
+ :text rmail-multipart-mixed-digest
+ ;; Rmail reads mbox files literally, so we must make sure the
+ ;; temporary mbox file has Unix-style EOLs.
+ :coding 'undecided-unix
+ (rmail file)
+ (undigestify-rmail-message)
+ (should (= rmail-total-messages 4))
+ (should (string= (rmail-message-content 2) "Message one.\n\n"))
+ (should (string= (rmail-message-content 3) "Message two.\n\n"))))
diff --git a/test/lisp/mail/uudecode-tests.el b/test/lisp/mail/uudecode-tests.el
index a58a4d9e6f6..7946e99dbc9 100644
--- a/test/lisp/mail/uudecode-tests.el
+++ b/test/lisp/mail/uudecode-tests.el
@@ -50,14 +50,11 @@ Same as `uudecode-tests-encoded-str' but plain text.")
(should (equal (buffer-string) uudecode-tests-decoded-str)))
;; Write to file
(with-temp-buffer
- (let ((tmpfile (make-temp-file "uudecode-tests-")))
- (unwind-protect
- (progn
- (insert uudecode-tests-encoded-str)
- (uudecode-decode-region-internal (point-min) (point-max) tmpfile)
- (should (equal (uudecode-tests-read-file tmpfile)
- uudecode-tests-decoded-str)))
- (delete-file tmpfile)))))
+ (ert-with-temp-file tmpfile
+ (insert uudecode-tests-encoded-str)
+ (uudecode-decode-region-internal (point-min) (point-max) tmpfile)
+ (should (equal (uudecode-tests-read-file tmpfile)
+ uudecode-tests-decoded-str)))))
(ert-deftest uudecode-tests-decode-region-external ()
;; Write to buffer
@@ -68,14 +65,11 @@ Same as `uudecode-tests-encoded-str' but plain text.")
(should (equal (buffer-string) uudecode-tests-decoded-str)))
;; Write to file
(with-temp-buffer
- (let ((tmpfile (make-temp-file "uudecode-tests-")))
- (unwind-protect
- (progn
- (insert uudecode-tests-encoded-str)
- (uudecode-decode-region-external (point-min) (point-max) tmpfile)
- (should (equal (uudecode-tests-read-file tmpfile)
- uudecode-tests-decoded-str)))
- (delete-file tmpfile))))))
+ (ert-with-temp-file tmpfile
+ (insert uudecode-tests-encoded-str)
+ (uudecode-decode-region-external (point-min) (point-max) tmpfile)
+ (should (equal (uudecode-tests-read-file tmpfile)
+ uudecode-tests-decoded-str))))))
(provide 'uudecode-tests)
;;; uudecode-tests.el ends here
diff --git a/test/lisp/mh-e/mh-thread-tests.el b/test/lisp/mh-e/mh-thread-tests.el
new file mode 100644
index 00000000000..ea8d441e2d1
--- /dev/null
+++ b/test/lisp/mh-e/mh-thread-tests.el
@@ -0,0 +1,131 @@
+;;; mh-thread-tests.el --- tests for mh-thread.el -*- lexical-binding: t -*-
+
+;; Copyright (C) 2021-2022 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'ert)
+(require 'mh-thread)
+(eval-when-compile (require 'cl-lib))
+
+(defun mh-thread-tests-before-from ()
+ "Generate the fields of a scan line up to where the \"From\" field would start.
+The exact contents are not important, but the number of characters is."
+ (concat (make-string mh-cmd-note ?9)
+ (make-string mh-scan-cmd-note-width ?A)
+ (make-string mh-scan-destination-width ?t)
+ (make-string mh-scan-date-width ?/)
+ (make-string mh-scan-date-flag-width ?*)))
+
+;;; Tests of support routines
+
+(ert-deftest mh-thread-current-indentation-level ()
+ "Test that `mh-thread-current-indentation-level' identifies the level."
+ (with-temp-buffer
+ (insert (mh-thread-tests-before-from) "[Sender One] Subject of msg 1\n")
+ (insert (mh-thread-tests-before-from) " [Sender Two] Subject of msg 2\n")
+ (goto-char (point-min))
+ (should (equal 0 (mh-thread-current-indentation-level)))
+ (forward-line)
+ (should (equal 2 (mh-thread-current-indentation-level)))))
+
+(ert-deftest mh-thread-find-children ()
+ "Test `mh-thread-find-children'."
+ (let (expected-start expected-end)
+ (with-temp-buffer
+ (insert (mh-thread-tests-before-from) "[Sender One] line 1\n")
+ (setq expected-start (point))
+ (insert (mh-thread-tests-before-from) " [Sender Two] line 2\n")
+ (insert (mh-thread-tests-before-from) " [Sender Three] line 3\n")
+ (insert (mh-thread-tests-before-from) " [Sender Four] line 4\n")
+ (setq expected-end (1- (point)))
+ (insert (mh-thread-tests-before-from) " [Sender Five] line 5\n")
+ (goto-char (1+ expected-start))
+ (should (equal (list expected-start expected-end)
+ (mh-thread-find-children))))))
+
+(ert-deftest mh-thread-immediate-ancestor ()
+ "Test that `mh-thread-immediate-ancestor' moves to the correct message."
+ (with-temp-buffer
+ (insert (mh-thread-tests-before-from) "[Sender Other] line 1\n")
+ (insert (mh-thread-tests-before-from) "[Sender One] line 2\n")
+ (insert (mh-thread-tests-before-from) " [Sender Two] line 3\n")
+ (insert (mh-thread-tests-before-from) " [Sender Three] line 4\n")
+ (insert (mh-thread-tests-before-from) " [Sender Four] line 5\n")
+ (insert (mh-thread-tests-before-from) " [Sender Five] line 6\n")
+ (forward-line -1)
+ (should (equal (line-number-at-pos) 6))
+ (mh-thread-immediate-ancestor)
+ (should (equal (line-number-at-pos) 4)) ;skips over sibling
+ (mh-thread-immediate-ancestor)
+ (should (equal (line-number-at-pos) 3)) ;goes up only one level at a time
+ (mh-thread-immediate-ancestor)
+ (should (equal (line-number-at-pos) 2))
+ (mh-thread-immediate-ancestor)
+ (should (equal (line-number-at-pos) 2)))) ;no further motion at thread root
+
+;;; Tests of MH-Folder Commands
+
+(ert-deftest mh-thread-sibling-and-ancestor ()
+ "Test motion by `mh-thread-ancestor' and `mh-thread-next-sibling'."
+ (with-temp-buffer
+ (insert (mh-thread-tests-before-from) "[Sender Other] line 1\n")
+ (insert (mh-thread-tests-before-from) "[Sender One] line 2\n")
+ (insert (mh-thread-tests-before-from) " [Sender Two] line 3\n")
+ (insert (mh-thread-tests-before-from) " [Sender Three] line 4\n")
+ (insert (mh-thread-tests-before-from) " [Sender Four] line 5\n")
+ (insert (mh-thread-tests-before-from) " [Sender Five] line 6\n")
+ (forward-line -1)
+ (let ((mh-view-ops '(unthread))
+ (show-count 0))
+ (cl-letf (((symbol-function 'mh-maybe-show)
+ (lambda ()
+ (setq show-count (1+ show-count)))))
+ (should (equal (line-number-at-pos) 6))
+ ;; test mh-thread-ancestor
+ (mh-thread-ancestor)
+ (should (equal (line-number-at-pos) 4)) ;skips over sibling
+ (should (equal show-count 1))
+ (mh-thread-ancestor t)
+ (should (equal (line-number-at-pos) 2)) ;root flag skips to root
+ (should (equal show-count 2))
+ (mh-thread-ancestor)
+ (should (equal (line-number-at-pos) 2)) ;do not move from root
+ (should (equal show-count 2)) ;do not re-show at root
+ ;; test mh-thread-sibling
+ (mh-thread-next-sibling)
+ (should (equal (line-number-at-pos) 2)) ;no next sibling, no motion
+ (should (equal show-count 2)) ;no sibling, no show
+ (mh-thread-next-sibling t)
+ (should (equal (line-number-at-pos) 1))
+ (should (equal show-count 3))
+ (mh-thread-next-sibling t)
+ (should (equal (line-number-at-pos) 1)) ;no previous sibling
+ (should (equal show-count 3))
+ (goto-char (point-max))
+ (forward-line -1)
+ (should (equal (line-number-at-pos) 6))
+ (mh-thread-next-sibling t)
+ (should (equal (line-number-at-pos) 5))
+ (should (equal show-count 4))
+ (mh-thread-next-sibling t)
+ (should (equal (line-number-at-pos) 5)) ;no previous sibling
+ (should (equal show-count 4))
+ ))))
+
+;;; mh-thread-tests.el ends here
diff --git a/test/lisp/mh-e/mh-utils-tests.el b/test/lisp/mh-e/mh-utils-tests.el
index b1a892b8530..72ee2fc4745 100644
--- a/test/lisp/mh-e/mh-utils-tests.el
+++ b/test/lisp/mh-e/mh-utils-tests.el
@@ -48,8 +48,10 @@
;;; Code:
(require 'ert)
-(eval-when-compile (require 'cl-lib))
(require 'mh-utils)
+(eval-when-compile
+ (require 'cl-lib)
+ (require 'subr-x))
(ert-deftest mh-quote-pick-expr ()
"Test `mh-quote-pick-expr'."
@@ -80,6 +82,54 @@
(mh-normalize-folder-name "+inbox////../news/" nil t)))
(should (equal "+inbox/news" (mh-normalize-folder-name "+inbox////./news"))))
+(ert-deftest mh-sub-folders-parse-no-folder ()
+ "Test `mh-sub-folders-parse' with no starting folder."
+ (let (others-position)
+ (with-temp-buffer
+ (insert "lines without has-string are ignored\n")
+ (insert "onespace has no messages.\n")
+ (insert "twospace has no messages.\n")
+ (insert " precedingblanks has no messages.\n")
+ (insert ".leadingdot has no messages.\n")
+ (insert "#leadinghash has no messages.\n")
+ (insert ",leadingcomma has no messages.\n")
+ (insert "withothers has no messages ; (others)")
+ (setq others-position (point))
+ (insert ".\n")
+ (insert "curf has no messages.\n")
+ (insert "curf+ has 123 messages.\n")
+ (insert "curf2+ has 17 messages.\n")
+ (insert "\ntotal after blank line is ignored has no messages.\n")
+ (should (equal
+ (mh-sub-folders-parse nil "curf+")
+ (list '("onespace") '("twospace") '("precedingblanks")
+ (cons "withothers" others-position)
+ '("curf") '("curf") '("curf2+")))))))
+
+(ert-deftest mh-sub-folders-parse-relative-folder ()
+ "Test `mh-sub-folders-parse' with folder."
+ (let (others-position)
+ (with-temp-buffer
+ (insert "testf+ has no messages.\n")
+ (insert "testf/sub1 has no messages.\n")
+ (insert "testf/sub2 has no messages ; (others)")
+ (setq others-position (point))
+ (insert ".\n")
+ (should (equal
+ (mh-sub-folders-parse "+testf" "testf+")
+ (list '("sub1") (cons "sub2" others-position)))))))
+
+(ert-deftest mh-sub-folders-parse-root-folder ()
+ "Test `mh-sub-folders-parse' with root folder."
+ (with-temp-buffer
+ (insert "/+ has no messages.\n")
+ (insert "/ has no messages.\n")
+ (insert "//nmh-style has no messages.\n")
+ (insert "/mu-style has no messages.\n")
+ (should (equal
+ (mh-sub-folders-parse "+/" "inbox+")
+ '(("") ("nmh-style") ("mu-style"))))))
+
;; Folder names that are used by the following tests.
(defvar mh-test-rel-folder "rela-folder")
@@ -211,6 +261,10 @@ The tests use this method if no configured MH variant is found."
"/abso-folder/bar has no messages."
"/abso-folder/foo has no messages."
"/abso-folder/food has no messages."))
+ (("folders" "-noheader" "-norecurse" "-nototal" "+/") .
+ ("/+ has no messages ; (others)."
+ "/abso-folder has no messages ; (others)."
+ "/tmp has no messages ; (others)."))
))
(arglist (cons (file-name-base program) args)))
(let ((response-list-cons (assoc arglist argument-responses)))
@@ -303,6 +357,15 @@ if `mh-test-utils-debug-mocks' is non-nil."
(message "file-directory-p: %S -> %s" filename result))
result))
+(defun mh-test-variant-handles-plus-slash (variant)
+ "Returns non-nil if this MH variant handles \"folders +/\".
+Mailutils 3.5, 3.7, and 3.13 are known not to."
+ (cond ((not (stringp variant))) ;our mock handles it
+ ((string-search "GNU Mailutils" variant)
+ (let ((mu-version (string-remove-prefix "GNU Mailutils " variant)))
+ (version<= "3.13.91" mu-version)))
+ (t))) ;no other known failures
+
(ert-deftest mh-sub-folders-actual ()
"Test `mh-sub-folders-actual'."
@@ -310,14 +373,15 @@ if `mh-test-utils-debug-mocks' is non-nil."
;; already been normalized with
;; (mh-normalize-folder-name folder nil nil t)
(with-mh-test-env
- (should (equal
+ (should (member
mh-test-rel-folder
- (car (assoc mh-test-rel-folder (mh-sub-folders-actual nil)))))
+ (mapcar (lambda (x) (car x)) (mh-sub-folders-actual nil))))
;; Empty string and "+" not tested since mh-normalize-folder-name
;; would change them to nil.
- (should (equal "foo"
- (car (assoc "foo" (mh-sub-folders-actual
- (format "+%s" mh-test-rel-folder))))))
+ (should (member "foo"
+ (mapcar (lambda (x) (car x))
+ (mh-sub-folders-actual
+ (format "+%s" mh-test-rel-folder)))))
;; Folder with trailing slash not tested since
;; mh-normalize-folder-name would strip it.
(should (equal
@@ -328,6 +392,10 @@ if `mh-test-utils-debug-mocks' is non-nil."
(list (list "bar") (list "foo") (list "food"))
(mh-sub-folders-actual (format "+%s" mh-test-abs-folder))))
+ (when (mh-test-variant-handles-plus-slash mh-variant-in-use)
+ (should (member "tmp" (mapcar (lambda (x) (car x))
+ (mh-sub-folders-actual "+/")))))
+
;; FIXME: mh-sub-folders-actual doesn't (yet) expect to be given a
;; nonexistent folder.
;; (should (equal nil
@@ -339,13 +407,12 @@ if `mh-test-utils-debug-mocks' is non-nil."
(ert-deftest mh-sub-folders ()
"Test `mh-sub-folders'."
(with-mh-test-env
- (should (equal mh-test-rel-folder
- (car (assoc mh-test-rel-folder (mh-sub-folders nil)))))
- (should (equal mh-test-rel-folder
- (car (assoc mh-test-rel-folder (mh-sub-folders "")))))
- (should (equal nil
- (car (assoc mh-test-no-such-folder (mh-sub-folders
- "+")))))
+ (should (member mh-test-rel-folder
+ (mapcar (lambda (x) (car x)) (mh-sub-folders nil))))
+ (should (member mh-test-rel-folder
+ (mapcar (lambda (x) (car x)) (mh-sub-folders ""))))
+ (should-not (member mh-test-no-such-folder
+ (mapcar (lambda (x) (car x)) (mh-sub-folders "+"))))
(should (equal (list (list "bar") (list "foo") (list "food"))
(mh-sub-folders (format "+%s" mh-test-rel-folder))))
(should (equal (list (list "bar") (list "foo") (list "food"))
@@ -356,6 +423,9 @@ if `mh-test-utils-debug-mocks' is non-nil."
(mh-sub-folders (format "+%s/foo" mh-test-rel-folder))))
(should (equal (list (list "bar") (list "foo") (list "food"))
(mh-sub-folders (format "+%s" mh-test-abs-folder))))
+ (when (mh-test-variant-handles-plus-slash mh-variant-in-use)
+ (should (member "tmp"
+ (mapcar (lambda (x) (car x)) (mh-sub-folders "+/")))))
;; FIXME: mh-sub-folders doesn't (yet) expect to be given a
;; nonexistent folder.
@@ -437,18 +507,20 @@ and the `should' macro requires idempotent evaluation anyway."
(ert-deftest mh-folder-completion-function-08-plus-slash ()
"Test `mh-folder-completion-function' with `+/'."
- :expected-result :failed ;to be fixed in a patch by mkupfer
- (mh-test-folder-completion-1 "+/" "+/" "tmp/" nil)
- ;; case "bb"
- (with-mh-test-env
- (should (equal nil
- (member (format "+%s/" mh-test-rel-folder)
- (mh-folder-completion-function "+/" nil t))))))
+ (with-mh-test-env
+ (skip-unless (mh-test-variant-handles-plus-slash mh-variant-in-use)))
+ (mh-test-folder-completion-1 "+/" "+/" "tmp/" t)
+ ;; case "bb"
+ (with-mh-test-env
+ (should (equal nil
+ (member (format "+%s/" mh-test-rel-folder)
+ (mh-folder-completion-function "+/" nil t))))))
(ert-deftest mh-folder-completion-function-09-plus-slash-tmp ()
"Test `mh-folder-completion-function' with `+/tmp'."
- :expected-result :failed ;to be fixed in a patch by mkupfer
- (mh-test-folder-completion-1 "+/tmp" "+/tmp" "tmp/" t))
+ (with-mh-test-env
+ (skip-unless (mh-test-variant-handles-plus-slash mh-variant-in-use)))
+ (mh-test-folder-completion-1 "+/tmp" "+/tmp/" "tmp/" t))
(ert-deftest mh-folder-completion-function-10-plus-slash-abs-folder ()
"Test `mh-folder-completion-function' with `+/abso-folder'."
diff --git a/test/lisp/mh-e/test-all-mh-variants.sh b/test/lisp/mh-e/test-all-mh-variants.sh
index 6693a8a3e97..3789a5fdedc 100755
--- a/test/lisp/mh-e/test-all-mh-variants.sh
+++ b/test/lisp/mh-e/test-all-mh-variants.sh
@@ -79,12 +79,10 @@ for path in "${mh_sys_path[@]}"; do
continue
fi
fi
- echo "Testing with PATH $path"
+ echo "** Testing with PATH $path"
((++tests_total))
- # The LD_LIBRARY_PATH setting is needed
- # to run locally installed Mailutils.
TEST_MH_PATH=$path TEST_MH_DEBUG=$debug \
- LD_LIBRARY_PATH=/usr/local/lib HOME=/nonexistent \
+ HOME=/nonexistent \
"${emacs[@]}" -l ert \
--eval "(setq load-prefer-newer t)" \
--eval "(load \"$PWD/test/lisp/mh-e/mh-utils-tests\" nil t)" \
diff --git a/test/lisp/minibuffer-tests.el b/test/lisp/minibuffer-tests.el
index 2a29d5f167b..ec93c8f42a5 100644
--- a/test/lisp/minibuffer-tests.el
+++ b/test/lisp/minibuffer-tests.el
@@ -331,5 +331,141 @@
"custgroup" '("customize-group-other-window") nil 9)))
15)))
+
+(defmacro completing-read-with-minibuffer-setup (collection &rest body)
+ (declare (indent 1) (debug (collection body)))
+ `(catch 'result
+ (minibuffer-with-setup-hook
+ (lambda ()
+ (let ((redisplay-skip-initial-frame nil)
+ (executing-kbd-macro nil)) ; Don't skip redisplay
+ (throw 'result (progn . ,body))))
+ (let ((executing-kbd-macro t)) ; Force the real minibuffer
+ (completing-read "Prompt: " ,collection)))))
+
+(ert-deftest completion-auto-help-test ()
+ (let (messages)
+ (cl-letf* (((symbol-function 'minibuffer-message)
+ (lambda (message &rest args)
+ (push (apply #'format-message message args) messages))))
+ (let ((completion-auto-help nil))
+ (completing-read-with-minibuffer-setup
+ '("a" "ab" "ac")
+ (execute-kbd-macro (kbd "a TAB TAB"))
+ (should (equal (car messages) "Complete, but not unique"))
+ (should-not (get-buffer-window "*Completions*" 0))))
+ (let ((completion-auto-help t))
+ (completing-read-with-minibuffer-setup
+ '("a" "ab" "ac")
+ (execute-kbd-macro (kbd "a TAB TAB"))
+ (should (get-buffer-window "*Completions*" 0)))))))
+
+(ert-deftest completion-auto-select-test ()
+ (let ((completion-auto-select t))
+ (completing-read-with-minibuffer-setup
+ '("aa" "ab" "ac")
+ (execute-kbd-macro (kbd "a TAB"))
+ (should (and (get-buffer-window "*Completions*" 0)
+ (eq (current-buffer) (get-buffer "*Completions*"))))
+ (execute-kbd-macro (kbd "TAB TAB TAB"))
+ (should (and (get-buffer-window "*Completions*" 0)
+ (eq (current-buffer) (get-buffer " *Minibuf-1*"))))
+ (execute-kbd-macro (kbd "S-TAB"))
+ (should (and (get-buffer-window "*Completions*" 0)
+ (eq (current-buffer) (get-buffer "*Completions*"))))))
+ (let ((completion-auto-select 'second-tab))
+ (completing-read-with-minibuffer-setup
+ '("aa" "ab" "ac")
+ (execute-kbd-macro (kbd "a TAB"))
+ (should (and (get-buffer-window "*Completions*" 0)
+ (not (eq (current-buffer) (get-buffer "*Completions*")))))
+ (execute-kbd-macro (kbd "TAB TAB"))
+ (should (eq (current-buffer) (get-buffer "*Completions*"))))))
+
+(ert-deftest completion-auto-wrap-test ()
+ (let ((completion-auto-wrap nil))
+ (completing-read-with-minibuffer-setup
+ '("aa" "ab" "ac")
+ (insert "a")
+ (minibuffer-completion-help)
+ (switch-to-completions)
+ (should (equal "aa" (get-text-property (point) 'completion--string)))
+ (next-completion 2)
+ (should (equal "ac" (get-text-property (point) 'completion--string)))
+ ;; Fixed in bug#54374
+ (next-completion 5)
+ (should (equal "ac" (get-text-property (point) 'completion--string)))
+ (previous-completion 5)
+ (should (equal "aa" (get-text-property (point) 'completion--string)))))
+ (let ((completion-auto-wrap t))
+ (completing-read-with-minibuffer-setup
+ '("aa" "ab" "ac")
+ (insert "a")
+ (minibuffer-completion-help)
+ (switch-to-completions)
+ (should (equal "aa" (get-text-property (point) 'completion--string)))
+ (next-completion 2)
+ (should (equal "ac" (get-text-property (point) 'completion--string)))
+ (next-completion 1)
+ (should (equal "aa" (get-text-property (point) 'completion--string)))
+ (previous-completion 1)
+ (should (equal "ac" (get-text-property (point) 'completion--string))))))
+
+(ert-deftest completions-header-format-test ()
+ (let ((completion-show-help nil)
+ (completions-header-format nil))
+ (completing-read-with-minibuffer-setup
+ '("aa" "ab" "ac")
+ (insert "a")
+ (minibuffer-completion-help)
+ (switch-to-completions)
+ ;; Fixed in bug#55430
+ (should (equal "aa" (get-text-property (point) 'completion--string)))
+ (next-completion 2)
+ (should (equal "ac" (get-text-property (point) 'completion--string)))
+ (previous-completion 2)
+ (should (equal "aa" (get-text-property (point) 'completion--string)))
+ ;; Fixed in bug#54374
+ (previous-completion 1)
+ (should (equal "ac" (get-text-property (point) 'completion--string)))
+ (next-completion 1)
+ (should (equal "aa" (get-text-property (point) 'completion--string)))
+ ;; Fixed in bug#55430
+ (execute-kbd-macro (kbd "C-u RET"))
+ (should (equal (minibuffer-contents) "aa")))
+ (completing-read-with-minibuffer-setup
+ '("aa" "ab" "ac")
+ ;; Fixed in bug#55289
+ (execute-kbd-macro (kbd "a M-<up> M-<down>"))
+ (should (equal (minibuffer-contents) "aa")))))
+
+(ert-deftest completions-affixation-navigation-test ()
+ (let ((completion-extra-properties
+ '(:affixation-function
+ (lambda (completions)
+ (mapcar (lambda (c)
+ (list c "prefix " " suffix"))
+ completions)))))
+ (completing-read-with-minibuffer-setup
+ '("aa" "ab" "ac")
+ (insert "a")
+ (minibuffer-completion-help)
+ (switch-to-completions)
+ (should (equal 'highlight (get-text-property (point) 'mouse-face)))
+ (should (equal "aa" (get-text-property (point) 'completion--string)))
+ (let ((completion-auto-wrap t))
+ (next-completion 3))
+ (should (equal 'highlight (get-text-property (point) 'mouse-face)))
+ (should (equal "aa" (get-text-property (point) 'completion--string)))
+ (let ((completion-auto-wrap nil))
+ (next-completion 3))
+ (should (equal 'highlight (get-text-property (point) 'mouse-face)))
+ (should (equal "ac" (get-text-property (point) 'completion--string)))
+ ;; Fixed in bug#54374
+ (goto-char (1- (point-max)))
+ (should-not (equal 'highlight (get-text-property (point) 'mouse-face)))
+ (execute-kbd-macro (kbd "C-u RET"))
+ (should (equal (minibuffer-contents) "ac")))))
+
(provide 'minibuffer-tests)
;;; minibuffer-tests.el ends here
diff --git a/test/lisp/misc-tests.el b/test/lisp/misc-tests.el
index 36a8726b885..a56feaa0495 100644
--- a/test/lisp/misc-tests.el
+++ b/test/lisp/misc-tests.el
@@ -44,7 +44,14 @@
(zap-up-to-char 1 ?c))
(with-misc-test "abcde abc123" "c123"
(goto-char (point-min))
- (zap-up-to-char 2 ?c)))
+ (zap-up-to-char 2 ?c))
+ (let ((case-fold-search t))
+ (with-misc-test "abcdeCXYZ" "cdeCXYZ"
+ (goto-char (point-min))
+ (zap-up-to-char 1 ?C))
+ (with-misc-test "abcdeCXYZ" "CXYZ"
+ (goto-char (point-min))
+ (zap-up-to-char 1 ?C 'interactive))))
(ert-deftest misc-test-upcase-char ()
(with-misc-test "abcde" "aBCDe"
@@ -73,5 +80,21 @@
(backward-to-word 3)
(should (equal (point) 1))))
+(ert-deftest misc--duplicate-line ()
+ ;; Duplicate a line (twice).
+ (with-temp-buffer
+ (insert "abc\ndefg\nh\n")
+ (goto-char 7)
+ (duplicate-line 2)
+ (should (equal (buffer-string) "abc\ndefg\ndefg\ndefg\nh\n"))
+ (should (equal (point) 7)))
+ ;; Duplicate a non-terminated line.
+ (with-temp-buffer
+ (insert "abc")
+ (goto-char 2)
+ (duplicate-line)
+ (should (equal (buffer-string) "abc\nabc\n"))
+ (should (equal (point) 2))))
+
(provide 'misc-tests)
;;; misc-tests.el ends here
diff --git a/test/lisp/mouse-tests.el b/test/lisp/mouse-tests.el
index 1cc9f64f049..03ecbc19858 100644
--- a/test/lisp/mouse-tests.el
+++ b/test/lisp/mouse-tests.el
@@ -25,6 +25,20 @@
;;; Code:
+(ert-deftest mouse-test-mouse-double-click-time ()
+ (let ((double-click-time 500))
+ (should (= (mouse-double-click-time) 500)))
+ (let ((double-click-time 0))
+ (should (= (mouse-double-click-time) 0)))
+ (let ((double-click-time -500))
+ (should (= (mouse-double-click-time) 0)))
+ (let ((double-click-time nil))
+ (should (= (mouse-double-click-time) 0)))
+ (let ((double-click-time t))
+ (should (numberp (mouse-double-click-time))))
+ (let ((double-click-time '(invalid)))
+ (should (= (mouse-double-click-time) 0))))
+
(ert-deftest bug23288-use-return-value ()
"If `mouse-on-link-p' returns a string, its first character is used."
(cl-letf ((unread-command-events '((down-mouse-1 nil 1) (mouse-1 nil 1)))
@@ -52,5 +66,167 @@ translate `mouse-1' events into `mouse-2' events."
(should (equal (mouse-position)
(cons frame (cons 0 0))))))
+(ert-deftest context-menu-map-remove-consecutive-separators ()
+ "Check that `context-menu-map' removes consecutive separators."
+ ;; Both separators after the overall prompt string.
+ (let ((context-menu-functions
+ '((lambda (menu _click)
+ (define-key-after menu [foo-item] '(menu-item "Foo" identity))
+ (define-key-after menu [separator-1] menu-bar-separator)
+ (define-key-after menu [separator-2] menu-bar-separator)
+ (define-key-after menu [bar-item] '(menu-item "Bar" identity))
+ menu))))
+ (should (equal `(keymap
+ "Context Menu"
+ (foo-item menu-item "Foo" identity)
+ (separator-1 . ,menu-bar-separator)
+ (bar-item menu-item "Bar" identity))
+ (context-menu-map))))
+ ;; Both separators before the overall prompt string.
+ (let ((context-menu-functions
+ '((lambda (menu _click)
+ (define-key menu [bar-item] '(menu-item "Bar" identity))
+ (define-key menu [separator-2] menu-bar-separator)
+ (define-key menu [separator-1] menu-bar-separator)
+ (define-key menu [foo-item] '(menu-item "Foo" identity))
+ menu))))
+ (should (equal `(keymap
+ (foo-item menu-item "Foo" identity)
+ (separator-1 . ,menu-bar-separator)
+ (bar-item menu-item "Bar" identity)
+ "Context Menu")
+ (context-menu-map))))
+ ;; First separator before and second separator after the overall
+ ;; prompt string.
+ (let ((context-menu-functions
+ '((lambda (menu _click)
+ (define-key-after menu [separator-2] menu-bar-separator)
+ (define-key-after menu [bar-item] '(menu-item "Bar" identity))
+ (define-key menu [separator-1] menu-bar-separator)
+ (define-key menu [foo-item] '(menu-item "Foo" identity))
+ menu))))
+ (should (equal `(keymap
+ (foo-item menu-item "Foo" identity)
+ (separator-1 . ,menu-bar-separator)
+ "Context Menu"
+ (bar-item menu-item "Bar" identity))
+ (context-menu-map))))
+ ;; Three consecutive separators.
+ (let ((context-menu-functions
+ '((lambda (menu _click)
+ (define-key-after menu [foo-item] '(menu-item "Foo" identity))
+ (define-key-after menu [separator-1] menu-bar-separator)
+ (define-key-after menu [separator-2] menu-bar-separator)
+ (define-key-after menu [separator-3] menu-bar-separator)
+ (define-key-after menu [bar-item] '(menu-item "Bar" identity))
+ menu))))
+ (should (equal `(keymap
+ "Context Menu"
+ (foo-item menu-item "Foo" identity)
+ (separator-1 . ,menu-bar-separator)
+ (bar-item menu-item "Bar" identity))
+ (context-menu-map)))))
+
+(ert-deftest context-menu-map-remove-separators-at-beginning-or-end ()
+ "Check that `context-menu-map' removes separators at the
+beginning or end of the menu."
+ ;; Menus with only separators.
+ (let ((test-functions
+ '(;; Separator before the overall prompt string.
+ (lambda (menu _click)
+ (define-key menu [separator] menu-bar-separator)
+ menu)
+ ;; Separator after the overall prompt string.
+ (lambda (menu _click)
+ (define-key-after menu [separator] menu-bar-separator)
+ menu)
+ ;; Begin and end separators before the overall prompt string.
+ (lambda (menu _click)
+ (define-key menu [end-separator] menu-bar-separator)
+ (define-key menu [begin-separator] menu-bar-separator)
+ menu)
+ ;; Begin and end separators after the overall prompt string.
+ (lambda (menu _click)
+ (define-key-after menu [begin-separator] menu-bar-separator)
+ (define-key-after menu [end-separator] menu-bar-separator)
+ menu)
+ ;; Begin separator before and end separator after the
+ ;; overall prompt string.
+ (lambda (menu _click)
+ (define-key menu [begin-separator] menu-bar-separator)
+ (define-key-after menu [end-separator] menu-bar-separator)
+ menu))))
+ (dolist (fun test-functions)
+ (let ((context-menu-functions (list fun)))
+ (should (equal '(keymap "Context Menu")
+ (context-menu-map))))))
+ ;; Menus with separators at beginning and/or end with a menu-item
+ ;; before the prompt string.
+ (let ((test-functions
+ '(;; Separator before the overall prompt string and the menu-item.
+ (lambda (menu _click)
+ (define-key menu [foo-item] '(menu-item "Foo" identity))
+ (define-key menu [separator] menu-bar-separator)
+ menu)
+ ;; Separator before the overall prompt string, but after
+ ;; the menu-item.
+ (lambda (menu _click)
+ (define-key menu [separator] menu-bar-separator)
+ (define-key menu [foo-item] '(menu-item "Foo" identity))
+ menu)
+ ;; Separator at the end.
+ (lambda (menu _click)
+ (define-key menu [foo-item] '(menu-item "Foo" identity))
+ (define-key-after menu [separator] menu-bar-separator)
+ menu)
+ ;; Begin separator before and end separator after the
+ ;; overall prompt string.
+ (lambda (menu _click)
+ (define-key menu [foo-item] '(menu-item "Foo" identity))
+ (define-key menu [begin-separator] menu-bar-separator)
+ (define-key-after menu [end-separator] menu-bar-separator)
+ menu))))
+ (dolist (fun test-functions)
+ (let ((context-menu-functions (list fun)))
+ (should (equal '(keymap (foo-item menu-item "Foo" identity)
+ "Context Menu")
+ (context-menu-map))))))
+ ;; Menus with separators at beginning and/or end with a menu-item
+ ;; after the prompt string.
+ (let ((test-functions
+ '(;; Separator before the overall prompt string.
+ (lambda (menu _click)
+ (define-key menu [separator] menu-bar-separator)
+ (define-key-after menu [foo-item] '(menu-item "Foo" identity))
+ menu)
+ ;; Separator after the overall prompt string, but before
+ ;; the menu-item.
+ (lambda (menu _click)
+ (define-key-after menu [separator] menu-bar-separator)
+ (define-key-after menu [foo-item] '(menu-item "Foo" identity))
+ menu)
+ ;; Separator at the end.
+ (lambda (menu _click)
+ (define-key-after menu [foo-item] '(menu-item "Foo" identity))
+ (define-key-after menu [separator] menu-bar-separator)
+ menu)
+ ;; Begin and end separators after the overall prompt string.
+ (lambda (menu _click)
+ (define-key-after menu [begin-separator] menu-bar-separator)
+ (define-key-after menu [foo-item] '(menu-item "Foo" identity))
+ (define-key-after menu [end-separator] menu-bar-separator)
+ menu)
+ ;; Begin separator before and end separator after the
+ ;; overall prompt string.
+ (lambda (menu _click)
+ (define-key menu [begin-separator] menu-bar-separator)
+ (define-key-after menu [foo-item] '(menu-item "Foo" identity))
+ (define-key-after menu [end-separator] menu-bar-separator)
+ menu))))
+ (dolist (fun test-functions)
+ (let ((context-menu-functions (list fun)))
+ (should (equal '(keymap "Context Menu"
+ (foo-item menu-item "Foo" identity))
+ (context-menu-map)))))))
;;; mouse-tests.el ends here
diff --git a/test/lisp/net/browse-url-tests.el b/test/lisp/net/browse-url-tests.el
index e0a0fec0fb9..1c993958b81 100644
--- a/test/lisp/net/browse-url-tests.el
+++ b/test/lisp/net/browse-url-tests.el
@@ -28,9 +28,10 @@
(require 'browse-url)
(require 'ert)
+(require 'ert-x)
(ert-deftest browse-url-tests-browser-kind ()
- (should (eq (browse-url--browser-kind #'browse-url-w3 "gnu.org")
+ (should (eq (browse-url--browser-kind #'browse-url-emacs "gnu.org")
'internal))
(should
(eq (browse-url--browser-kind #'browse-url-firefox "gnu.org")
@@ -72,7 +73,7 @@
(should (equal (browse-url-encode-url "\"a\" \"b\"")
"%22a%22%20%22b%22"))
(should (equal (browse-url-encode-url "(a) (b)") "%28a%29%20%28b%29"))
- (should (equal (browse-url-encode-url "a$ b$") "a%24%20b%24")))
+ (should (equal (browse-url-encode-url "a$ b$") "a$%20b$")))
(ert-deftest browse-url-tests-url-at-point ()
(with-temp-buffer
@@ -81,17 +82,19 @@
(ert-deftest browse-url-tests-file-url ()
(should (equal (browse-url-file-url "/foo") "file:///foo"))
- (should (equal (browse-url-file-url "/foo:") "ftp://foo/"))
- (should (equal (browse-url-file-url "/ftp@foo:") "ftp://foo/"))
- (should (equal (browse-url-file-url "/anonymous@foo:")
- "ftp://foo/")))
+ (when (file-remote-p "/foo:")
+ (should (equal (browse-url-file-url "/foo:") "ftp://foo/")))
+ (when (file-remote-p "/ftp@foo:")
+ (should (equal (browse-url-file-url "/ftp@foo:") "ftp://foo/")))
+ (when (file-remote-p "/anonymous@foo:")
+ (should (equal (browse-url-file-url "/anonymous@foo:")
+ "ftp://foo/"))))
(ert-deftest browse-url-tests-delete-temp-file ()
- (let ((browse-url-temp-file-name
- (make-temp-file "browse-url-tests-")))
+ (ert-with-temp-file browse-url-temp-file-name
(browse-url-delete-temp-file)
(should-not (file-exists-p browse-url-temp-file-name)))
- (let ((file (make-temp-file "browse-url-tests-")))
+ (ert-with-temp-file file
(browse-url-delete-temp-file file)
(should-not (file-exists-p file))))
diff --git a/test/lisp/net/gnutls-tests.el b/test/lisp/net/gnutls-tests.el
index f5280092c69..f14ee20a302 100644
--- a/test/lisp/net/gnutls-tests.el
+++ b/test/lisp/net/gnutls-tests.el
@@ -30,6 +30,14 @@
(require 'gnutls)
(require 'hex-util)
+(declare-function gnutls-symmetric-decrypt "gnutls.c")
+(declare-function gnutls-symmetric-encrypt "gnutls.c")
+(declare-function gnutls-hash-mac "gnutls.c")
+(declare-function gnutls-hash-digest "gnutls.c")
+(declare-function gnutls-ciphers "gnutls.c")
+(declare-function gnutls-digests "gnutls.c")
+(declare-function gnutls-macs "gnutls.c")
+
(defvar gnutls-tests-message-prefix "")
(defsubst gnutls-tests-message (format-string &rest args)
diff --git a/test/lisp/net/mailcap-resources/mailcap b/test/lisp/net/mailcap-resources/mailcap
new file mode 100644
index 00000000000..ad3f7404fda
--- /dev/null
+++ b/test/lisp/net/mailcap-resources/mailcap
@@ -0,0 +1,9 @@
+audio/ogg; mpv %s
+audio/flac; mpv %s
+audio/x-wav; aplay %s
+text/*; emacsclient -t %s
+application/pdf; acroread %s; test=false
+application/pdf; evince %s
+application/pdf; okular %s
+image/*; eog %s
+image/svg+xml; inkscape %s
diff --git a/test/lisp/net/mailcap-resources/test.test b/test/lisp/net/mailcap-resources/test.test
new file mode 100644
index 00000000000..9daeafb9864
--- /dev/null
+++ b/test/lisp/net/mailcap-resources/test.test
@@ -0,0 +1 @@
+test
diff --git a/test/lisp/net/mailcap-tests.el b/test/lisp/net/mailcap-tests.el
index 362cb22bb2f..188706fc86a 100644
--- a/test/lisp/net/mailcap-tests.el
+++ b/test/lisp/net/mailcap-tests.el
@@ -63,4 +63,74 @@
(append mailcap-tests-path-extensions
mailcap-tests-mime-extensions))))
+(defmacro with-pristine-mailcap (&rest body)
+ ;; We only want the mailcap info we define ourselves.
+ `(let (mailcap--computed-mime-data
+ mailcap-mime-data
+ mailcap-user-mime-data)
+ ;; `mailcap-mime-info' calls `mailcap-parse-mailcaps' which parses
+ ;; the system's mailcaps. We don't want that for our test.
+ (cl-letf (((symbol-function 'mailcap-parse-mailcaps) #'ignore))
+ ,@body)))
+
+(ert-deftest mailcap-parsing-and-mailcap-mime-info ()
+ (with-pristine-mailcap
+ ;; One mailcap entry has a test=false field. The shell command
+ ;; execution errors when running the tests from the Makefile
+ ;; because then HOME=/nonexistent.
+ (ert-with-temp-directory home
+ (with-environment-variables (("HOME" home))
+ ;; Now parse our resource mailcap file.
+ (mailcap-parse-mailcap (ert-resource-file "mailcap"))
+
+ ;; Assert that we get what we have defined.
+ (dolist (type '("audio/ogg" "audio/flac"))
+ (should (string= "mpv %s" (mailcap-mime-info type))))
+ (should (string= "aplay %s" (mailcap-mime-info "audio/x-wav")))
+ (should (string= "emacsclient -t %s"
+ (mailcap-mime-info "text/plain")))
+ ;; evince is chosen because acroread has test=false and okular
+ ;; comes later.
+ (should (string= "evince %s"
+ (mailcap-mime-info "application/pdf")))
+ (should (string= "inkscape %s"
+ (mailcap-mime-info "image/svg+xml")))
+ (should (string= "eog %s"
+ (mailcap-mime-info "image/jpg")))
+ ;; With REQUEST being a number, all fields of the selected entry
+ ;; should be returned.
+ (should (equal '((viewer . "evince %s")
+ (type . "application/pdf"))
+ (mailcap-mime-info "application/pdf" 1)))
+ ;; With 'all, all applicable entries should be returned.
+ (should (equal '(((viewer . "evince %s")
+ (type . "application/pdf"))
+ ((viewer . "okular %s")
+ (type . "application/pdf")))
+ (mailcap-mime-info "application/pdf" 'all)))
+ (let* ((c nil)
+ (toggle (lambda (_) (setq c (not c)))))
+ (mailcap-add "audio/ogg" "toggle %s" toggle)
+ (should (string= "toggle %s" (mailcap-mime-info "audio/ogg")))
+ ;; The test results are cached, so in order to have the test
+ ;; re-evaluated, one needs to clear the cache.
+ (setq mailcap-viewer-test-cache nil)
+ (should (string= "mpv %s" (mailcap-mime-info "audio/ogg")))
+ (setq mailcap-viewer-test-cache nil)
+ (should (string= "toggle %s" (mailcap-mime-info "audio/ogg"))))))))
+
+(defvar mailcap--test-result nil)
+(defun mailcap--test-viewer ()
+ (setq mailcap--test-result (string= (buffer-string) "test\n")))
+
+(ert-deftest mailcap-view-file ()
+ (with-pristine-mailcap
+ ;; Try using a lambda as viewer and check wether
+ ;; `mailcap-view-file' works correctly.
+ (let* ((mailcap-mime-extensions '((".test" . "test/test"))))
+ (mailcap-add "test/test" 'mailcap--test-viewer)
+ (save-window-excursion
+ (mailcap-view-file (ert-resource-file "test.test")))
+ (should mailcap--test-result))))
+
;;; mailcap-tests.el ends here
diff --git a/test/lisp/net/netrc-tests.el b/test/lisp/net/netrc-tests.el
index 22c353928c3..8e83f405bcc 100644
--- a/test/lisp/net/netrc-tests.el
+++ b/test/lisp/net/netrc-tests.el
@@ -48,7 +48,7 @@
(should (equal (netrc-credentials "ftp.example.org")
'("jrh" "*baz*")))))
-(ert-deftest test-netrc-credentials ()
+(ert-deftest test-netrc-credentials-2 ()
(let ((netrc-file (ert-resource-file "netrc-folding")))
(should
(equal (netrc-parse netrc-file)
diff --git a/test/lisp/net/network-stream-tests.el b/test/lisp/net/network-stream-tests.el
index e10d81a756a..1bdc35da195 100644
--- a/test/lisp/net/network-stream-tests.el
+++ b/test/lisp/net/network-stream-tests.el
@@ -32,6 +32,8 @@
;; it pulls in nsm, which then makes the :nowait t' tests fail unless
;; we disable the nsm, which we do by binding 'network-security-level'
+(declare-function gnutls-peer-status "gnutls.c")
+
(ert-deftest make-local-unix-server ()
(skip-unless (featurep 'make-network-process '(:family local)))
(let* ((file (make-temp-name "/tmp/server-test"))
diff --git a/test/lisp/net/ntlm-tests.el b/test/lisp/net/ntlm-tests.el
index b96228426bd..a02d97f19a8 100644
--- a/test/lisp/net/ntlm-tests.el
+++ b/test/lisp/net/ntlm-tests.el
@@ -227,13 +227,20 @@ This string will be returned from the NTLM server to the NTLM client."
;; Silence some byte-compiler warnings that occur when
;; web-server/web-server.el is not found.
+(eval-when-compile (cl-pushnew 'headers eieio--known-slot-names)
+ (cl-pushnew 'process eieio--known-slot-names))
(declare-function ws-send nil)
(declare-function ws-parse-request nil)
(declare-function ws-start nil)
(declare-function ws-stop-all nil)
-(require 'web-server nil t)
-(require 'url-http-ntlm nil t)
+(eval-and-compile
+ (push (expand-file-name "../elpa/packages/web-server/" source-directory)
+ load-path)
+ (require 'web-server nil t)
+ (push (expand-file-name "../elpa/packages/url-http-ntlm/" source-directory)
+ load-path)
+ (require 'url-http-ntlm nil t))
(defun ntlm-server-do-token (request _process)
"Process an NTLM client's REQUEST.
diff --git a/test/lisp/net/puny-resources/IdnaTestV2.txt b/test/lisp/net/puny-resources/IdnaTestV2.txt
new file mode 100644
index 00000000000..ed2f32e129f
--- /dev/null
+++ b/test/lisp/net/puny-resources/IdnaTestV2.txt
@@ -0,0 +1,6344 @@
+# IdnaTestV2.txt
+# Date: 2021-08-17, 19:34:01 GMT
+# © 2021 Unicode®, Inc.
+# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
+# For terms of use, see http://www.unicode.org/terms_of_use.html
+#
+# Unicode IDNA Compatible Preprocessing for UTS #46
+# Version: 14.0.0
+#
+# For documentation and usage, see http://www.unicode.org/reports/tr46
+#
+# Test cases for verifying UTS #46 conformance.
+#
+# FORMAT:
+#
+# This file is in UTF-8, where characters may be escaped using the \uXXXX or \x{XXXX}
+# convention where they could otherwise have a confusing display.
+# These characters include control codes and combining marks.
+#
+# Columns (c1, c2,...) are separated by semicolons.
+# Leading and trailing spaces and tabs in each column are ignored.
+# Comments are indicated with hash marks.
+#
+# Column 1: source - The source string to be tested
+# Column 2: toUnicode - The result of applying toUnicode to the source,
+# with Transitional_Processing=false.
+# A blank value means the same as the source value.
+# Column 3: toUnicodeStatus - A set of status codes, each corresponding to a particular test.
+# A blank value means [] (no errors).
+# Column 4: toAsciiN - The result of applying toASCII to the source,
+# with Transitional_Processing=false.
+# A blank value means the same as the toUnicode value.
+# Column 5: toAsciiNStatus - A set of status codes, each corresponding to a particular test.
+# A blank value means the same as the toUnicodeStatus value.
+# An explicit [] means no errors.
+# Column 6: toAsciiT - The result of applying toASCII to the source,
+# with Transitional_Processing=true.
+# A blank value means the same as the toAsciiN value.
+# Column 7: toAsciiTStatus - A set of status codes, each corresponding to a particular test.
+# A blank value means the same as the toAsciiNStatus value.
+# An explicit [] means no errors.
+#
+# The line comments currently show visible characters that have been escaped.
+#
+# CONFORMANCE:
+#
+# To test for conformance to UTS #46, an implementation will perform the toUnicode, toAsciiN, and
+# toAsciiT operations on the source string, then verify the resulting strings and relevant status
+# values.
+#
+# If the implementation converts illegal code points into U+FFFD (as per
+# https://www.unicode.org/reports/tr46/#Processing) then the string comparisons need to
+# account for that by treating U+FFFD in the actual value as a wildcard when comparing to the
+# expected value in the test file.
+#
+# A status in toUnicode, toAsciiN or toAsciiT is indicated by a value in square brackets,
+# such as "[B5 B6]". In such a case, the contents is a list of status codes based on the step
+# numbers in UTS #46 and IDNA2008, with the following formats.
+#
+# Pn for Section 4 Processing step n
+# Vn for 4.1 Validity Criteria step n
+# U1 for UseSTD3ASCIIRules
+# An for 4.2 ToASCII step n
+# Bn for Bidi (in IDNA2008)
+# Cn for ContextJ (in IDNA2008)
+# Xn for toUnicode issues (see below)
+#
+# Thus C1 = Appendix A.1. ZERO WIDTH NON-JOINER, and C2 = Appendix A.2. ZERO WIDTH JOINER.
+# (The CONTEXTO tests are optional for client software, and not tested here.)
+#
+# Implementations that allow values of particular input flags to be false would ignore
+# the corresponding status codes listed in the table below when testing for errors.
+#
+# VerifyDnsLength: P4
+# CheckHyphens: V2, V3
+# CheckBidi: V8
+# CheckJoiners: V7
+# UseSTD3ASCIIRules: U1
+#
+# Implementations may be more strict than the default settings for UTS #46.
+# In particular, an implementation conformant to IDNA2008 would disallow the input for lines
+# marked with NV8.
+#
+# Implementations need only record that there is an error: they need not reproduce the
+# precise status codes (after removing the ignored status values).
+#
+# Compatibility errors
+#
+# The special error codes X3 and X4_2 are now returned where a toASCII error code
+# was formerly being generated in toUnicode due to an empty label.
+#
+# A3 was being generated in the following cases (in addition to its normal usage).
+# • an empty label in toUnicode. In this case, it is replaced by X3.
+#
+# A4_2 was being generated in the following case (in addition to its normal usage).
+# • an empty label in V8 (CheckBidi). In this case, it is being replaced by X4_2.
+# ============================================================================================
+fass.de; ; ; ; ; ; # fass.de
+faß.de; ; ; xn--fa-hia.de; ; fass.de; # faß.de
+Faß.de; faß.de; ; xn--fa-hia.de; ; fass.de; # faß.de
+xn--fa-hia.de; faß.de; ; xn--fa-hia.de; ; ; # faß.de
+
+# BIDI TESTS
+
+àא; ; [B5, B6]; xn--0ca24w; ; ; # àא
+àא; àא; [B5, B6]; xn--0ca24w; ; ; # àא
+Àא; àא; [B5, B6]; xn--0ca24w; ; ; # àא
+Àא; àא; [B5, B6]; xn--0ca24w; ; ; # àא
+xn--0ca24w; àא; [B5, B6]; xn--0ca24w; ; ; # àא
+0à.א; ; [B1]; xn--0-sfa.xn--4db; ; ; # 0à.א
+0à.א; 0à.א; [B1]; xn--0-sfa.xn--4db; ; ; # 0à.א
+0À.א; 0à.א; [B1]; xn--0-sfa.xn--4db; ; ; # 0à.א
+0À.א; 0à.א; [B1]; xn--0-sfa.xn--4db; ; ; # 0à.א
+xn--0-sfa.xn--4db; 0à.א; [B1]; xn--0-sfa.xn--4db; ; ; # 0à.א
+à.א̈; ; ; xn--0ca.xn--ssa73l; ; ; # à.א̈
+à.א̈; à.א̈; ; xn--0ca.xn--ssa73l; ; ; # à.א̈
+À.א̈; à.א̈; ; xn--0ca.xn--ssa73l; ; ; # à.א̈
+À.א̈; à.א̈; ; xn--0ca.xn--ssa73l; ; ; # à.א̈
+xn--0ca.xn--ssa73l; à.א̈; ; xn--0ca.xn--ssa73l; ; ; # à.א̈
+à.א0٠א; ; [B4]; xn--0ca.xn--0-zhcb98c; ; ; # à.א0٠א
+à.א0٠א; à.א0٠א; [B4]; xn--0ca.xn--0-zhcb98c; ; ; # à.א0٠א
+À.א0٠א; à.א0٠א; [B4]; xn--0ca.xn--0-zhcb98c; ; ; # à.א0٠א
+À.א0٠א; à.א0٠א; [B4]; xn--0ca.xn--0-zhcb98c; ; ; # à.א0٠א
+xn--0ca.xn--0-zhcb98c; à.א0٠א; [B4]; xn--0ca.xn--0-zhcb98c; ; ; # à.א0٠א
+̈.א; ; [B1, B3, B6, V5]; xn--ssa.xn--4db; ; ; # ̈.א
+xn--ssa.xn--4db; ̈.א; [B1, B3, B6, V5]; xn--ssa.xn--4db; ; ; # ̈.א
+à.א0٠; ; [B4]; xn--0ca.xn--0-zhc74b; ; ; # à.א0٠
+à.א0٠; à.א0٠; [B4]; xn--0ca.xn--0-zhc74b; ; ; # à.א0٠
+À.א0٠; à.א0٠; [B4]; xn--0ca.xn--0-zhc74b; ; ; # à.א0٠
+À.א0٠; à.א0٠; [B4]; xn--0ca.xn--0-zhc74b; ; ; # à.א0٠
+xn--0ca.xn--0-zhc74b; à.א0٠; [B4]; xn--0ca.xn--0-zhc74b; ; ; # à.א0٠
+àˇ.א; ; [B6]; xn--0ca88g.xn--4db; ; ; # àˇ.א
+àˇ.א; àˇ.א; [B6]; xn--0ca88g.xn--4db; ; ; # àˇ.א
+Àˇ.א; àˇ.א; [B6]; xn--0ca88g.xn--4db; ; ; # àˇ.א
+Àˇ.א; àˇ.א; [B6]; xn--0ca88g.xn--4db; ; ; # àˇ.א
+xn--0ca88g.xn--4db; àˇ.א; [B6]; xn--0ca88g.xn--4db; ; ; # àˇ.א
+à̈.א; ; ; xn--0ca81i.xn--4db; ; ; # à̈.א
+à̈.א; à̈.א; ; xn--0ca81i.xn--4db; ; ; # à̈.א
+À̈.א; à̈.א; ; xn--0ca81i.xn--4db; ; ; # à̈.א
+À̈.א; à̈.א; ; xn--0ca81i.xn--4db; ; ; # à̈.א
+xn--0ca81i.xn--4db; à̈.א; ; xn--0ca81i.xn--4db; ; ; # à̈.א
+
+# CONTEXT TESTS
+
+a‌b; ; [C1]; xn--ab-j1t; ; ab; [] # ab
+A‌B; a‌b; [C1]; xn--ab-j1t; ; ab; [] # ab
+A‌b; a‌b; [C1]; xn--ab-j1t; ; ab; [] # ab
+ab; ; ; ; ; ; # ab
+xn--ab-j1t; a‌b; [C1]; xn--ab-j1t; ; ; # ab
+a्‌b; ; ; xn--ab-fsf604u; ; xn--ab-fsf; # a्b
+A्‌B; a्‌b; ; xn--ab-fsf604u; ; xn--ab-fsf; # a्b
+A्‌b; a्‌b; ; xn--ab-fsf604u; ; xn--ab-fsf; # a्b
+xn--ab-fsf; a्b; ; xn--ab-fsf; ; ; # a्b
+a्b; ; ; xn--ab-fsf; ; ; # a्b
+A्B; a्b; ; xn--ab-fsf; ; ; # a्b
+A्b; a्b; ; xn--ab-fsf; ; ; # a्b
+xn--ab-fsf604u; a्‌b; ; xn--ab-fsf604u; ; ; # a्b
+̈‌̈بb; ; [B1, C1, V5]; xn--b-bcba413a2w8b; ; xn--b-bcba413a; [B1, V5] # ̈̈بb
+̈‌̈بB; ̈‌̈بb; [B1, C1, V5]; xn--b-bcba413a2w8b; ; xn--b-bcba413a; [B1, V5] # ̈̈بb
+xn--b-bcba413a; ̈̈بb; [B1, V5]; xn--b-bcba413a; ; ; # ̈̈بb
+xn--b-bcba413a2w8b; ̈‌̈بb; [B1, C1, V5]; xn--b-bcba413a2w8b; ; ; # ̈̈بb
+aب̈‌̈; ; [B5, B6, C1]; xn--a-ccba213a5w8b; ; xn--a-ccba213a; [B5, B6] # aب̈̈
+Aب̈‌̈; aب̈‌̈; [B5, B6, C1]; xn--a-ccba213a5w8b; ; xn--a-ccba213a; [B5, B6] # aب̈̈
+xn--a-ccba213a; aب̈̈; [B5, B6]; xn--a-ccba213a; ; ; # aب̈̈
+xn--a-ccba213a5w8b; aب̈‌̈; [B5, B6, C1]; xn--a-ccba213a5w8b; ; ; # aب̈̈
+aب̈‌̈بb; ; [B5]; xn--ab-uuba211bca8057b; ; xn--ab-uuba211bca; # aب̈̈بb
+Aب̈‌̈بB; aب̈‌̈بb; [B5]; xn--ab-uuba211bca8057b; ; xn--ab-uuba211bca; # aب̈̈بb
+Aب̈‌̈بb; aب̈‌̈بb; [B5]; xn--ab-uuba211bca8057b; ; xn--ab-uuba211bca; # aب̈̈بb
+xn--ab-uuba211bca; aب̈̈بb; [B5]; xn--ab-uuba211bca; ; ; # aب̈̈بb
+xn--ab-uuba211bca8057b; aب̈‌̈بb; [B5]; xn--ab-uuba211bca8057b; ; ; # aب̈̈بb
+a‍b; ; [C2]; xn--ab-m1t; ; ab; [] # ab
+A‍B; a‍b; [C2]; xn--ab-m1t; ; ab; [] # ab
+A‍b; a‍b; [C2]; xn--ab-m1t; ; ab; [] # ab
+xn--ab-m1t; a‍b; [C2]; xn--ab-m1t; ; ; # ab
+a्‍b; ; ; xn--ab-fsf014u; ; xn--ab-fsf; # a्b
+A्‍B; a्‍b; ; xn--ab-fsf014u; ; xn--ab-fsf; # a्b
+A्‍b; a्‍b; ; xn--ab-fsf014u; ; xn--ab-fsf; # a्b
+xn--ab-fsf014u; a्‍b; ; xn--ab-fsf014u; ; ; # a्b
+̈‍̈بb; ; [B1, C2, V5]; xn--b-bcba413a7w8b; ; xn--b-bcba413a; [B1, V5] # ̈̈بb
+̈‍̈بB; ̈‍̈بb; [B1, C2, V5]; xn--b-bcba413a7w8b; ; xn--b-bcba413a; [B1, V5] # ̈̈بb
+xn--b-bcba413a7w8b; ̈‍̈بb; [B1, C2, V5]; xn--b-bcba413a7w8b; ; ; # ̈̈بb
+aب̈‍̈; ; [B5, B6, C2]; xn--a-ccba213abx8b; ; xn--a-ccba213a; [B5, B6] # aب̈̈
+Aب̈‍̈; aب̈‍̈; [B5, B6, C2]; xn--a-ccba213abx8b; ; xn--a-ccba213a; [B5, B6] # aب̈̈
+xn--a-ccba213abx8b; aب̈‍̈; [B5, B6, C2]; xn--a-ccba213abx8b; ; ; # aب̈̈
+aب̈‍̈بb; ; [B5, C2]; xn--ab-uuba211bca5157b; ; xn--ab-uuba211bca; [B5] # aب̈̈بb
+Aب̈‍̈بB; aب̈‍̈بb; [B5, C2]; xn--ab-uuba211bca5157b; ; xn--ab-uuba211bca; [B5] # aب̈̈بb
+Aب̈‍̈بb; aب̈‍̈بb; [B5, C2]; xn--ab-uuba211bca5157b; ; xn--ab-uuba211bca; [B5] # aب̈̈بb
+xn--ab-uuba211bca5157b; aب̈‍̈بb; [B5, C2]; xn--ab-uuba211bca5157b; ; ; # aب̈̈بb
+
+# SELECTED TESTS
+
+¡; ; ; xn--7a; ; ; # ¡
+xn--7a; ¡; ; xn--7a; ; ; # ¡
+᧚; ; ; xn--pkf; ; ; # ᧚
+xn--pkf; ᧚; ; xn--pkf; ; ; # ᧚
+。; .; [X4_2]; ; [A4_2]; ; # .
+.; ; [X4_2]; ; [A4_2]; ; # .
+ꭠ; ; ; xn--3y9a; ; ; # ꭠ
+xn--3y9a; ꭠ; ; xn--3y9a; ; ; # ꭠ
+1234567890ä1234567890123456789012345678901234567890123456; ; ; xn--12345678901234567890123456789012345678901234567890123456-fxe; [A4_2]; ; # 1234567890ä1234567890123456789012345678901234567890123456
+1234567890ä1234567890123456789012345678901234567890123456; 1234567890ä1234567890123456789012345678901234567890123456; ; xn--12345678901234567890123456789012345678901234567890123456-fxe; [A4_2]; ; # 1234567890ä1234567890123456789012345678901234567890123456
+1234567890Ä1234567890123456789012345678901234567890123456; 1234567890ä1234567890123456789012345678901234567890123456; ; xn--12345678901234567890123456789012345678901234567890123456-fxe; [A4_2]; ; # 1234567890ä1234567890123456789012345678901234567890123456
+1234567890Ä1234567890123456789012345678901234567890123456; 1234567890ä1234567890123456789012345678901234567890123456; ; xn--12345678901234567890123456789012345678901234567890123456-fxe; [A4_2]; ; # 1234567890ä1234567890123456789012345678901234567890123456
+xn--12345678901234567890123456789012345678901234567890123456-fxe; 1234567890ä1234567890123456789012345678901234567890123456; ; xn--12345678901234567890123456789012345678901234567890123456-fxe; [A4_2]; ; # 1234567890ä1234567890123456789012345678901234567890123456
+www.eXample.cOm; www.example.com; ; ; ; ; # www.example.com
+Bücher.de; bücher.de; ; xn--bcher-kva.de; ; ; # bücher.de
+Bücher.de; bücher.de; ; xn--bcher-kva.de; ; ; # bücher.de
+bücher.de; bücher.de; ; xn--bcher-kva.de; ; ; # bücher.de
+bücher.de; ; ; xn--bcher-kva.de; ; ; # bücher.de
+BÜCHER.DE; bücher.de; ; xn--bcher-kva.de; ; ; # bücher.de
+BÜCHER.DE; bücher.de; ; xn--bcher-kva.de; ; ; # bücher.de
+xn--bcher-kva.de; bücher.de; ; xn--bcher-kva.de; ; ; # bücher.de
+ÖBB; öbb; ; xn--bb-eka; ; ; # öbb
+ÖBB; öbb; ; xn--bb-eka; ; ; # öbb
+öbb; öbb; ; xn--bb-eka; ; ; # öbb
+öbb; ; ; xn--bb-eka; ; ; # öbb
+Öbb; öbb; ; xn--bb-eka; ; ; # öbb
+Öbb; öbb; ; xn--bb-eka; ; ; # öbb
+xn--bb-eka; öbb; ; xn--bb-eka; ; ; # öbb
+βόλος.com; ; ; xn--nxasmm1c.com; ; xn--nxasmq6b.com; # βόλος.com
+βόλος.com; βόλος.com; ; xn--nxasmm1c.com; ; xn--nxasmq6b.com; # βόλος.com
+ΒΌΛΟΣ.COM; βόλοσ.com; ; xn--nxasmq6b.com; ; ; # βόλοσ.com
+ΒΌΛΟΣ.COM; βόλοσ.com; ; xn--nxasmq6b.com; ; ; # βόλοσ.com
+βόλοσ.com; ; ; xn--nxasmq6b.com; ; ; # βόλοσ.com
+βόλοσ.com; βόλοσ.com; ; xn--nxasmq6b.com; ; ; # βόλοσ.com
+Βόλοσ.com; βόλοσ.com; ; xn--nxasmq6b.com; ; ; # βόλοσ.com
+Βόλοσ.com; βόλοσ.com; ; xn--nxasmq6b.com; ; ; # βόλοσ.com
+xn--nxasmq6b.com; βόλοσ.com; ; xn--nxasmq6b.com; ; ; # βόλοσ.com
+Βόλος.com; βόλος.com; ; xn--nxasmm1c.com; ; xn--nxasmq6b.com; # βόλος.com
+Βόλος.com; βόλος.com; ; xn--nxasmm1c.com; ; xn--nxasmq6b.com; # βόλος.com
+xn--nxasmm1c.com; βόλος.com; ; xn--nxasmm1c.com; ; ; # βόλος.com
+xn--nxasmm1c; βόλος; ; xn--nxasmm1c; ; ; # βόλος
+βόλος; ; ; xn--nxasmm1c; ; xn--nxasmq6b; # βόλος
+βόλος; βόλος; ; xn--nxasmm1c; ; xn--nxasmq6b; # βόλος
+ΒΌΛΟΣ; βόλοσ; ; xn--nxasmq6b; ; ; # βόλοσ
+ΒΌΛΟΣ; βόλοσ; ; xn--nxasmq6b; ; ; # βόλοσ
+βόλοσ; ; ; xn--nxasmq6b; ; ; # βόλοσ
+βόλοσ; βόλοσ; ; xn--nxasmq6b; ; ; # βόλοσ
+Βόλοσ; βόλοσ; ; xn--nxasmq6b; ; ; # βόλοσ
+Βόλοσ; βόλοσ; ; xn--nxasmq6b; ; ; # βόλοσ
+xn--nxasmq6b; βόλοσ; ; xn--nxasmq6b; ; ; # βόλοσ
+Βόλος; βόλος; ; xn--nxasmm1c; ; xn--nxasmq6b; # βόλος
+Βόλος; βόλος; ; xn--nxasmm1c; ; xn--nxasmq6b; # βόλος
+www.ශ්‍රී.com; ; ; www.xn--10cl1a0b660p.com; ; www.xn--10cl1a0b.com; # www.ශ්රී.com
+WWW.ශ්‍රී.COM; www.ශ්‍රී.com; ; www.xn--10cl1a0b660p.com; ; www.xn--10cl1a0b.com; # www.ශ්රී.com
+Www.ශ්‍රී.com; www.ශ්‍රී.com; ; www.xn--10cl1a0b660p.com; ; www.xn--10cl1a0b.com; # www.ශ්රී.com
+www.xn--10cl1a0b.com; www.ශ්රී.com; ; www.xn--10cl1a0b.com; ; ; # www.ශ්රී.com
+www.ශ්රී.com; ; ; www.xn--10cl1a0b.com; ; ; # www.ශ්රී.com
+WWW.ශ්රී.COM; www.ශ්රී.com; ; www.xn--10cl1a0b.com; ; ; # www.ශ්රී.com
+Www.ශ්රී.com; www.ශ්රී.com; ; www.xn--10cl1a0b.com; ; ; # www.ශ්රී.com
+www.xn--10cl1a0b660p.com; www.ශ්‍රී.com; ; www.xn--10cl1a0b660p.com; ; ; # www.ශ්රී.com
+نامه‌ای; ; ; xn--mgba3gch31f060k; ; xn--mgba3gch31f; # نامهای
+xn--mgba3gch31f; نامهای; ; xn--mgba3gch31f; ; ; # نامهای
+نامهای; ; ; xn--mgba3gch31f; ; ; # نامهای
+xn--mgba3gch31f060k; نامه‌ای; ; xn--mgba3gch31f060k; ; ; # نامهای
+xn--mgba3gch31f060k.com; نامه‌ای.com; ; xn--mgba3gch31f060k.com; ; ; # نامهای.com
+نامه‌ای.com; ; ; xn--mgba3gch31f060k.com; ; xn--mgba3gch31f.com; # نامهای.com
+نامه‌ای.COM; نامه‌ای.com; ; xn--mgba3gch31f060k.com; ; xn--mgba3gch31f.com; # نامهای.com
+xn--mgba3gch31f.com; نامهای.com; ; xn--mgba3gch31f.com; ; ; # نامهای.com
+نامهای.com; ; ; xn--mgba3gch31f.com; ; ; # نامهای.com
+نامهای.COM; نامهای.com; ; xn--mgba3gch31f.com; ; ; # نامهای.com
+a.b.c。d。; a.b.c.d.; ; ; ; ; # a.b.c.d.
+a.b.c。d。; a.b.c.d.; ; ; ; ; # a.b.c.d.
+A.B.C。D。; a.b.c.d.; ; ; ; ; # a.b.c.d.
+A.b.c。D。; a.b.c.d.; ; ; ; ; # a.b.c.d.
+a.b.c.d.; ; ; ; ; ; # a.b.c.d.
+A.B.C。D。; a.b.c.d.; ; ; ; ; # a.b.c.d.
+A.b.c。D。; a.b.c.d.; ; ; ; ; # a.b.c.d.
+Ü.xn--tda; ü.ü; ; xn--tda.xn--tda; ; ; # ü.ü
+Ü.xn--tda; ü.ü; ; xn--tda.xn--tda; ; ; # ü.ü
+ü.xn--tda; ü.ü; ; xn--tda.xn--tda; ; ; # ü.ü
+ü.xn--tda; ü.ü; ; xn--tda.xn--tda; ; ; # ü.ü
+Ü.XN--TDA; ü.ü; ; xn--tda.xn--tda; ; ; # ü.ü
+Ü.XN--TDA; ü.ü; ; xn--tda.xn--tda; ; ; # ü.ü
+Ü.xn--Tda; ü.ü; ; xn--tda.xn--tda; ; ; # ü.ü
+Ü.xn--Tda; ü.ü; ; xn--tda.xn--tda; ; ; # ü.ü
+xn--tda.xn--tda; ü.ü; ; xn--tda.xn--tda; ; ; # ü.ü
+ü.ü; ; ; xn--tda.xn--tda; ; ; # ü.ü
+ü.ü; ü.ü; ; xn--tda.xn--tda; ; ; # ü.ü
+Ü.Ü; ü.ü; ; xn--tda.xn--tda; ; ; # ü.ü
+Ü.Ü; ü.ü; ; xn--tda.xn--tda; ; ; # ü.ü
+Ü.ü; ü.ü; ; xn--tda.xn--tda; ; ; # ü.ü
+Ü.ü; ü.ü; ; xn--tda.xn--tda; ; ; # ü.ü
+xn--u-ccb; ü; [V1]; xn--u-ccb; ; ; # ü
+a⒈com; ; [P1, V6]; xn--acom-0w1b; ; ; # a⒈com
+a1.com; ; ; ; ; ; # a1.com
+A⒈COM; a⒈com; [P1, V6]; xn--acom-0w1b; ; ; # a⒈com
+A⒈Com; a⒈com; [P1, V6]; xn--acom-0w1b; ; ; # a⒈com
+xn--acom-0w1b; a⒈com; [V6]; xn--acom-0w1b; ; ; # a⒈com
+xn--a-ecp.ru; a⒈.ru; [V6]; xn--a-ecp.ru; ; ; # a⒈.ru
+xn--0.pt; ; [P4]; ; ; ; # xn--0.pt
+xn--a.pt; €.pt; [V6]; xn--a.pt; ; ; # .pt
+xn--a-Ä.pt; xn--a-ä.pt; [P4]; xn--xn--a--gua.pt; ; ; # xn--a-ä.pt
+xn--a-Ä.pt; xn--a-ä.pt; [P4]; xn--xn--a--gua.pt; ; ; # xn--a-ä.pt
+xn--a-ä.pt; xn--a-ä.pt; [P4]; xn--xn--a--gua.pt; ; ; # xn--a-ä.pt
+xn--a-ä.pt; ; [P4]; xn--xn--a--gua.pt; ; ; # xn--a-ä.pt
+XN--A-Ä.PT; xn--a-ä.pt; [P4]; xn--xn--a--gua.pt; ; ; # xn--a-ä.pt
+XN--A-Ä.PT; xn--a-ä.pt; [P4]; xn--xn--a--gua.pt; ; ; # xn--a-ä.pt
+Xn--A-Ä.pt; xn--a-ä.pt; [P4]; xn--xn--a--gua.pt; ; ; # xn--a-ä.pt
+Xn--A-Ä.pt; xn--a-ä.pt; [P4]; xn--xn--a--gua.pt; ; ; # xn--a-ä.pt
+xn--xn--a--gua.pt; xn--a-ä.pt; [V2]; xn--xn--a--gua.pt; ; ; # xn--a-ä.pt
+日本語。JP; 日本語.jp; ; xn--wgv71a119e.jp; ; ; # 日本語.jp
+日本語。JP; 日本語.jp; ; xn--wgv71a119e.jp; ; ; # 日本語.jp
+日本語。jp; 日本語.jp; ; xn--wgv71a119e.jp; ; ; # 日本語.jp
+日本語。Jp; 日本語.jp; ; xn--wgv71a119e.jp; ; ; # 日本語.jp
+xn--wgv71a119e.jp; 日本語.jp; ; xn--wgv71a119e.jp; ; ; # 日本語.jp
+日本語.jp; ; ; xn--wgv71a119e.jp; ; ; # 日本語.jp
+日本語.JP; 日本語.jp; ; xn--wgv71a119e.jp; ; ; # 日本語.jp
+日本語.Jp; 日本語.jp; ; xn--wgv71a119e.jp; ; ; # 日本語.jp
+日本語。jp; 日本語.jp; ; xn--wgv71a119e.jp; ; ; # 日本語.jp
+日本語。Jp; 日本語.jp; ; xn--wgv71a119e.jp; ; ; # 日本語.jp
+☕; ; ; xn--53h; ; ; # ☕
+xn--53h; ☕; ; xn--53h; ; ; # ☕
+1.aß‌‍b‌‍cßßßßdςσßßßßßßßßeßßßßßßßßßßxßßßßßßßßßßyßßßßßßßß̂ßz; ; [C1, C2]; 1.xn--abcdexyz-qyacaaabaaaaaaabaaaaaaaaabaaaaaaaaabaaaaaaaa010ze2isb1140zba8cc; [C1, C2, A4_2]; 1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa; [A4_2] # 1.aßbcßßßßdςσßßßßßßßßeßßßßßßßßßßxßßßßßßßßßßyßßßßßßßß̂ßz
+1.ASS‌‍B‌‍CSSSSSSSSDΣΣSSSSSSSSSSSSSSSSESSSSSSSSSSSSSSSSSSSSXSSSSSSSSSSSSSSSSSSSSYSSSSSSSSSSSSSSSŜSSZ; 1.ass‌‍b‌‍cssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz; [C1, C2]; 1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa69989dba9gc; [C1, C2, A4_2]; 1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa; [A4_2] # 1.assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz
+1.ASS‌‍B‌‍CSSSSSSSSDΣΣSSSSSSSSSSSSSSSSESSSSSSSSSSSSSSSSSSSSXSSSSSSSSSSSSSSSSSSSSYSSSSSSSSSSSSSSSŜSSZ; 1.ass‌‍b‌‍cssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz; [C1, C2]; 1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa69989dba9gc; [C1, C2, A4_2]; 1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa; [A4_2] # 1.assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz
+1.ass‌‍b‌‍cssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz; ; [C1, C2]; 1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa69989dba9gc; [C1, C2, A4_2]; 1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa; [A4_2] # 1.assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz
+1.ass‌‍b‌‍cssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz; 1.ass‌‍b‌‍cssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz; [C1, C2]; 1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa69989dba9gc; [C1, C2, A4_2]; 1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa; [A4_2] # 1.assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz
+1.Ass‌‍b‌‍cssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz; 1.ass‌‍b‌‍cssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz; [C1, C2]; 1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa69989dba9gc; [C1, C2, A4_2]; 1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa; [A4_2] # 1.assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz
+1.Ass‌‍b‌‍cssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz; 1.ass‌‍b‌‍cssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz; [C1, C2]; 1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa69989dba9gc; [C1, C2, A4_2]; 1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa; [A4_2] # 1.assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz
+1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa; 1.assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz; ; 1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa; [A4_2]; ; # 1.assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz
+1.assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz; ; ; 1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa; [A4_2]; ; # 1.assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz
+1.assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz; 1.assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz; ; 1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa; [A4_2]; ; # 1.assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz
+1.ASSBCSSSSSSSSDΣΣSSSSSSSSSSSSSSSSESSSSSSSSSSSSSSSSSSSSXSSSSSSSSSSSSSSSSSSSSYSSSSSSSSSSSSSSSŜSSZ; 1.assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz; ; 1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa; [A4_2]; ; # 1.assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz
+1.ASSBCSSSSSSSSDΣΣSSSSSSSSSSSSSSSSESSSSSSSSSSSSSSSSSSSSXSSSSSSSSSSSSSSSSSSSSYSSSSSSSSSSSSSSSŜSSZ; 1.assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz; ; 1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa; [A4_2]; ; # 1.assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz
+1.Assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz; 1.assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz; ; 1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa; [A4_2]; ; # 1.assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz
+1.Assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz; 1.assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz; ; 1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa; [A4_2]; ; # 1.assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz
+1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa69989dba9gc; 1.ass‌‍b‌‍cssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz; [C1, C2]; 1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa69989dba9gc; [C1, C2, A4_2]; ; # 1.assbcssssssssdσσssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssŝssz
+1.Aß‌‍b‌‍cßßßßdςσßßßßßßßßeßßßßßßßßßßxßßßßßßßßßßyßßßßßßßß̂ßz; 1.aß‌‍b‌‍cßßßßdςσßßßßßßßßeßßßßßßßßßßxßßßßßßßßßßyßßßßßßßß̂ßz; [C1, C2]; 1.xn--abcdexyz-qyacaaabaaaaaaabaaaaaaaaabaaaaaaaaabaaaaaaaa010ze2isb1140zba8cc; [C1, C2, A4_2]; 1.xn--assbcssssssssdssssssssssssssssessssssssssssssssssssxssssssssssssssssssssysssssssssssssssssz-pxq1419aa; [A4_2] # 1.aßbcßßßßdςσßßßßßßßßeßßßßßßßßßßxßßßßßßßßßßyßßßßßßßß̂ßz
+1.xn--abcdexyz-qyacaaabaaaaaaabaaaaaaaaabaaaaaaaaabaaaaaaaa010ze2isb1140zba8cc; 1.aß‌‍b‌‍cßßßßdςσßßßßßßßßeßßßßßßßßßßxßßßßßßßßßßyßßßßßßßß̂ßz; [C1, C2]; 1.xn--abcdexyz-qyacaaabaaaaaaabaaaaaaaaabaaaaaaaaabaaaaaaaa010ze2isb1140zba8cc; [C1, C2, A4_2]; ; # 1.aßbcßßßßdςσßßßßßßßßeßßßßßßßßßßxßßßßßßßßßßyßßßßßßßß̂ßz
+‌x‍n‌-‍-bß; ; [C1, C2]; xn--xn--b-pqa5796ccahd; ; xn--bss; [] # xn--bß
+‌X‍N‌-‍-BSS; ‌x‍n‌-‍-bss; [C1, C2]; xn--xn--bss-7z6ccid; ; xn--bss; [] # xn--bss
+‌x‍n‌-‍-bss; ; [C1, C2]; xn--xn--bss-7z6ccid; ; xn--bss; [] # xn--bss
+‌X‍n‌-‍-Bss; ‌x‍n‌-‍-bss; [C1, C2]; xn--xn--bss-7z6ccid; ; xn--bss; [] # xn--bss
+xn--bss; 夙; ; xn--bss; ; ; # 夙
+夙; ; ; xn--bss; ; ; # 夙
+xn--xn--bss-7z6ccid; ‌x‍n‌-‍-bss; [C1, C2]; xn--xn--bss-7z6ccid; ; ; # xn--bss
+‌X‍n‌-‍-Bß; ‌x‍n‌-‍-bß; [C1, C2]; xn--xn--b-pqa5796ccahd; ; xn--bss; [] # xn--bß
+xn--xn--b-pqa5796ccahd; ‌x‍n‌-‍-bß; [C1, C2]; xn--xn--b-pqa5796ccahd; ; ; # xn--bß
+ˣ͏ℕ​﹣­-᠌ℬ︀ſ⁤𝔰󠇯ffl; 夡夞夜夙; ; xn--bssffl; ; ; # 夡夞夜夙
+x͏N​-­-᠌B︀s⁤s󠇯ffl; 夡夞夜夙; ; xn--bssffl; ; ; # 夡夞夜夙
+x͏n​-­-᠌b︀s⁤s󠇯ffl; 夡夞夜夙; ; xn--bssffl; ; ; # 夡夞夜夙
+X͏N​-­-᠌B︀S⁤S󠇯FFL; 夡夞夜夙; ; xn--bssffl; ; ; # 夡夞夜夙
+X͏n​-­-᠌B︀s⁤s󠇯ffl; 夡夞夜夙; ; xn--bssffl; ; ; # 夡夞夜夙
+xn--bssffl; 夡夞夜夙; ; xn--bssffl; ; ; # 夡夞夜夙
+夡夞夜夙; ; ; xn--bssffl; ; ; # 夡夞夜夙
+ˣ͏ℕ​﹣­-᠌ℬ︀S⁤𝔰󠇯FFL; 夡夞夜夙; ; xn--bssffl; ; ; # 夡夞夜夙
+x͏N​-­-᠌B︀S⁤s󠇯FFL; 夡夞夜夙; ; xn--bssffl; ; ; # 夡夞夜夙
+ˣ͏ℕ​﹣­-᠌ℬ︀s⁤𝔰󠇯ffl; 夡夞夜夙; ; xn--bssffl; ; ; # 夡夞夜夙
+123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; ; ; ; ; ; # 123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901
+123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.; ; ; ; ; ; # 123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.
+123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012; ; ; ; [A4_1]; ; # 123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012
+123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901234.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890; ; ; ; [A4_2]; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901234.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890
+123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901234.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890.; ; ; ; [A4_2]; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901234.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890.
+123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901234.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; ; ; ; [A4_1, A4_2]; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901234.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901
+ä1234567890123456789012345678901234567890123456789012345; ; ; xn--1234567890123456789012345678901234567890123456789012345-9te; ; ; # ä1234567890123456789012345678901234567890123456789012345
+ä1234567890123456789012345678901234567890123456789012345; ä1234567890123456789012345678901234567890123456789012345; ; xn--1234567890123456789012345678901234567890123456789012345-9te; ; ; # ä1234567890123456789012345678901234567890123456789012345
+Ä1234567890123456789012345678901234567890123456789012345; ä1234567890123456789012345678901234567890123456789012345; ; xn--1234567890123456789012345678901234567890123456789012345-9te; ; ; # ä1234567890123456789012345678901234567890123456789012345
+Ä1234567890123456789012345678901234567890123456789012345; ä1234567890123456789012345678901234567890123456789012345; ; xn--1234567890123456789012345678901234567890123456789012345-9te; ; ; # ä1234567890123456789012345678901234567890123456789012345
+xn--1234567890123456789012345678901234567890123456789012345-9te; ä1234567890123456789012345678901234567890123456789012345; ; xn--1234567890123456789012345678901234567890123456789012345-9te; ; ; # ä1234567890123456789012345678901234567890123456789012345
+123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; ; ; 123456789012345678901234567890123456789012345678901234567890123.xn--1234567890123456789012345678901234567890123456789012345-kue.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; ; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901
+123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; ; 123456789012345678901234567890123456789012345678901234567890123.xn--1234567890123456789012345678901234567890123456789012345-kue.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; ; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901
+123456789012345678901234567890123456789012345678901234567890123.1234567890Ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; ; 123456789012345678901234567890123456789012345678901234567890123.xn--1234567890123456789012345678901234567890123456789012345-kue.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; ; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901
+123456789012345678901234567890123456789012345678901234567890123.1234567890Ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; ; 123456789012345678901234567890123456789012345678901234567890123.xn--1234567890123456789012345678901234567890123456789012345-kue.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; ; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901
+123456789012345678901234567890123456789012345678901234567890123.xn--1234567890123456789012345678901234567890123456789012345-kue.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; ; 123456789012345678901234567890123456789012345678901234567890123.xn--1234567890123456789012345678901234567890123456789012345-kue.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; ; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901
+123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.; ; ; 123456789012345678901234567890123456789012345678901234567890123.xn--1234567890123456789012345678901234567890123456789012345-kue.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.; ; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.
+123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.; ; 123456789012345678901234567890123456789012345678901234567890123.xn--1234567890123456789012345678901234567890123456789012345-kue.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.; ; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.
+123456789012345678901234567890123456789012345678901234567890123.1234567890Ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.; ; 123456789012345678901234567890123456789012345678901234567890123.xn--1234567890123456789012345678901234567890123456789012345-kue.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.; ; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.
+123456789012345678901234567890123456789012345678901234567890123.1234567890Ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.; ; 123456789012345678901234567890123456789012345678901234567890123.xn--1234567890123456789012345678901234567890123456789012345-kue.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.; ; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.
+123456789012345678901234567890123456789012345678901234567890123.xn--1234567890123456789012345678901234567890123456789012345-kue.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.; ; 123456789012345678901234567890123456789012345678901234567890123.xn--1234567890123456789012345678901234567890123456789012345-kue.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.; ; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.
+123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012; ; ; 123456789012345678901234567890123456789012345678901234567890123.xn--1234567890123456789012345678901234567890123456789012345-kue.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012; [A4_1]; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012
+123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012; ; 123456789012345678901234567890123456789012345678901234567890123.xn--1234567890123456789012345678901234567890123456789012345-kue.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012; [A4_1]; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012
+123456789012345678901234567890123456789012345678901234567890123.1234567890Ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012; ; 123456789012345678901234567890123456789012345678901234567890123.xn--1234567890123456789012345678901234567890123456789012345-kue.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012; [A4_1]; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012
+123456789012345678901234567890123456789012345678901234567890123.1234567890Ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012; ; 123456789012345678901234567890123456789012345678901234567890123.xn--1234567890123456789012345678901234567890123456789012345-kue.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012; [A4_1]; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012
+123456789012345678901234567890123456789012345678901234567890123.xn--1234567890123456789012345678901234567890123456789012345-kue.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012; ; 123456789012345678901234567890123456789012345678901234567890123.xn--1234567890123456789012345678901234567890123456789012345-kue.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012; [A4_1]; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä123456789012345678901234567890123456789012345.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012
+123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890; ; ; 123456789012345678901234567890123456789012345678901234567890123.xn--12345678901234567890123456789012345678901234567890123456-fxe.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890; [A4_2]; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890
+123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890; ; 123456789012345678901234567890123456789012345678901234567890123.xn--12345678901234567890123456789012345678901234567890123456-fxe.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890; [A4_2]; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890
+123456789012345678901234567890123456789012345678901234567890123.1234567890Ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890; ; 123456789012345678901234567890123456789012345678901234567890123.xn--12345678901234567890123456789012345678901234567890123456-fxe.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890; [A4_2]; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890
+123456789012345678901234567890123456789012345678901234567890123.1234567890Ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890; ; 123456789012345678901234567890123456789012345678901234567890123.xn--12345678901234567890123456789012345678901234567890123456-fxe.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890; [A4_2]; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890
+123456789012345678901234567890123456789012345678901234567890123.xn--12345678901234567890123456789012345678901234567890123456-fxe.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890; ; 123456789012345678901234567890123456789012345678901234567890123.xn--12345678901234567890123456789012345678901234567890123456-fxe.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890; [A4_2]; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890
+123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890.; ; ; 123456789012345678901234567890123456789012345678901234567890123.xn--12345678901234567890123456789012345678901234567890123456-fxe.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890.; [A4_2]; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890.
+123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890.; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890.; ; 123456789012345678901234567890123456789012345678901234567890123.xn--12345678901234567890123456789012345678901234567890123456-fxe.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890.; [A4_2]; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890.
+123456789012345678901234567890123456789012345678901234567890123.1234567890Ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890.; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890.; ; 123456789012345678901234567890123456789012345678901234567890123.xn--12345678901234567890123456789012345678901234567890123456-fxe.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890.; [A4_2]; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890.
+123456789012345678901234567890123456789012345678901234567890123.1234567890Ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890.; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890.; ; 123456789012345678901234567890123456789012345678901234567890123.xn--12345678901234567890123456789012345678901234567890123456-fxe.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890.; [A4_2]; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890.
+123456789012345678901234567890123456789012345678901234567890123.xn--12345678901234567890123456789012345678901234567890123456-fxe.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890.; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890.; ; 123456789012345678901234567890123456789012345678901234567890123.xn--12345678901234567890123456789012345678901234567890123456-fxe.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890.; [A4_2]; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890.
+123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; ; ; 123456789012345678901234567890123456789012345678901234567890123.xn--12345678901234567890123456789012345678901234567890123456-fxe.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; [A4_1, A4_2]; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901
+123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; ; 123456789012345678901234567890123456789012345678901234567890123.xn--12345678901234567890123456789012345678901234567890123456-fxe.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; [A4_1, A4_2]; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901
+123456789012345678901234567890123456789012345678901234567890123.1234567890Ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; ; 123456789012345678901234567890123456789012345678901234567890123.xn--12345678901234567890123456789012345678901234567890123456-fxe.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; [A4_1, A4_2]; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901
+123456789012345678901234567890123456789012345678901234567890123.1234567890Ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; ; 123456789012345678901234567890123456789012345678901234567890123.xn--12345678901234567890123456789012345678901234567890123456-fxe.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; [A4_1, A4_2]; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901
+123456789012345678901234567890123456789012345678901234567890123.xn--12345678901234567890123456789012345678901234567890123456-fxe.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; ; 123456789012345678901234567890123456789012345678901234567890123.xn--12345678901234567890123456789012345678901234567890123456-fxe.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901; [A4_1, A4_2]; ; # 123456789012345678901234567890123456789012345678901234567890123.1234567890ä1234567890123456789012345678901234567890123456.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901
+a.b..-q--a-.e; ; [V2, V3, X4_2]; ; [V2, V3, A4_2]; ; # a.b..-q--a-.e
+a.b..-q--ä-.e; ; [V2, V3, X4_2]; a.b..xn---q----jra.e; [V2, V3, A4_2]; ; # a.b..-q--ä-.e
+a.b..-q--ä-.e; a.b..-q--ä-.e; [V2, V3, X4_2]; a.b..xn---q----jra.e; [V2, V3, A4_2]; ; # a.b..-q--ä-.e
+A.B..-Q--Ä-.E; a.b..-q--ä-.e; [V2, V3, X4_2]; a.b..xn---q----jra.e; [V2, V3, A4_2]; ; # a.b..-q--ä-.e
+A.B..-Q--Ä-.E; a.b..-q--ä-.e; [V2, V3, X4_2]; a.b..xn---q----jra.e; [V2, V3, A4_2]; ; # a.b..-q--ä-.e
+A.b..-Q--Ä-.E; a.b..-q--ä-.e; [V2, V3, X4_2]; a.b..xn---q----jra.e; [V2, V3, A4_2]; ; # a.b..-q--ä-.e
+A.b..-Q--Ä-.E; a.b..-q--ä-.e; [V2, V3, X4_2]; a.b..xn---q----jra.e; [V2, V3, A4_2]; ; # a.b..-q--ä-.e
+a.b..xn---q----jra.e; a.b..-q--ä-.e; [V2, V3, X4_2]; a.b..xn---q----jra.e; [V2, V3, A4_2]; ; # a.b..-q--ä-.e
+a..c; ; [X4_2]; ; [A4_2]; ; # a..c
+a.-b.; ; [V3]; ; ; ; # a.-b.
+a.b-.c; ; [V3]; ; ; ; # a.b-.c
+a.-.c; ; [V3]; ; ; ; # a.-.c
+a.bc--de.f; ; [V2]; ; ; ; # a.bc--de.f
+ä.­.c; ä..c; [X4_2]; xn--4ca..c; [A4_2]; ; # ä..c
+ä.­.c; ä..c; [X4_2]; xn--4ca..c; [A4_2]; ; # ä..c
+Ä.­.C; ä..c; [X4_2]; xn--4ca..c; [A4_2]; ; # ä..c
+Ä.­.C; ä..c; [X4_2]; xn--4ca..c; [A4_2]; ; # ä..c
+xn--4ca..c; ä..c; [X4_2]; xn--4ca..c; [A4_2]; ; # ä..c
+ä.-b.; ; [V3]; xn--4ca.-b.; ; ; # ä.-b.
+ä.-b.; ä.-b.; [V3]; xn--4ca.-b.; ; ; # ä.-b.
+Ä.-B.; ä.-b.; [V3]; xn--4ca.-b.; ; ; # ä.-b.
+Ä.-B.; ä.-b.; [V3]; xn--4ca.-b.; ; ; # ä.-b.
+xn--4ca.-b.; ä.-b.; [V3]; xn--4ca.-b.; ; ; # ä.-b.
+ä.b-.c; ; [V3]; xn--4ca.b-.c; ; ; # ä.b-.c
+ä.b-.c; ä.b-.c; [V3]; xn--4ca.b-.c; ; ; # ä.b-.c
+Ä.B-.C; ä.b-.c; [V3]; xn--4ca.b-.c; ; ; # ä.b-.c
+Ä.B-.C; ä.b-.c; [V3]; xn--4ca.b-.c; ; ; # ä.b-.c
+Ä.b-.C; ä.b-.c; [V3]; xn--4ca.b-.c; ; ; # ä.b-.c
+Ä.b-.C; ä.b-.c; [V3]; xn--4ca.b-.c; ; ; # ä.b-.c
+xn--4ca.b-.c; ä.b-.c; [V3]; xn--4ca.b-.c; ; ; # ä.b-.c
+ä.-.c; ; [V3]; xn--4ca.-.c; ; ; # ä.-.c
+ä.-.c; ä.-.c; [V3]; xn--4ca.-.c; ; ; # ä.-.c
+Ä.-.C; ä.-.c; [V3]; xn--4ca.-.c; ; ; # ä.-.c
+Ä.-.C; ä.-.c; [V3]; xn--4ca.-.c; ; ; # ä.-.c
+xn--4ca.-.c; ä.-.c; [V3]; xn--4ca.-.c; ; ; # ä.-.c
+ä.bc--de.f; ; [V2]; xn--4ca.bc--de.f; ; ; # ä.bc--de.f
+ä.bc--de.f; ä.bc--de.f; [V2]; xn--4ca.bc--de.f; ; ; # ä.bc--de.f
+Ä.BC--DE.F; ä.bc--de.f; [V2]; xn--4ca.bc--de.f; ; ; # ä.bc--de.f
+Ä.BC--DE.F; ä.bc--de.f; [V2]; xn--4ca.bc--de.f; ; ; # ä.bc--de.f
+Ä.bc--De.f; ä.bc--de.f; [V2]; xn--4ca.bc--de.f; ; ; # ä.bc--de.f
+Ä.bc--De.f; ä.bc--de.f; [V2]; xn--4ca.bc--de.f; ; ; # ä.bc--de.f
+xn--4ca.bc--de.f; ä.bc--de.f; [V2]; xn--4ca.bc--de.f; ; ; # ä.bc--de.f
+a.b.̈c.d; ; [V5]; a.b.xn--c-bcb.d; ; ; # a.b.̈c.d
+A.B.̈C.D; a.b.̈c.d; [V5]; a.b.xn--c-bcb.d; ; ; # a.b.̈c.d
+A.b.̈c.d; a.b.̈c.d; [V5]; a.b.xn--c-bcb.d; ; ; # a.b.̈c.d
+a.b.xn--c-bcb.d; a.b.̈c.d; [V5]; a.b.xn--c-bcb.d; ; ; # a.b.̈c.d
+A0; a0; ; ; ; ; # a0
+0A; 0a; ; ; ; ; # 0a
+0A.א; 0a.א; [B1]; 0a.xn--4db; ; ; # 0a.א
+0a.א; ; [B1]; 0a.xn--4db; ; ; # 0a.א
+0a.xn--4db; 0a.א; [B1]; 0a.xn--4db; ; ; # 0a.א
+c.xn--0-eha.xn--4db; c.0ü.א; [B1]; c.xn--0-eha.xn--4db; ; ; # c.0ü.א
+b-.א; ; [B6, V3]; b-.xn--4db; ; ; # b-.א
+B-.א; b-.א; [B6, V3]; b-.xn--4db; ; ; # b-.א
+b-.xn--4db; b-.א; [B6, V3]; b-.xn--4db; ; ; # b-.א
+d.xn----dha.xn--4db; d.ü-.א; [B6, V3]; d.xn----dha.xn--4db; ; ; # d.ü-.א
+aא; ; [B5, B6]; xn--a-0hc; ; ; # aא
+Aא; aא; [B5, B6]; xn--a-0hc; ; ; # aא
+xn--a-0hc; aא; [B5, B6]; xn--a-0hc; ; ; # aא
+אׇ; ; ; xn--vdbr; ; ; # אׇ
+xn--vdbr; אׇ; ; xn--vdbr; ; ; # אׇ
+א9ׇ; ; ; xn--9-ihcz; ; ; # א9ׇ
+xn--9-ihcz; א9ׇ; ; xn--9-ihcz; ; ; # א9ׇ
+אaׇ; ; [B2, B3]; xn--a-ihcz; ; ; # אaׇ
+אAׇ; אaׇ; [B2, B3]; xn--a-ihcz; ; ; # אaׇ
+xn--a-ihcz; אaׇ; [B2, B3]; xn--a-ihcz; ; ; # אaׇ
+את; ; ; xn--4db6c; ; ; # את
+xn--4db6c; את; ; xn--4db6c; ; ; # את
+א׳ת; ; ; xn--4db6c0a; ; ; # א׳ת
+xn--4db6c0a; א׳ת; ; xn--4db6c0a; ; ; # א׳ת
+aאTz; aאtz; [B5]; xn--atz-qpe; ; ; # aאtz
+aאtz; ; [B5]; xn--atz-qpe; ; ; # aאtz
+AאTZ; aאtz; [B5]; xn--atz-qpe; ; ; # aאtz
+Aאtz; aאtz; [B5]; xn--atz-qpe; ; ; # aאtz
+xn--atz-qpe; aאtz; [B5]; xn--atz-qpe; ; ; # aאtz
+אTת; אtת; [B2]; xn--t-zhc3f; ; ; # אtת
+אtת; ; [B2]; xn--t-zhc3f; ; ; # אtת
+xn--t-zhc3f; אtת; [B2]; xn--t-zhc3f; ; ; # אtת
+א7ת; ; ; xn--7-zhc3f; ; ; # א7ת
+xn--7-zhc3f; א7ת; ; xn--7-zhc3f; ; ; # א7ת
+א٧ת; ; ; xn--4db6c6t; ; ; # א٧ת
+xn--4db6c6t; א٧ת; ; xn--4db6c6t; ; ; # א٧ת
+a7٧z; ; [B5]; xn--a7z-06e; ; ; # a7٧z
+A7٧Z; a7٧z; [B5]; xn--a7z-06e; ; ; # a7٧z
+A7٧z; a7٧z; [B5]; xn--a7z-06e; ; ; # a7٧z
+xn--a7z-06e; a7٧z; [B5]; xn--a7z-06e; ; ; # a7٧z
+א7٧ת; ; [B4]; xn--7-zhc3fty; ; ; # א7٧ת
+xn--7-zhc3fty; א7٧ת; [B4]; xn--7-zhc3fty; ; ; # א7٧ת
+ஹ்‍; ; ; xn--dmc4b194h; ; xn--dmc4b; # ஹ்
+xn--dmc4b; ஹ்; ; xn--dmc4b; ; ; # ஹ்
+ஹ்; ; ; xn--dmc4b; ; ; # ஹ்
+xn--dmc4b194h; ஹ்‍; ; xn--dmc4b194h; ; ; # ஹ்
+ஹ‍; ; [C2]; xn--dmc225h; ; xn--dmc; [] # ஹ
+xn--dmc; ஹ; ; xn--dmc; ; ; # ஹ
+ஹ; ; ; xn--dmc; ; ; # ஹ
+xn--dmc225h; ஹ‍; [C2]; xn--dmc225h; ; ; # ஹ
+‍; ; [C2]; xn--1ug; ; ; [A4_2] #
+; ; [X4_2]; ; [A4_2]; ; #
+xn--1ug; ‍; [C2]; xn--1ug; ; ; #
+ஹ்‌; ; ; xn--dmc4by94h; ; xn--dmc4b; # ஹ்
+xn--dmc4by94h; ஹ்‌; ; xn--dmc4by94h; ; ; # ஹ்
+ஹ‌; ; [C1]; xn--dmc025h; ; xn--dmc; [] # ஹ
+xn--dmc025h; ஹ‌; [C1]; xn--dmc025h; ; ; # ஹ
+‌; ; [C1]; xn--0ug; ; ; [A4_2] #
+xn--0ug; ‌; [C1]; xn--0ug; ; ; #
+لٰ‌ۭۯ; ; ; xn--ghb2gxqia7523a; ; xn--ghb2gxqia; # لٰۭۯ
+xn--ghb2gxqia; لٰۭۯ; ; xn--ghb2gxqia; ; ; # لٰۭۯ
+لٰۭۯ; ; ; xn--ghb2gxqia; ; ; # لٰۭۯ
+xn--ghb2gxqia7523a; لٰ‌ۭۯ; ; xn--ghb2gxqia7523a; ; ; # لٰۭۯ
+لٰ‌ۯ; ; ; xn--ghb2g3qq34f; ; xn--ghb2g3q; # لٰۯ
+xn--ghb2g3q; لٰۯ; ; xn--ghb2g3q; ; ; # لٰۯ
+لٰۯ; ; ; xn--ghb2g3q; ; ; # لٰۯ
+xn--ghb2g3qq34f; لٰ‌ۯ; ; xn--ghb2g3qq34f; ; ; # لٰۯ
+ل‌ۭۯ; ; ; xn--ghb25aga828w; ; xn--ghb25aga; # لۭۯ
+xn--ghb25aga; لۭۯ; ; xn--ghb25aga; ; ; # لۭۯ
+لۭۯ; ; ; xn--ghb25aga; ; ; # لۭۯ
+xn--ghb25aga828w; ل‌ۭۯ; ; xn--ghb25aga828w; ; ; # لۭۯ
+ل‌ۯ; ; ; xn--ghb65a953d; ; xn--ghb65a; # لۯ
+xn--ghb65a; لۯ; ; xn--ghb65a; ; ; # لۯ
+لۯ; ; ; xn--ghb65a; ; ; # لۯ
+xn--ghb65a953d; ل‌ۯ; ; xn--ghb65a953d; ; ; # لۯ
+لٰ‌ۭ; ; [B3, C1]; xn--ghb2gxqy34f; ; xn--ghb2gxq; [] # لٰۭ
+xn--ghb2gxq; لٰۭ; ; xn--ghb2gxq; ; ; # لٰۭ
+لٰۭ; ; ; xn--ghb2gxq; ; ; # لٰۭ
+xn--ghb2gxqy34f; لٰ‌ۭ; [B3, C1]; xn--ghb2gxqy34f; ; ; # لٰۭ
+ۯ‌ۯ; ; [C1]; xn--cmba004q; ; xn--cmba; [] # ۯۯ
+xn--cmba; ۯۯ; ; xn--cmba; ; ; # ۯۯ
+ۯۯ; ; ; xn--cmba; ; ; # ۯۯ
+xn--cmba004q; ۯ‌ۯ; [C1]; xn--cmba004q; ; ; # ۯۯ
+ل‌; ; [B3, C1]; xn--ghb413k; ; xn--ghb; [] # ل
+xn--ghb; ل; ; xn--ghb; ; ; # ل
+ل; ; ; xn--ghb; ; ; # ل
+xn--ghb413k; ل‌; [B3, C1]; xn--ghb413k; ; ; # ل
+a。。b; a..b; [X4_2]; ; [A4_2]; ; # a..b
+A。。B; a..b; [X4_2]; ; [A4_2]; ; # a..b
+a..b; ; [X4_2]; ; [A4_2]; ; # a..b
+‍。。ڹ‌; ‍..ڹ‌; [B1, B3, C1, C2, X4_2]; xn--1ug..xn--skb080k; [B1, B3, C1, C2, A4_2]; ..xn--skb; [A4_2] # ..ڹ
+..xn--skb; ..ڹ; [X4_2]; ..xn--skb; [A4_2]; ; # ..ڹ
+xn--1ug..xn--skb080k; ‍..ڹ‌; [B1, B3, C1, C2, X4_2]; xn--1ug..xn--skb080k; [B1, B3, C1, C2, A4_2]; ; # ..ڹ
+א0٠; ; [B4]; xn--0-zhc74b; ; ; # א0٠
+xn--0-zhc74b; א0٠; [B4]; xn--0-zhc74b; ; ; # א0٠
+$; ; [P1, V6]; ; ; ; # $
+
+# RANDOMIZED TESTS
+
+c.0ü.א; ; [B1]; c.xn--0-eha.xn--4db; ; ; # c.0ü.א
+c.0ü.א; c.0ü.א; [B1]; c.xn--0-eha.xn--4db; ; ; # c.0ü.א
+C.0Ü.א; c.0ü.א; [B1]; c.xn--0-eha.xn--4db; ; ; # c.0ü.א
+C.0Ü.א; c.0ü.א; [B1]; c.xn--0-eha.xn--4db; ; ; # c.0ü.א
+C.0ü.א; c.0ü.א; [B1]; c.xn--0-eha.xn--4db; ; ; # c.0ü.א
+C.0ü.א; c.0ü.א; [B1]; c.xn--0-eha.xn--4db; ; ; # c.0ü.א
+⒕∝ٟ򓤦.-󠄯; ⒕∝ٟ򓤦.-; [P1, V3, V6]; xn--7hb713lfwbi1311b.-; ; ; # ⒕∝ٟ.-
+14.∝ٟ򓤦.-󠄯; 14.∝ٟ򓤦.-; [P1, V3, V6]; 14.xn--7hb713l3v90n.-; ; ; # 14.∝ٟ.-
+14.xn--7hb713l3v90n.-; 14.∝ٟ򓤦.-; [V3, V6]; 14.xn--7hb713l3v90n.-; ; ; # 14.∝ٟ.-
+xn--7hb713lfwbi1311b.-; ⒕∝ٟ򓤦.-; [V3, V6]; xn--7hb713lfwbi1311b.-; ; ; # ⒕∝ٟ.-
+ꡣ.ߏ; ; ; xn--8c9a.xn--qsb; ; ; # ꡣ.ߏ
+xn--8c9a.xn--qsb; ꡣ.ߏ; ; xn--8c9a.xn--qsb; ; ; # ꡣ.ߏ
+≯؃。-; ≯؃.-; [B1, P1, V3, V6]; xn--lfb566l.-; ; ; # ≯.-
+≯؃。-; ≯؃.-; [B1, P1, V3, V6]; xn--lfb566l.-; ; ; # ≯.-
+≯؃。-; ≯؃.-; [B1, P1, V3, V6]; xn--lfb566l.-; ; ; # ≯.-
+≯؃。-; ≯؃.-; [B1, P1, V3, V6]; xn--lfb566l.-; ; ; # ≯.-
+xn--lfb566l.-; ≯؃.-; [B1, V3, V6]; xn--lfb566l.-; ; ; # ≯.-
+⾛𐹧⾕.ᅟ󠗰ςႭ; 走𐹧谷.ᅟ󠗰ςႭ; [B5, P1, V6]; xn--6g3a1x434z.xn--3xa827dhpae6345i; ; xn--6g3a1x434z.xn--4xa627dhpae6345i; # 走𐹧谷.ςႭ
+走𐹧谷.ᅟ󠗰ςႭ; ; [B5, P1, V6]; xn--6g3a1x434z.xn--3xa827dhpae6345i; ; xn--6g3a1x434z.xn--4xa627dhpae6345i; # 走𐹧谷.ςႭ
+走𐹧谷.ᅟ󠗰ςⴍ; ; [B5, P1, V6]; xn--6g3a1x434z.xn--3xa380eotvh7453a; ; xn--6g3a1x434z.xn--4xa180eotvh7453a; # 走𐹧谷.ςⴍ
+走𐹧谷.ᅟ󠗰ΣႭ; 走𐹧谷.ᅟ󠗰σႭ; [B5, P1, V6]; xn--6g3a1x434z.xn--4xa627dhpae6345i; ; ; # 走𐹧谷.σႭ
+走𐹧谷.ᅟ󠗰σⴍ; ; [B5, P1, V6]; xn--6g3a1x434z.xn--4xa180eotvh7453a; ; ; # 走𐹧谷.σⴍ
+走𐹧谷.ᅟ󠗰Σⴍ; 走𐹧谷.ᅟ󠗰σⴍ; [B5, P1, V6]; xn--6g3a1x434z.xn--4xa180eotvh7453a; ; ; # 走𐹧谷.σⴍ
+xn--6g3a1x434z.xn--4xa180eotvh7453a; 走𐹧谷.ᅟ󠗰σⴍ; [B5, V6]; xn--6g3a1x434z.xn--4xa180eotvh7453a; ; ; # 走𐹧谷.σⴍ
+xn--6g3a1x434z.xn--4xa627dhpae6345i; 走𐹧谷.ᅟ󠗰σႭ; [B5, V6]; xn--6g3a1x434z.xn--4xa627dhpae6345i; ; ; # 走𐹧谷.σႭ
+xn--6g3a1x434z.xn--3xa380eotvh7453a; 走𐹧谷.ᅟ󠗰ςⴍ; [B5, V6]; xn--6g3a1x434z.xn--3xa380eotvh7453a; ; ; # 走𐹧谷.ςⴍ
+xn--6g3a1x434z.xn--3xa827dhpae6345i; 走𐹧谷.ᅟ󠗰ςႭ; [B5, V6]; xn--6g3a1x434z.xn--3xa827dhpae6345i; ; ; # 走𐹧谷.ςႭ
+⾛𐹧⾕.ᅟ󠗰ςⴍ; 走𐹧谷.ᅟ󠗰ςⴍ; [B5, P1, V6]; xn--6g3a1x434z.xn--3xa380eotvh7453a; ; xn--6g3a1x434z.xn--4xa180eotvh7453a; # 走𐹧谷.ςⴍ
+⾛𐹧⾕.ᅟ󠗰ΣႭ; 走𐹧谷.ᅟ󠗰σႭ; [B5, P1, V6]; xn--6g3a1x434z.xn--4xa627dhpae6345i; ; ; # 走𐹧谷.σႭ
+⾛𐹧⾕.ᅟ󠗰σⴍ; 走𐹧谷.ᅟ󠗰σⴍ; [B5, P1, V6]; xn--6g3a1x434z.xn--4xa180eotvh7453a; ; ; # 走𐹧谷.σⴍ
+⾛𐹧⾕.ᅟ󠗰Σⴍ; 走𐹧谷.ᅟ󠗰σⴍ; [B5, P1, V6]; xn--6g3a1x434z.xn--4xa180eotvh7453a; ; ; # 走𐹧谷.σⴍ
+‍≠ᢙ≯.솣-ᡴႠ; ; [C2, P1, V6]; xn--jbf929a90b0b.xn----6zg521d196p; ; xn--jbf911clb.xn----6zg521d196p; [P1, V6] # ≠ᢙ≯.솣-ᡴႠ
+‍≠ᢙ≯.솣-ᡴႠ; ‍≠ᢙ≯.솣-ᡴႠ; [C2, P1, V6]; xn--jbf929a90b0b.xn----6zg521d196p; ; xn--jbf911clb.xn----6zg521d196p; [P1, V6] # ≠ᢙ≯.솣-ᡴႠ
+‍≠ᢙ≯.솣-ᡴⴀ; ‍≠ᢙ≯.솣-ᡴⴀ; [C2, P1, V6]; xn--jbf929a90b0b.xn----p9j493ivi4l; ; xn--jbf911clb.xn----p9j493ivi4l; [P1, V6] # ≠ᢙ≯.솣-ᡴⴀ
+‍≠ᢙ≯.솣-ᡴⴀ; ; [C2, P1, V6]; xn--jbf929a90b0b.xn----p9j493ivi4l; ; xn--jbf911clb.xn----p9j493ivi4l; [P1, V6] # ≠ᢙ≯.솣-ᡴⴀ
+xn--jbf911clb.xn----p9j493ivi4l; ≠ᢙ≯.솣-ᡴⴀ; [V6]; xn--jbf911clb.xn----p9j493ivi4l; ; ; # ≠ᢙ≯.솣-ᡴⴀ
+xn--jbf929a90b0b.xn----p9j493ivi4l; ‍≠ᢙ≯.솣-ᡴⴀ; [C2, V6]; xn--jbf929a90b0b.xn----p9j493ivi4l; ; ; # ≠ᢙ≯.솣-ᡴⴀ
+xn--jbf911clb.xn----6zg521d196p; ≠ᢙ≯.솣-ᡴႠ; [V6]; xn--jbf911clb.xn----6zg521d196p; ; ; # ≠ᢙ≯.솣-ᡴႠ
+xn--jbf929a90b0b.xn----6zg521d196p; ‍≠ᢙ≯.솣-ᡴႠ; [C2, V6]; xn--jbf929a90b0b.xn----6zg521d196p; ; ; # ≠ᢙ≯.솣-ᡴႠ
+񯞜.𐿇ྡྷݽ؀; 񯞜.𐿇ྡྷݽ؀; [P1, V6]; xn--gw68a.xn--ifb57ev2psc6027m; ; ; # .𐿇ྡྷݽ
+񯞜.𐿇ྡྷݽ؀; 񯞜.𐿇ྡྷݽ؀; [P1, V6]; xn--gw68a.xn--ifb57ev2psc6027m; ; ; # .𐿇ྡྷݽ
+񯞜.𐿇ྡྷݽ؀; ; [P1, V6]; xn--gw68a.xn--ifb57ev2psc6027m; ; ; # .𐿇ྡྷݽ
+xn--gw68a.xn--ifb57ev2psc6027m; 񯞜.𐿇ྡྷݽ؀; [V6]; xn--gw68a.xn--ifb57ev2psc6027m; ; ; # .𐿇ྡྷݽ
+𣳔̃.𑓂; ; [V5]; xn--nsa95820a.xn--wz1d; ; ; # 𣳔̃.𑓂
+xn--nsa95820a.xn--wz1d; 𣳔̃.𑓂; [V5]; xn--nsa95820a.xn--wz1d; ; ; # 𣳔̃.𑓂
+𞤀𞥅񘐱。󠄌Ⴣꡥ; 𞤢𞥅񘐱.Ⴣꡥ; [B2, B3, P1, V6]; xn--9d6hgcy3556a.xn--7nd0578e; ; ; # 𞤢𞥅.Ⴣꡥ
+𞤢𞥅񘐱。󠄌ⴣꡥ; 𞤢𞥅񘐱.ⴣꡥ; [B2, B3, P1, V6]; xn--9d6hgcy3556a.xn--rlju750b; ; ; # 𞤢𞥅.ⴣꡥ
+xn--9d6hgcy3556a.xn--rlju750b; 𞤢𞥅񘐱.ⴣꡥ; [B2, B3, V6]; xn--9d6hgcy3556a.xn--rlju750b; ; ; # 𞤢𞥅.ⴣꡥ
+xn--9d6hgcy3556a.xn--7nd0578e; 𞤢𞥅񘐱.Ⴣꡥ; [B2, B3, V6]; xn--9d6hgcy3556a.xn--7nd0578e; ; ; # 𞤢𞥅.Ⴣꡥ
+𞤀𞥅񘐱。󠄌ⴣꡥ; 𞤢𞥅񘐱.ⴣꡥ; [B2, B3, P1, V6]; xn--9d6hgcy3556a.xn--rlju750b; ; ; # 𞤢𞥅.ⴣꡥ
+࣢𑁿ς𖬱。󠅡렧; ࣢𑁿ς𖬱.렧; [B1, P1, V6]; xn--3xa73xp48ys2xc.xn--kn2b; ; xn--4xa53xp48ys2xc.xn--kn2b; # 𑁿ς𖬱.렧
+࣢𑁿ς𖬱。󠅡렧; ࣢𑁿ς𖬱.렧; [B1, P1, V6]; xn--3xa73xp48ys2xc.xn--kn2b; ; xn--4xa53xp48ys2xc.xn--kn2b; # 𑁿ς𖬱.렧
+࣢𑁿Σ𖬱。󠅡렧; ࣢𑁿σ𖬱.렧; [B1, P1, V6]; xn--4xa53xp48ys2xc.xn--kn2b; ; ; # 𑁿σ𖬱.렧
+࣢𑁿Σ𖬱。󠅡렧; ࣢𑁿σ𖬱.렧; [B1, P1, V6]; xn--4xa53xp48ys2xc.xn--kn2b; ; ; # 𑁿σ𖬱.렧
+࣢𑁿σ𖬱。󠅡렧; ࣢𑁿σ𖬱.렧; [B1, P1, V6]; xn--4xa53xp48ys2xc.xn--kn2b; ; ; # 𑁿σ𖬱.렧
+࣢𑁿σ𖬱。󠅡렧; ࣢𑁿σ𖬱.렧; [B1, P1, V6]; xn--4xa53xp48ys2xc.xn--kn2b; ; ; # 𑁿σ𖬱.렧
+xn--4xa53xp48ys2xc.xn--kn2b; ࣢𑁿σ𖬱.렧; [B1, V6]; xn--4xa53xp48ys2xc.xn--kn2b; ; ; # 𑁿σ𖬱.렧
+xn--3xa73xp48ys2xc.xn--kn2b; ࣢𑁿ς𖬱.렧; [B1, V6]; xn--3xa73xp48ys2xc.xn--kn2b; ; ; # 𑁿ς𖬱.렧
+-‍。𞤍‌‍⒈; -‍.𞤯‌‍⒈; [B1, C1, C2, P1, V3, V6]; xn----ugn.xn--0ugc555aiv51d; ; -.xn--tsh3666n; [B1, P1, V3, V6] # -.𞤯⒈
+-‍。𞤍‌‍1.; -‍.𞤯‌‍1.; [B1, C1, C2, V3]; xn----ugn.xn--1-rgnd61297b.; ; -.xn--1-0i8r.; [B1, V3] # -.𞤯1.
+-‍。𞤯‌‍1.; -‍.𞤯‌‍1.; [B1, C1, C2, V3]; xn----ugn.xn--1-rgnd61297b.; ; -.xn--1-0i8r.; [B1, V3] # -.𞤯1.
+-.xn--1-0i8r.; -.𞤯1.; [B1, V3]; -.xn--1-0i8r.; ; ; # -.𞤯1.
+xn----ugn.xn--1-rgnd61297b.; -‍.𞤯‌‍1.; [B1, C1, C2, V3]; xn----ugn.xn--1-rgnd61297b.; ; ; # -.𞤯1.
+-‍。𞤯‌‍⒈; -‍.𞤯‌‍⒈; [B1, C1, C2, P1, V3, V6]; xn----ugn.xn--0ugc555aiv51d; ; -.xn--tsh3666n; [B1, P1, V3, V6] # -.𞤯⒈
+-.xn--tsh3666n; -.𞤯⒈; [B1, V3, V6]; -.xn--tsh3666n; ; ; # -.𞤯⒈
+xn----ugn.xn--0ugc555aiv51d; -‍.𞤯‌‍⒈; [B1, C1, C2, V3, V6]; xn----ugn.xn--0ugc555aiv51d; ; ; # -.𞤯⒈
+‌򅎭.Ⴒ𑇀; ; [C1, P1, V6]; xn--0ug15083f.xn--qnd6272k; ; xn--bn95b.xn--qnd6272k; [P1, V6] # .Ⴒ𑇀
+‌򅎭.ⴒ𑇀; ; [C1, P1, V6]; xn--0ug15083f.xn--9kj2034e; ; xn--bn95b.xn--9kj2034e; [P1, V6] # .ⴒ𑇀
+xn--bn95b.xn--9kj2034e; 򅎭.ⴒ𑇀; [V6]; xn--bn95b.xn--9kj2034e; ; ; # .ⴒ𑇀
+xn--0ug15083f.xn--9kj2034e; ‌򅎭.ⴒ𑇀; [C1, V6]; xn--0ug15083f.xn--9kj2034e; ; ; # .ⴒ𑇀
+xn--bn95b.xn--qnd6272k; 򅎭.Ⴒ𑇀; [V6]; xn--bn95b.xn--qnd6272k; ; ; # .Ⴒ𑇀
+xn--0ug15083f.xn--qnd6272k; ‌򅎭.Ⴒ𑇀; [C1, V6]; xn--0ug15083f.xn--qnd6272k; ; ; # .Ⴒ𑇀
+繱𑖿‍.8︒; 繱𑖿‍.8︒; [P1, V6]; xn--1ug6928ac48e.xn--8-o89h; ; xn--gl0as212a.xn--8-o89h; # 繱𑖿.8︒
+繱𑖿‍.8。; 繱𑖿‍.8.; ; xn--1ug6928ac48e.8.; ; xn--gl0as212a.8.; # 繱𑖿.8.
+xn--gl0as212a.8.; 繱𑖿.8.; ; xn--gl0as212a.8.; ; ; # 繱𑖿.8.
+繱𑖿.8.; ; ; xn--gl0as212a.8.; ; ; # 繱𑖿.8.
+xn--1ug6928ac48e.8.; 繱𑖿‍.8.; ; xn--1ug6928ac48e.8.; ; ; # 繱𑖿.8.
+繱𑖿‍.8.; ; ; xn--1ug6928ac48e.8.; ; xn--gl0as212a.8.; # 繱𑖿.8.
+xn--gl0as212a.xn--8-o89h; 繱𑖿.8︒; [V6]; xn--gl0as212a.xn--8-o89h; ; ; # 繱𑖿.8︒
+xn--1ug6928ac48e.xn--8-o89h; 繱𑖿‍.8︒; [V6]; xn--1ug6928ac48e.xn--8-o89h; ; ; # 繱𑖿.8︒
+󠆾.𞀈; .𞀈; [V5, X4_2]; .xn--ph4h; [V5, A4_2]; ; # .𞀈
+󠆾.𞀈; .𞀈; [V5, X4_2]; .xn--ph4h; [V5, A4_2]; ; # .𞀈
+.xn--ph4h; .𞀈; [V5, X4_2]; .xn--ph4h; [V5, A4_2]; ; # .𞀈
+ß۫。‍; ß۫.‍; [C2]; xn--zca012a.xn--1ug; ; xn--ss-59d.; [] # ß۫.
+SS۫。‍; ss۫.‍; [C2]; xn--ss-59d.xn--1ug; ; xn--ss-59d.; [] # ss۫.
+ss۫。‍; ss۫.‍; [C2]; xn--ss-59d.xn--1ug; ; xn--ss-59d.; [] # ss۫.
+Ss۫。‍; ss۫.‍; [C2]; xn--ss-59d.xn--1ug; ; xn--ss-59d.; [] # ss۫.
+xn--ss-59d.; ss۫.; ; xn--ss-59d.; ; ; # ss۫.
+ss۫.; ; ; xn--ss-59d.; ; ; # ss۫.
+SS۫.; ss۫.; ; xn--ss-59d.; ; ; # ss۫.
+Ss۫.; ss۫.; ; xn--ss-59d.; ; ; # ss۫.
+xn--ss-59d.xn--1ug; ss۫.‍; [C2]; xn--ss-59d.xn--1ug; ; ; # ss۫.
+xn--zca012a.xn--1ug; ß۫.‍; [C2]; xn--zca012a.xn--1ug; ; ; # ß۫.
+󠐵‌⒈.󠎇; 󠐵‌⒈.󠎇; [C1, P1, V6]; xn--0ug88o47900b.xn--tv36e; ; xn--tshz2001k.xn--tv36e; [P1, V6] # ⒈.
+󠐵‌1..󠎇; ; [C1, P1, V6, X4_2]; xn--1-rgn37671n..xn--tv36e; [C1, P1, V6, A4_2]; xn--1-bs31m..xn--tv36e; [P1, V6, A4_2] # 1..
+xn--1-bs31m..xn--tv36e; 󠐵1..󠎇; [V6, X4_2]; xn--1-bs31m..xn--tv36e; [V6, A4_2]; ; # 1..
+xn--1-rgn37671n..xn--tv36e; 󠐵‌1..󠎇; [C1, V6, X4_2]; xn--1-rgn37671n..xn--tv36e; [C1, V6, A4_2]; ; # 1..
+xn--tshz2001k.xn--tv36e; 󠐵⒈.󠎇; [V6]; xn--tshz2001k.xn--tv36e; ; ; # ⒈.
+xn--0ug88o47900b.xn--tv36e; 󠐵‌⒈.󠎇; [C1, V6]; xn--0ug88o47900b.xn--tv36e; ; ; # ⒈.
+󟈣ٟꪲß。󌓧; 󟈣ٟꪲß.󌓧; [P1, V6]; xn--zca92z0t7n5w96j.xn--bb79d; ; xn--ss-3xd2839nncy1m.xn--bb79d; # ٟꪲß.
+󟈣ٟꪲSS。󌓧; 󟈣ٟꪲss.󌓧; [P1, V6]; xn--ss-3xd2839nncy1m.xn--bb79d; ; ; # ٟꪲss.
+󟈣ٟꪲss。󌓧; 󟈣ٟꪲss.󌓧; [P1, V6]; xn--ss-3xd2839nncy1m.xn--bb79d; ; ; # ٟꪲss.
+󟈣ٟꪲSs。󌓧; 󟈣ٟꪲss.󌓧; [P1, V6]; xn--ss-3xd2839nncy1m.xn--bb79d; ; ; # ٟꪲss.
+xn--ss-3xd2839nncy1m.xn--bb79d; 󟈣ٟꪲss.󌓧; [V6]; xn--ss-3xd2839nncy1m.xn--bb79d; ; ; # ٟꪲss.
+xn--zca92z0t7n5w96j.xn--bb79d; 󟈣ٟꪲß.󌓧; [V6]; xn--zca92z0t7n5w96j.xn--bb79d; ; ; # ٟꪲß.
+ݴ‌𞤿。𽘐䉜‍񿤼; ݴ‌𞤿.𽘐䉜‍񿤼; [C1, C2, P1, V6]; xn--4pb607jjt73a.xn--1ug236ke314donv1a; ; xn--4pb2977v.xn--z0nt555ukbnv; [P1, V6] # ݴ𞤿.䉜
+ݴ‌𞤝。𽘐䉜‍񿤼; ݴ‌𞤿.𽘐䉜‍񿤼; [C1, C2, P1, V6]; xn--4pb607jjt73a.xn--1ug236ke314donv1a; ; xn--4pb2977v.xn--z0nt555ukbnv; [P1, V6] # ݴ𞤿.䉜
+xn--4pb2977v.xn--z0nt555ukbnv; ݴ𞤿.𽘐䉜񿤼; [V6]; xn--4pb2977v.xn--z0nt555ukbnv; ; ; # ݴ𞤿.䉜
+xn--4pb607jjt73a.xn--1ug236ke314donv1a; ݴ‌𞤿.𽘐䉜‍񿤼; [C1, C2, V6]; xn--4pb607jjt73a.xn--1ug236ke314donv1a; ; ; # ݴ𞤿.䉜
+򔭜ςᡱ⒈.≮𑄳‍𐮍; ; [B1, P1, V6]; xn--3xa407hkzinr77u.xn--1ug85gn777ahze; ; xn--4xa207hkzinr77u.xn--gdh5392g6sd; # ςᡱ⒈.≮𑄳𐮍
+򔭜ςᡱ⒈.≮𑄳‍𐮍; 򔭜ςᡱ⒈.≮𑄳‍𐮍; [B1, P1, V6]; xn--3xa407hkzinr77u.xn--1ug85gn777ahze; ; xn--4xa207hkzinr77u.xn--gdh5392g6sd; # ςᡱ⒈.≮𑄳𐮍
+򔭜ςᡱ1..≮𑄳‍𐮍; ; [B1, P1, V6, X4_2]; xn--1-xmb999meq63t..xn--1ug85gn777ahze; [B1, P1, V6, A4_2]; xn--1-zmb699meq63t..xn--gdh5392g6sd; # ςᡱ1..≮𑄳𐮍
+򔭜ςᡱ1..≮𑄳‍𐮍; 򔭜ςᡱ1..≮𑄳‍𐮍; [B1, P1, V6, X4_2]; xn--1-xmb999meq63t..xn--1ug85gn777ahze; [B1, P1, V6, A4_2]; xn--1-zmb699meq63t..xn--gdh5392g6sd; # ςᡱ1..≮𑄳𐮍
+򔭜Σᡱ1..≮𑄳‍𐮍; 򔭜σᡱ1..≮𑄳‍𐮍; [B1, P1, V6, X4_2]; xn--1-zmb699meq63t..xn--1ug85gn777ahze; [B1, P1, V6, A4_2]; xn--1-zmb699meq63t..xn--gdh5392g6sd; # σᡱ1..≮𑄳𐮍
+򔭜Σᡱ1..≮𑄳‍𐮍; 򔭜σᡱ1..≮𑄳‍𐮍; [B1, P1, V6, X4_2]; xn--1-zmb699meq63t..xn--1ug85gn777ahze; [B1, P1, V6, A4_2]; xn--1-zmb699meq63t..xn--gdh5392g6sd; # σᡱ1..≮𑄳𐮍
+򔭜σᡱ1..≮𑄳‍𐮍; ; [B1, P1, V6, X4_2]; xn--1-zmb699meq63t..xn--1ug85gn777ahze; [B1, P1, V6, A4_2]; xn--1-zmb699meq63t..xn--gdh5392g6sd; # σᡱ1..≮𑄳𐮍
+򔭜σᡱ1..≮𑄳‍𐮍; 򔭜σᡱ1..≮𑄳‍𐮍; [B1, P1, V6, X4_2]; xn--1-zmb699meq63t..xn--1ug85gn777ahze; [B1, P1, V6, A4_2]; xn--1-zmb699meq63t..xn--gdh5392g6sd; # σᡱ1..≮𑄳𐮍
+xn--1-zmb699meq63t..xn--gdh5392g6sd; 򔭜σᡱ1..≮𑄳𐮍; [B1, V6, X4_2]; xn--1-zmb699meq63t..xn--gdh5392g6sd; [B1, V6, A4_2]; ; # σᡱ1..≮𑄳𐮍
+xn--1-zmb699meq63t..xn--1ug85gn777ahze; 򔭜σᡱ1..≮𑄳‍𐮍; [B1, V6, X4_2]; xn--1-zmb699meq63t..xn--1ug85gn777ahze; [B1, V6, A4_2]; ; # σᡱ1..≮𑄳𐮍
+xn--1-xmb999meq63t..xn--1ug85gn777ahze; 򔭜ςᡱ1..≮𑄳‍𐮍; [B1, V6, X4_2]; xn--1-xmb999meq63t..xn--1ug85gn777ahze; [B1, V6, A4_2]; ; # ςᡱ1..≮𑄳𐮍
+򔭜Σᡱ⒈.≮𑄳‍𐮍; 򔭜σᡱ⒈.≮𑄳‍𐮍; [B1, P1, V6]; xn--4xa207hkzinr77u.xn--1ug85gn777ahze; ; xn--4xa207hkzinr77u.xn--gdh5392g6sd; # σᡱ⒈.≮𑄳𐮍
+򔭜Σᡱ⒈.≮𑄳‍𐮍; 򔭜σᡱ⒈.≮𑄳‍𐮍; [B1, P1, V6]; xn--4xa207hkzinr77u.xn--1ug85gn777ahze; ; xn--4xa207hkzinr77u.xn--gdh5392g6sd; # σᡱ⒈.≮𑄳𐮍
+򔭜σᡱ⒈.≮𑄳‍𐮍; ; [B1, P1, V6]; xn--4xa207hkzinr77u.xn--1ug85gn777ahze; ; xn--4xa207hkzinr77u.xn--gdh5392g6sd; # σᡱ⒈.≮𑄳𐮍
+򔭜σᡱ⒈.≮𑄳‍𐮍; 򔭜σᡱ⒈.≮𑄳‍𐮍; [B1, P1, V6]; xn--4xa207hkzinr77u.xn--1ug85gn777ahze; ; xn--4xa207hkzinr77u.xn--gdh5392g6sd; # σᡱ⒈.≮𑄳𐮍
+xn--4xa207hkzinr77u.xn--gdh5392g6sd; 򔭜σᡱ⒈.≮𑄳𐮍; [B1, V6]; xn--4xa207hkzinr77u.xn--gdh5392g6sd; ; ; # σᡱ⒈.≮𑄳𐮍
+xn--4xa207hkzinr77u.xn--1ug85gn777ahze; 򔭜σᡱ⒈.≮𑄳‍𐮍; [B1, V6]; xn--4xa207hkzinr77u.xn--1ug85gn777ahze; ; ; # σᡱ⒈.≮𑄳𐮍
+xn--3xa407hkzinr77u.xn--1ug85gn777ahze; 򔭜ςᡱ⒈.≮𑄳‍𐮍; [B1, V6]; xn--3xa407hkzinr77u.xn--1ug85gn777ahze; ; ; # ςᡱ⒈.≮𑄳𐮍
+ㅤ्Ⴀ័.᠋; ㅤ्Ⴀ័.; [P1, V6]; xn--n3b468azngju2a.; ; ; # ्Ⴀ័.
+ᅠ्Ⴀ័.᠋; ᅠ्Ⴀ័.; [P1, V6]; xn--n3b468aoqa89r.; ; ; # ्Ⴀ័.
+ᅠ्ⴀ័.᠋; ᅠ्ⴀ័.; [P1, V6]; xn--n3b742bkqf4ty.; ; ; # ्ⴀ័.
+xn--n3b742bkqf4ty.; ᅠ्ⴀ័.; [V6]; xn--n3b742bkqf4ty.; ; ; # ्ⴀ័.
+xn--n3b468aoqa89r.; ᅠ्Ⴀ័.; [V6]; xn--n3b468aoqa89r.; ; ; # ्Ⴀ័.
+ㅤ्ⴀ័.᠋; ㅤ्ⴀ័.; [P1, V6]; xn--n3b445e53po6d.; ; ; # ्ⴀ័.
+xn--n3b445e53po6d.; ㅤ्ⴀ័.; [V6]; xn--n3b445e53po6d.; ; ; # ्ⴀ័.
+xn--n3b468azngju2a.; ㅤ्Ⴀ័.; [V6]; xn--n3b468azngju2a.; ; ; # ्Ⴀ័.
+❣‍.্𑰽ؒꤩ; ❣‍.্𑰽ؒꤩ; [C2, V5]; xn--1ugy10a.xn--0fb32q3w7q2g4d; ; xn--pei.xn--0fb32q3w7q2g4d; [V5] # ❣.্𑰽ؒꤩ
+❣‍.্𑰽ؒꤩ; ; [C2, V5]; xn--1ugy10a.xn--0fb32q3w7q2g4d; ; xn--pei.xn--0fb32q3w7q2g4d; [V5] # ❣.্𑰽ؒꤩ
+xn--pei.xn--0fb32q3w7q2g4d; ❣.্𑰽ؒꤩ; [V5]; xn--pei.xn--0fb32q3w7q2g4d; ; ; # ❣.্𑰽ؒꤩ
+xn--1ugy10a.xn--0fb32q3w7q2g4d; ❣‍.্𑰽ؒꤩ; [C2, V5]; xn--1ugy10a.xn--0fb32q3w7q2g4d; ; ; # ❣.্𑰽ؒꤩ
+≮𐳺𐹄.≯񪮸ꡅ; ; [B1, P1, V6]; xn--gdh7943gk2a.xn--hdh1383c5e36c; ; ; # ≮𐳺.≯ꡅ
+≮𐳺𐹄.≯񪮸ꡅ; ≮𐳺𐹄.≯񪮸ꡅ; [B1, P1, V6]; xn--gdh7943gk2a.xn--hdh1383c5e36c; ; ; # ≮𐳺.≯ꡅ
+xn--gdh7943gk2a.xn--hdh1383c5e36c; ≮𐳺𐹄.≯񪮸ꡅ; [B1, V6]; xn--gdh7943gk2a.xn--hdh1383c5e36c; ; ; # ≮𐳺.≯ꡅ
+ೌ𐧅𐳏󠲺。್ᠦ; ೌ𐧅𐳏󠲺.್ᠦ; [B1, P1, V5, V6]; xn--7tc6360ky5bn2732c.xn--8tc429c; ; ; # ೌ𐧅𐳏.್ᠦ
+ೌ𐧅𐳏󠲺。್ᠦ; ೌ𐧅𐳏󠲺.್ᠦ; [B1, P1, V5, V6]; xn--7tc6360ky5bn2732c.xn--8tc429c; ; ; # ೌ𐧅𐳏.್ᠦ
+ೌ𐧅𐲏󠲺。್ᠦ; ೌ𐧅𐳏󠲺.್ᠦ; [B1, P1, V5, V6]; xn--7tc6360ky5bn2732c.xn--8tc429c; ; ; # ೌ𐧅𐳏.್ᠦ
+xn--7tc6360ky5bn2732c.xn--8tc429c; ೌ𐧅𐳏󠲺.್ᠦ; [B1, V5, V6]; xn--7tc6360ky5bn2732c.xn--8tc429c; ; ; # ೌ𐧅𐳏.್ᠦ
+ೌ𐧅𐲏󠲺。್ᠦ; ೌ𐧅𐳏󠲺.್ᠦ; [B1, P1, V5, V6]; xn--7tc6360ky5bn2732c.xn--8tc429c; ; ; # ೌ𐧅𐳏.್ᠦ
+͉。𧡫; ͉.𧡫; [V5]; xn--nua.xn--bc6k; ; ; # ͉.𧡫
+xn--nua.xn--bc6k; ͉.𧡫; [V5]; xn--nua.xn--bc6k; ; ; # ͉.𧡫
+𑰿󠅦.ᅠ; 𑰿.ᅠ; [P1, V5, V6]; xn--ok3d.xn--psd; ; ; # 𑰿.
+𑰿󠅦.ᅠ; 𑰿.ᅠ; [P1, V5, V6]; xn--ok3d.xn--psd; ; ; # 𑰿.
+xn--ok3d.xn--psd; 𑰿.ᅠ; [V5, V6]; xn--ok3d.xn--psd; ; ; # 𑰿.
+-𞤆‍。󸼄𞳒; -𞤨‍.󸼄𞳒; [B1, B5, B6, C2, P1, V3, V6]; xn----ugnx367r.xn--846h96596c; ; xn----ni8r.xn--846h96596c; [B1, B5, B6, P1, V3, V6] # -𞤨.
+-𞤨‍。󸼄𞳒; -𞤨‍.󸼄𞳒; [B1, B5, B6, C2, P1, V3, V6]; xn----ugnx367r.xn--846h96596c; ; xn----ni8r.xn--846h96596c; [B1, B5, B6, P1, V3, V6] # -𞤨.
+xn----ni8r.xn--846h96596c; -𞤨.󸼄𞳒; [B1, B5, B6, V3, V6]; xn----ni8r.xn--846h96596c; ; ; # -𞤨.
+xn----ugnx367r.xn--846h96596c; -𞤨‍.󸼄𞳒; [B1, B5, B6, C2, V3, V6]; xn----ugnx367r.xn--846h96596c; ; ; # -𞤨.
+ꡏ󠇶≯𳾽。᷽⾇滸𐹰; ꡏ󠇶≯𳾽.᷽舛滸𐹰; [B1, P1, V5, V6]; xn--hdh7483cu6twwki8e.xn--yfg0765a58l0n6k; ; ; # ꡏ≯.᷽舛滸𐹰
+ꡏ󠇶≯𳾽。᷽⾇滸𐹰; ꡏ󠇶≯𳾽.᷽舛滸𐹰; [B1, P1, V5, V6]; xn--hdh7483cu6twwki8e.xn--yfg0765a58l0n6k; ; ; # ꡏ≯.᷽舛滸𐹰
+ꡏ󠇶≯𳾽。᷽舛滸𐹰; ꡏ󠇶≯𳾽.᷽舛滸𐹰; [B1, P1, V5, V6]; xn--hdh7483cu6twwki8e.xn--yfg0765a58l0n6k; ; ; # ꡏ≯.᷽舛滸𐹰
+ꡏ󠇶≯𳾽。᷽舛滸𐹰; ꡏ󠇶≯𳾽.᷽舛滸𐹰; [B1, P1, V5, V6]; xn--hdh7483cu6twwki8e.xn--yfg0765a58l0n6k; ; ; # ꡏ≯.᷽舛滸𐹰
+xn--hdh7483cu6twwki8e.xn--yfg0765a58l0n6k; ꡏ󠇶≯𳾽.᷽舛滸𐹰; [B1, V5, V6]; xn--hdh7483cu6twwki8e.xn--yfg0765a58l0n6k; ; ; # ꡏ≯.᷽舛滸𐹰
+蔏。𑰺; 蔏.𑰺; [V5]; xn--uy1a.xn--jk3d; ; ; # 蔏.𑰺
+蔏。𑰺; 蔏.𑰺; [V5]; xn--uy1a.xn--jk3d; ; ; # 蔏.𑰺
+xn--uy1a.xn--jk3d; 蔏.𑰺; [V5]; xn--uy1a.xn--jk3d; ; ; # 蔏.𑰺
+𝟿𐮋。󠄊; 9𐮋.; [B1]; xn--9-rv5i.; ; ; # 9𐮋.
+9𐮋。󠄊; 9𐮋.; [B1]; xn--9-rv5i.; ; ; # 9𐮋.
+xn--9-rv5i.; 9𐮋.; [B1]; xn--9-rv5i.; ; ; # 9𐮋.
+󟇇-䟖F。ߋ⒈٢; 󟇇-䟖f.ߋ⒈٢; [B4, P1, V6]; xn---f-mz8b08788k.xn--bib53ev44d; ; ; # -䟖f.ߋ⒈٢
+󟇇-䟖F。ߋ1.٢; 󟇇-䟖f.ߋ1.٢; [B1, P1, V6]; xn---f-mz8b08788k.xn--1-ybd.xn--bib; ; ; # -䟖f.ߋ1.٢
+󟇇-䟖f。ߋ1.٢; 󟇇-䟖f.ߋ1.٢; [B1, P1, V6]; xn---f-mz8b08788k.xn--1-ybd.xn--bib; ; ; # -䟖f.ߋ1.٢
+xn---f-mz8b08788k.xn--1-ybd.xn--bib; 󟇇-䟖f.ߋ1.٢; [B1, V6]; xn---f-mz8b08788k.xn--1-ybd.xn--bib; ; ; # -䟖f.ߋ1.٢
+󟇇-䟖f。ߋ⒈٢; 󟇇-䟖f.ߋ⒈٢; [B4, P1, V6]; xn---f-mz8b08788k.xn--bib53ev44d; ; ; # -䟖f.ߋ⒈٢
+xn---f-mz8b08788k.xn--bib53ev44d; 󟇇-䟖f.ߋ⒈٢; [B4, V6]; xn---f-mz8b08788k.xn--bib53ev44d; ; ; # -䟖f.ߋ⒈٢
+‌。𐹺; ‌.𐹺; [B1, C1]; xn--0ug.xn--yo0d; ; .xn--yo0d; [B1, A4_2] # .𐹺
+‌。𐹺; ‌.𐹺; [B1, C1]; xn--0ug.xn--yo0d; ; .xn--yo0d; [B1, A4_2] # .𐹺
+.xn--yo0d; .𐹺; [B1, X4_2]; .xn--yo0d; [B1, A4_2]; ; # .𐹺
+xn--0ug.xn--yo0d; ‌.𐹺; [B1, C1]; xn--0ug.xn--yo0d; ; ; # .𐹺
+𐡆.≯‌-𞥀; ; [B1, C1, P1, V6]; xn--le9c.xn----rgn40iy359e; ; xn--le9c.xn----ogo9956r; [B1, P1, V6] # 𐡆.≯-𞥀
+𐡆.≯‌-𞥀; 𐡆.≯‌-𞥀; [B1, C1, P1, V6]; xn--le9c.xn----rgn40iy359e; ; xn--le9c.xn----ogo9956r; [B1, P1, V6] # 𐡆.≯-𞥀
+𐡆.≯‌-𞤞; 𐡆.≯‌-𞥀; [B1, C1, P1, V6]; xn--le9c.xn----rgn40iy359e; ; xn--le9c.xn----ogo9956r; [B1, P1, V6] # 𐡆.≯-𞥀
+𐡆.≯‌-𞤞; 𐡆.≯‌-𞥀; [B1, C1, P1, V6]; xn--le9c.xn----rgn40iy359e; ; xn--le9c.xn----ogo9956r; [B1, P1, V6] # 𐡆.≯-𞥀
+xn--le9c.xn----ogo9956r; 𐡆.≯-𞥀; [B1, V6]; xn--le9c.xn----ogo9956r; ; ; # 𐡆.≯-𞥀
+xn--le9c.xn----rgn40iy359e; 𐡆.≯‌-𞥀; [B1, C1, V6]; xn--le9c.xn----rgn40iy359e; ; ; # 𐡆.≯-𞥀
+󠁀-。≠ﳗ; 󠁀-.≠هج; [B1, P1, V3, V6]; xn----f411m.xn--rgb7c611j; ; ; # -.≠هج
+󠁀-。≠ﳗ; 󠁀-.≠هج; [B1, P1, V3, V6]; xn----f411m.xn--rgb7c611j; ; ; # -.≠هج
+󠁀-。≠هج; 󠁀-.≠هج; [B1, P1, V3, V6]; xn----f411m.xn--rgb7c611j; ; ; # -.≠هج
+󠁀-。≠هج; 󠁀-.≠هج; [B1, P1, V3, V6]; xn----f411m.xn--rgb7c611j; ; ; # -.≠هج
+xn----f411m.xn--rgb7c611j; 󠁀-.≠هج; [B1, V3, V6]; xn----f411m.xn--rgb7c611j; ; ; # -.≠هج
+񻬹𑈵。‍𞨶; 񻬹𑈵.‍𞨶; [B1, C2, P1, V6]; xn--8g1d12120a.xn--1ug6651p; ; xn--8g1d12120a.xn--5l6h; [P1, V6] # 𑈵.
+xn--8g1d12120a.xn--5l6h; 񻬹𑈵.𞨶; [V6]; xn--8g1d12120a.xn--5l6h; ; ; # 𑈵.
+xn--8g1d12120a.xn--1ug6651p; 񻬹𑈵.‍𞨶; [B1, C2, V6]; xn--8g1d12120a.xn--1ug6651p; ; ; # 𑈵.
+𑋧꧀2。㧉򒖄; 𑋧꧀2.㧉򒖄; [P1, V5, V6]; xn--2-5z4eu89y.xn--97l02706d; ; ; # 𑋧꧀2.㧉
+𑋧꧀2。㧉򒖄; 𑋧꧀2.㧉򒖄; [P1, V5, V6]; xn--2-5z4eu89y.xn--97l02706d; ; ; # 𑋧꧀2.㧉
+xn--2-5z4eu89y.xn--97l02706d; 𑋧꧀2.㧉򒖄; [V5, V6]; xn--2-5z4eu89y.xn--97l02706d; ; ; # 𑋧꧀2.㧉
+‌𽬄𐹴𞩥。≯6; ‌𽬄𐹴𞩥.≯6; [B1, C1, P1, V6]; xn--0ug7105gf5wfxepq.xn--6-ogo; ; xn--so0du768aim9m.xn--6-ogo; [B1, B5, B6, P1, V6] # 𐹴.≯6
+‌𽬄𐹴𞩥。≯6; ‌𽬄𐹴𞩥.≯6; [B1, C1, P1, V6]; xn--0ug7105gf5wfxepq.xn--6-ogo; ; xn--so0du768aim9m.xn--6-ogo; [B1, B5, B6, P1, V6] # 𐹴.≯6
+xn--so0du768aim9m.xn--6-ogo; 𽬄𐹴𞩥.≯6; [B1, B5, B6, V6]; xn--so0du768aim9m.xn--6-ogo; ; ; # 𐹴.≯6
+xn--0ug7105gf5wfxepq.xn--6-ogo; ‌𽬄𐹴𞩥.≯6; [B1, C1, V6]; xn--0ug7105gf5wfxepq.xn--6-ogo; ; ; # 𐹴.≯6
+𑁿.𐹦𻞵-‍; 𑁿.𐹦𻞵-‍; [B1, B3, B6, C2, P1, V5, V6]; xn--q30d.xn----ugn1088hfsxv; ; xn--q30d.xn----i26i1299n; [B1, B3, B6, P1, V3, V5, V6] # 𑁿.𐹦-
+𑁿.𐹦𻞵-‍; ; [B1, B3, B6, C2, P1, V5, V6]; xn--q30d.xn----ugn1088hfsxv; ; xn--q30d.xn----i26i1299n; [B1, B3, B6, P1, V3, V5, V6] # 𑁿.𐹦-
+xn--q30d.xn----i26i1299n; 𑁿.𐹦𻞵-; [B1, B3, B6, V3, V5, V6]; xn--q30d.xn----i26i1299n; ; ; # 𑁿.𐹦-
+xn--q30d.xn----ugn1088hfsxv; 𑁿.𐹦𻞵-‍; [B1, B3, B6, C2, V5, V6]; xn--q30d.xn----ugn1088hfsxv; ; ; # 𑁿.𐹦-
+⤸ς𺱀。ᅠ; ⤸ς𺱀.ᅠ; [P1, V6]; xn--3xa392qmp03d.xn--cl7c; ; xn--4xa192qmp03d.xn--cl7c; # ⤸ς.
+⤸ς𺱀。ᅠ; ⤸ς𺱀.ᅠ; [P1, V6]; xn--3xa392qmp03d.xn--psd; ; xn--4xa192qmp03d.xn--psd; # ⤸ς.
+⤸Σ𺱀。ᅠ; ⤸σ𺱀.ᅠ; [P1, V6]; xn--4xa192qmp03d.xn--psd; ; ; # ⤸σ.
+⤸σ𺱀。ᅠ; ⤸σ𺱀.ᅠ; [P1, V6]; xn--4xa192qmp03d.xn--psd; ; ; # ⤸σ.
+xn--4xa192qmp03d.xn--psd; ⤸σ𺱀.ᅠ; [V6]; xn--4xa192qmp03d.xn--psd; ; ; # ⤸σ.
+xn--3xa392qmp03d.xn--psd; ⤸ς𺱀.ᅠ; [V6]; xn--3xa392qmp03d.xn--psd; ; ; # ⤸ς.
+⤸Σ𺱀。ᅠ; ⤸σ𺱀.ᅠ; [P1, V6]; xn--4xa192qmp03d.xn--cl7c; ; ; # ⤸σ.
+⤸σ𺱀。ᅠ; ⤸σ𺱀.ᅠ; [P1, V6]; xn--4xa192qmp03d.xn--cl7c; ; ; # ⤸σ.
+xn--4xa192qmp03d.xn--cl7c; ⤸σ𺱀.ᅠ; [V6]; xn--4xa192qmp03d.xn--cl7c; ; ; # ⤸σ.
+xn--3xa392qmp03d.xn--cl7c; ⤸ς𺱀.ᅠ; [V6]; xn--3xa392qmp03d.xn--cl7c; ; ; # ⤸ς.
+ݥဵ𐫔ە.𐦬𑋪Ⴃ; ; [B2, B3, P1, V6]; xn--llb10as9tqp5y.xn--bnd9168j21f; ; ; # ݥဵ𐫔ە.𐦬𑋪Ⴃ
+ݥဵ𐫔ە.𐦬𑋪ⴃ; ; [B2, B3]; xn--llb10as9tqp5y.xn--ukj7371e21f; ; ; # ݥဵ𐫔ە.𐦬𑋪ⴃ
+xn--llb10as9tqp5y.xn--ukj7371e21f; ݥဵ𐫔ە.𐦬𑋪ⴃ; [B2, B3]; xn--llb10as9tqp5y.xn--ukj7371e21f; ; ; # ݥဵ𐫔ە.𐦬𑋪ⴃ
+xn--llb10as9tqp5y.xn--bnd9168j21f; ݥဵ𐫔ە.𐦬𑋪Ⴃ; [B2, B3, V6]; xn--llb10as9tqp5y.xn--bnd9168j21f; ; ; # ݥဵ𐫔ە.𐦬𑋪Ⴃ
+١᭄-킼.᮪ؖ٬≯; ; [B1, B5, B6, P1, V5, V6]; xn----9pc551nk39n.xn--4fb6o571degg; ; ; # ١᭄-킼.᮪ؖ٬≯
+١᭄-킼.᮪ؖ٬≯; ١᭄-킼.᮪ؖ٬≯; [B1, B5, B6, P1, V5, V6]; xn----9pc551nk39n.xn--4fb6o571degg; ; ; # ١᭄-킼.᮪ؖ٬≯
+xn----9pc551nk39n.xn--4fb6o571degg; ١᭄-킼.᮪ؖ٬≯; [B1, B5, B6, V5, V6]; xn----9pc551nk39n.xn--4fb6o571degg; ; ; # ١᭄-킼.᮪ؖ٬≯
+-。ۂ؄򅖡𑓂; -.ۂ؄򅖡𑓂; [B1, B2, B3, P1, V3, V6]; -.xn--mfb39a7208dzgs3d; ; ; # -.ۂ𑓂
+-。ۂ؄򅖡𑓂; -.ۂ؄򅖡𑓂; [B1, B2, B3, P1, V3, V6]; -.xn--mfb39a7208dzgs3d; ; ; # -.ۂ𑓂
+-.xn--mfb39a7208dzgs3d; -.ۂ؄򅖡𑓂; [B1, B2, B3, V3, V6]; -.xn--mfb39a7208dzgs3d; ; ; # -.ۂ𑓂
+‍󯑖󠁐.ֽ𙮰ꡝ𐋡; ‍󯑖󠁐.ֽ𙮰ꡝ𐋡; [C2, P1, V5, V6]; xn--1ug66101lt8me.xn--ldb8734fg0qcyzzg; ; xn--b726ey18m.xn--ldb8734fg0qcyzzg; [P1, V5, V6] # .ֽꡝ𐋡
+‍󯑖󠁐.ֽ𙮰ꡝ𐋡; ; [C2, P1, V5, V6]; xn--1ug66101lt8me.xn--ldb8734fg0qcyzzg; ; xn--b726ey18m.xn--ldb8734fg0qcyzzg; [P1, V5, V6] # .ֽꡝ𐋡
+xn--b726ey18m.xn--ldb8734fg0qcyzzg; 󯑖󠁐.ֽ𙮰ꡝ𐋡; [V5, V6]; xn--b726ey18m.xn--ldb8734fg0qcyzzg; ; ; # .ֽꡝ𐋡
+xn--1ug66101lt8me.xn--ldb8734fg0qcyzzg; ‍󯑖󠁐.ֽ𙮰ꡝ𐋡; [C2, V5, V6]; xn--1ug66101lt8me.xn--ldb8734fg0qcyzzg; ; ; # .ֽꡝ𐋡
+︒􃈵ς񀠇。𐮈; ︒􃈵ς񀠇.𐮈; [B1, P1, V6]; xn--3xa3729jwz5t7gl5f.xn--f29c; ; xn--4xa1729jwz5t7gl5f.xn--f29c; # ︒ς.𐮈
+。􃈵ς񀠇。𐮈; .􃈵ς񀠇.𐮈; [P1, V6, X4_2]; .xn--3xa88573c7n64d.xn--f29c; [P1, V6, A4_2]; .xn--4xa68573c7n64d.xn--f29c; # .ς.𐮈
+。􃈵Σ񀠇。𐮈; .􃈵σ񀠇.𐮈; [P1, V6, X4_2]; .xn--4xa68573c7n64d.xn--f29c; [P1, V6, A4_2]; ; # .σ.𐮈
+。􃈵σ񀠇。𐮈; .􃈵σ񀠇.𐮈; [P1, V6, X4_2]; .xn--4xa68573c7n64d.xn--f29c; [P1, V6, A4_2]; ; # .σ.𐮈
+.xn--4xa68573c7n64d.xn--f29c; .􃈵σ񀠇.𐮈; [V6, X4_2]; .xn--4xa68573c7n64d.xn--f29c; [V6, A4_2]; ; # .σ.𐮈
+.xn--3xa88573c7n64d.xn--f29c; .􃈵ς񀠇.𐮈; [V6, X4_2]; .xn--3xa88573c7n64d.xn--f29c; [V6, A4_2]; ; # .ς.𐮈
+︒􃈵Σ񀠇。𐮈; ︒􃈵σ񀠇.𐮈; [B1, P1, V6]; xn--4xa1729jwz5t7gl5f.xn--f29c; ; ; # ︒σ.𐮈
+︒􃈵σ񀠇。𐮈; ︒􃈵σ񀠇.𐮈; [B1, P1, V6]; xn--4xa1729jwz5t7gl5f.xn--f29c; ; ; # ︒σ.𐮈
+xn--4xa1729jwz5t7gl5f.xn--f29c; ︒􃈵σ񀠇.𐮈; [B1, V6]; xn--4xa1729jwz5t7gl5f.xn--f29c; ; ; # ︒σ.𐮈
+xn--3xa3729jwz5t7gl5f.xn--f29c; ︒􃈵ς񀠇.𐮈; [B1, V6]; xn--3xa3729jwz5t7gl5f.xn--f29c; ; ; # ︒ς.𐮈
+ߙ.ۮ󆾃≯󠅲; ߙ.ۮ󆾃≯; [B2, B3, P1, V6]; xn--0sb.xn--bmb691l0524t; ; ; # ߙ.ۮ≯
+ߙ.ۮ󆾃≯󠅲; ߙ.ۮ󆾃≯; [B2, B3, P1, V6]; xn--0sb.xn--bmb691l0524t; ; ; # ߙ.ۮ≯
+ߙ.ۮ󆾃≯󠅲; ߙ.ۮ󆾃≯; [B2, B3, P1, V6]; xn--0sb.xn--bmb691l0524t; ; ; # ߙ.ۮ≯
+ߙ.ۮ󆾃≯󠅲; ߙ.ۮ󆾃≯; [B2, B3, P1, V6]; xn--0sb.xn--bmb691l0524t; ; ; # ߙ.ۮ≯
+xn--0sb.xn--bmb691l0524t; ߙ.ۮ󆾃≯; [B2, B3, V6]; xn--0sb.xn--bmb691l0524t; ; ; # ߙ.ۮ≯
+ᩳ󚙸.𐭍; ; [B1, P1, V5, V6]; xn--2of22352n.xn--q09c; ; ; # ᩳ.𐭍
+xn--2of22352n.xn--q09c; ᩳ󚙸.𐭍; [B1, V5, V6]; xn--2of22352n.xn--q09c; ; ; # ᩳ.𐭍
+⒉󠊓≠。Ⴟ⬣Ⴈ; ⒉󠊓≠.Ⴟ⬣Ⴈ; [P1, V6]; xn--1ch07f91401d.xn--gnd9b297j; ; ; # ⒉≠.Ⴟ⬣Ⴈ
+⒉󠊓≠。Ⴟ⬣Ⴈ; ⒉󠊓≠.Ⴟ⬣Ⴈ; [P1, V6]; xn--1ch07f91401d.xn--gnd9b297j; ; ; # ⒉≠.Ⴟ⬣Ⴈ
+2.󠊓≠。Ⴟ⬣Ⴈ; 2.󠊓≠.Ⴟ⬣Ⴈ; [P1, V6]; 2.xn--1chz4101l.xn--gnd9b297j; ; ; # 2.≠.Ⴟ⬣Ⴈ
+2.󠊓≠。Ⴟ⬣Ⴈ; 2.󠊓≠.Ⴟ⬣Ⴈ; [P1, V6]; 2.xn--1chz4101l.xn--gnd9b297j; ; ; # 2.≠.Ⴟ⬣Ⴈ
+2.󠊓≠。ⴟ⬣ⴈ; 2.󠊓≠.ⴟ⬣ⴈ; [P1, V6]; 2.xn--1chz4101l.xn--45iz7d6b; ; ; # 2.≠.ⴟ⬣ⴈ
+2.󠊓≠。ⴟ⬣ⴈ; 2.󠊓≠.ⴟ⬣ⴈ; [P1, V6]; 2.xn--1chz4101l.xn--45iz7d6b; ; ; # 2.≠.ⴟ⬣ⴈ
+2.xn--1chz4101l.xn--45iz7d6b; 2.󠊓≠.ⴟ⬣ⴈ; [V6]; 2.xn--1chz4101l.xn--45iz7d6b; ; ; # 2.≠.ⴟ⬣ⴈ
+2.xn--1chz4101l.xn--gnd9b297j; 2.󠊓≠.Ⴟ⬣Ⴈ; [V6]; 2.xn--1chz4101l.xn--gnd9b297j; ; ; # 2.≠.Ⴟ⬣Ⴈ
+⒉󠊓≠。ⴟ⬣ⴈ; ⒉󠊓≠.ⴟ⬣ⴈ; [P1, V6]; xn--1ch07f91401d.xn--45iz7d6b; ; ; # ⒉≠.ⴟ⬣ⴈ
+⒉󠊓≠。ⴟ⬣ⴈ; ⒉󠊓≠.ⴟ⬣ⴈ; [P1, V6]; xn--1ch07f91401d.xn--45iz7d6b; ; ; # ⒉≠.ⴟ⬣ⴈ
+xn--1ch07f91401d.xn--45iz7d6b; ⒉󠊓≠.ⴟ⬣ⴈ; [V6]; xn--1ch07f91401d.xn--45iz7d6b; ; ; # ⒉≠.ⴟ⬣ⴈ
+xn--1ch07f91401d.xn--gnd9b297j; ⒉󠊓≠.Ⴟ⬣Ⴈ; [V6]; xn--1ch07f91401d.xn--gnd9b297j; ; ; # ⒉≠.Ⴟ⬣Ⴈ
+-󠉱ྸჅ。-𐹽ݴ𞣑; -󠉱ྸჅ.-𐹽ݴ𞣑; [B1, P1, V3, V6]; xn----xmg12fm2555h.xn----05c4213ryr0g; ; ; # -ྸჅ.-𐹽ݴ𞣑
+-󠉱ྸⴥ。-𐹽ݴ𞣑; -󠉱ྸⴥ.-𐹽ݴ𞣑; [B1, P1, V3, V6]; xn----xmg317tgv352a.xn----05c4213ryr0g; ; ; # -ྸⴥ.-𐹽ݴ𞣑
+xn----xmg317tgv352a.xn----05c4213ryr0g; -󠉱ྸⴥ.-𐹽ݴ𞣑; [B1, V3, V6]; xn----xmg317tgv352a.xn----05c4213ryr0g; ; ; # -ྸⴥ.-𐹽ݴ𞣑
+xn----xmg12fm2555h.xn----05c4213ryr0g; -󠉱ྸჅ.-𐹽ݴ𞣑; [B1, V3, V6]; xn----xmg12fm2555h.xn----05c4213ryr0g; ; ; # -ྸჅ.-𐹽ݴ𞣑
+ٙ。𑄴︒اߝ; ٙ.𑄴︒اߝ; [B1, B3, B6, P1, V5, V6]; xn--1hb.xn--mgb09fp820c08pa; ; ; # ٙ.𑄴︒اߝ
+ٙ。𑄴。اߝ; ٙ.𑄴.اߝ; [B1, B3, B6, V5]; xn--1hb.xn--w80d.xn--mgb09f; ; ; # ٙ.𑄴.اߝ
+xn--1hb.xn--w80d.xn--mgb09f; ٙ.𑄴.اߝ; [B1, B3, B6, V5]; xn--1hb.xn--w80d.xn--mgb09f; ; ; # ٙ.𑄴.اߝ
+xn--1hb.xn--mgb09fp820c08pa; ٙ.𑄴︒اߝ; [B1, B3, B6, V5, V6]; xn--1hb.xn--mgb09fp820c08pa; ; ; # ٙ.𑄴︒اߝ
+Ⴙظ.󠆓‍; Ⴙظ.‍; [B1, B5, B6, C2, P1, V6]; xn--3gb194c.xn--1ug; ; xn--3gb194c.; [B5, B6, P1, V6] # Ⴙظ.
+ⴙظ.󠆓‍; ⴙظ.‍; [B1, B5, B6, C2]; xn--3gb910r.xn--1ug; ; xn--3gb910r.; [B5, B6] # ⴙظ.
+xn--3gb910r.; ⴙظ.; [B5, B6]; xn--3gb910r.; ; ; # ⴙظ.
+xn--3gb910r.xn--1ug; ⴙظ.‍; [B1, B5, B6, C2]; xn--3gb910r.xn--1ug; ; ; # ⴙظ.
+xn--3gb194c.; Ⴙظ.; [B5, B6, V6]; xn--3gb194c.; ; ; # Ⴙظ.
+xn--3gb194c.xn--1ug; Ⴙظ.‍; [B1, B5, B6, C2, V6]; xn--3gb194c.xn--1ug; ; ; # Ⴙظ.
+󠆸。₆0𐺧ݖ; .60𐺧ݖ; [B1, X4_2]; .xn--60-cke9470y; [B1, A4_2]; ; # .60𐺧ݖ
+󠆸。60𐺧ݖ; .60𐺧ݖ; [B1, X4_2]; .xn--60-cke9470y; [B1, A4_2]; ; # .60𐺧ݖ
+.xn--60-cke9470y; .60𐺧ݖ; [B1, X4_2]; .xn--60-cke9470y; [B1, A4_2]; ; # .60𐺧ݖ
+6ࡏ。-𑈴; 6ࡏ.-𑈴; [B1, V3]; xn--6-jjd.xn----6n8i; ; ; # 6ࡏ.-𑈴
+6ࡏ。-𑈴; 6ࡏ.-𑈴; [B1, V3]; xn--6-jjd.xn----6n8i; ; ; # 6ࡏ.-𑈴
+xn--6-jjd.xn----6n8i; 6ࡏ.-𑈴; [B1, V3]; xn--6-jjd.xn----6n8i; ; ; # 6ࡏ.-𑈴
+‍񋌿𐹰。્ς𞰎ࣖ; ‍񋌿𐹰.્ς𞰎ࣖ; [B1, C2, P1, V5, V6]; xn--1ugx105gq26y.xn--3xa41xcwbfz15g; ; xn--oo0d1330n.xn--4xa21xcwbfz15g; [B1, B5, B6, P1, V5, V6] # 𐹰.્ςࣖ
+‍񋌿𐹰。્ς𞰎ࣖ; ‍񋌿𐹰.્ς𞰎ࣖ; [B1, C2, P1, V5, V6]; xn--1ugx105gq26y.xn--3xa41xcwbfz15g; ; xn--oo0d1330n.xn--4xa21xcwbfz15g; [B1, B5, B6, P1, V5, V6] # 𐹰.્ςࣖ
+‍񋌿𐹰。્Σ𞰎ࣖ; ‍񋌿𐹰.્σ𞰎ࣖ; [B1, C2, P1, V5, V6]; xn--1ugx105gq26y.xn--4xa21xcwbfz15g; ; xn--oo0d1330n.xn--4xa21xcwbfz15g; [B1, B5, B6, P1, V5, V6] # 𐹰.્σࣖ
+‍񋌿𐹰。્σ𞰎ࣖ; ‍񋌿𐹰.્σ𞰎ࣖ; [B1, C2, P1, V5, V6]; xn--1ugx105gq26y.xn--4xa21xcwbfz15g; ; xn--oo0d1330n.xn--4xa21xcwbfz15g; [B1, B5, B6, P1, V5, V6] # 𐹰.્σࣖ
+xn--oo0d1330n.xn--4xa21xcwbfz15g; 񋌿𐹰.્σ𞰎ࣖ; [B1, B5, B6, V5, V6]; xn--oo0d1330n.xn--4xa21xcwbfz15g; ; ; # 𐹰.્σࣖ
+xn--1ugx105gq26y.xn--4xa21xcwbfz15g; ‍񋌿𐹰.્σ𞰎ࣖ; [B1, C2, V5, V6]; xn--1ugx105gq26y.xn--4xa21xcwbfz15g; ; ; # 𐹰.્σࣖ
+xn--1ugx105gq26y.xn--3xa41xcwbfz15g; ‍񋌿𐹰.્ς𞰎ࣖ; [B1, C2, V5, V6]; xn--1ugx105gq26y.xn--3xa41xcwbfz15g; ; ; # 𐹰.્ςࣖ
+‍񋌿𐹰。્Σ𞰎ࣖ; ‍񋌿𐹰.્σ𞰎ࣖ; [B1, C2, P1, V5, V6]; xn--1ugx105gq26y.xn--4xa21xcwbfz15g; ; xn--oo0d1330n.xn--4xa21xcwbfz15g; [B1, B5, B6, P1, V5, V6] # 𐹰.્σࣖ
+‍񋌿𐹰。્σ𞰎ࣖ; ‍񋌿𐹰.્σ𞰎ࣖ; [B1, C2, P1, V5, V6]; xn--1ugx105gq26y.xn--4xa21xcwbfz15g; ; xn--oo0d1330n.xn--4xa21xcwbfz15g; [B1, B5, B6, P1, V5, V6] # 𐹰.્σࣖ
+⒈񟄜Ⴓ⒪.්򘘶ࢋ𐹢; ⒈񟄜Ⴓ⒪.්򘘶ࢋ𐹢; [B1, P1, V5, V6]; xn--rnd762h7cx3027d.xn--3xb99xpx1yoes3e; ; ; # ⒈Ⴓ⒪.්ࢋ𐹢
+1.񟄜Ⴓ(o).්򘘶ࢋ𐹢; ; [B1, B6, P1, V5, V6]; 1.xn--(o)-7sn88849j.xn--3xb99xpx1yoes3e; ; ; # 1.Ⴓ(o).්ࢋ𐹢
+1.񟄜ⴓ(o).්򘘶ࢋ𐹢; ; [B1, B6, P1, V5, V6]; 1.xn--(o)-ej1bu5389e.xn--3xb99xpx1yoes3e; ; ; # 1.ⴓ(o).්ࢋ𐹢
+1.񟄜Ⴓ(O).්򘘶ࢋ𐹢; 1.񟄜Ⴓ(o).්򘘶ࢋ𐹢; [B1, B6, P1, V5, V6]; 1.xn--(o)-7sn88849j.xn--3xb99xpx1yoes3e; ; ; # 1.Ⴓ(o).්ࢋ𐹢
+1.xn--(o)-7sn88849j.xn--3xb99xpx1yoes3e; 1.񟄜Ⴓ(o).්򘘶ࢋ𐹢; [B1, B6, P1, V5, V6]; 1.xn--(o)-7sn88849j.xn--3xb99xpx1yoes3e; ; ; # 1.Ⴓ(o).්ࢋ𐹢
+1.xn--(o)-ej1bu5389e.xn--3xb99xpx1yoes3e; 1.񟄜ⴓ(o).්򘘶ࢋ𐹢; [B1, B6, P1, V5, V6]; 1.xn--(o)-ej1bu5389e.xn--3xb99xpx1yoes3e; ; ; # 1.ⴓ(o).්ࢋ𐹢
+⒈񟄜ⴓ⒪.්򘘶ࢋ𐹢; ⒈񟄜ⴓ⒪.්򘘶ࢋ𐹢; [B1, P1, V5, V6]; xn--tsh0ds63atl31n.xn--3xb99xpx1yoes3e; ; ; # ⒈ⴓ⒪.්ࢋ𐹢
+xn--tsh0ds63atl31n.xn--3xb99xpx1yoes3e; ⒈񟄜ⴓ⒪.්򘘶ࢋ𐹢; [B1, V5, V6]; xn--tsh0ds63atl31n.xn--3xb99xpx1yoes3e; ; ; # ⒈ⴓ⒪.්ࢋ𐹢
+xn--rnd762h7cx3027d.xn--3xb99xpx1yoes3e; ⒈񟄜Ⴓ⒪.්򘘶ࢋ𐹢; [B1, V5, V6]; xn--rnd762h7cx3027d.xn--3xb99xpx1yoes3e; ; ; # ⒈Ⴓ⒪.්ࢋ𐹢
+𞤷.𐮐𞢁𐹠ؤ; ; ; xn--ve6h.xn--jgb1694kz0b2176a; ; ; # 𞤷.𐮐𞢁𐹠ؤ
+𞤷.𐮐𞢁𐹠ؤ; 𞤷.𐮐𞢁𐹠ؤ; ; xn--ve6h.xn--jgb1694kz0b2176a; ; ; # 𞤷.𐮐𞢁𐹠ؤ
+𞤕.𐮐𞢁𐹠ؤ; 𞤷.𐮐𞢁𐹠ؤ; ; xn--ve6h.xn--jgb1694kz0b2176a; ; ; # 𞤷.𐮐𞢁𐹠ؤ
+𞤕.𐮐𞢁𐹠ؤ; 𞤷.𐮐𞢁𐹠ؤ; ; xn--ve6h.xn--jgb1694kz0b2176a; ; ; # 𞤷.𐮐𞢁𐹠ؤ
+xn--ve6h.xn--jgb1694kz0b2176a; 𞤷.𐮐𞢁𐹠ؤ; ; xn--ve6h.xn--jgb1694kz0b2176a; ; ; # 𞤷.𐮐𞢁𐹠ؤ
+𐲈-。𑄳񢌻; 𐳈-.𑄳񢌻; [B1, B3, P1, V3, V5, V6]; xn----ue6i.xn--v80d6662t; ; ; # 𐳈-.𑄳
+𐲈-。𑄳񢌻; 𐳈-.𑄳񢌻; [B1, B3, P1, V3, V5, V6]; xn----ue6i.xn--v80d6662t; ; ; # 𐳈-.𑄳
+𐳈-。𑄳񢌻; 𐳈-.𑄳񢌻; [B1, B3, P1, V3, V5, V6]; xn----ue6i.xn--v80d6662t; ; ; # 𐳈-.𑄳
+xn----ue6i.xn--v80d6662t; 𐳈-.𑄳񢌻; [B1, B3, V3, V5, V6]; xn----ue6i.xn--v80d6662t; ; ; # 𐳈-.𑄳
+𐳈-。𑄳񢌻; 𐳈-.𑄳񢌻; [B1, B3, P1, V3, V5, V6]; xn----ue6i.xn--v80d6662t; ; ; # 𐳈-.𑄳
+-󠉖ꡧ.󠊂񇆃🄉; -󠉖ꡧ.󠊂񇆃🄉; [P1, V3, V6]; xn----hg4ei0361g.xn--207ht163h7m94c; ; ; # -ꡧ.🄉
+-󠉖ꡧ.󠊂񇆃8,; ; [P1, V3, V6]; xn----hg4ei0361g.xn--8,-k362evu488a; ; ; # -ꡧ.8,
+xn----hg4ei0361g.xn--8,-k362evu488a; -󠉖ꡧ.󠊂񇆃8,; [P1, V3, V6]; xn----hg4ei0361g.xn--8,-k362evu488a; ; ; # -ꡧ.8,
+xn----hg4ei0361g.xn--207ht163h7m94c; -󠉖ꡧ.󠊂񇆃🄉; [V3, V6]; xn----hg4ei0361g.xn--207ht163h7m94c; ; ; # -ꡧ.🄉
+󠾛󠈴臯𧔤.ݨ𝟝; 󠾛󠈴臯𧔤.ݨ5; [B1, P1, V6]; xn--zb1at733hm579ddhla.xn--5-b5c; ; ; # 臯𧔤.ݨ5
+󠾛󠈴臯𧔤.ݨ5; ; [B1, P1, V6]; xn--zb1at733hm579ddhla.xn--5-b5c; ; ; # 臯𧔤.ݨ5
+xn--zb1at733hm579ddhla.xn--5-b5c; 󠾛󠈴臯𧔤.ݨ5; [B1, V6]; xn--zb1at733hm579ddhla.xn--5-b5c; ; ; # 臯𧔤.ݨ5
+≮𐹣.𝨿; ≮𐹣.𝨿; [B1, B3, B6, P1, V5, V6]; xn--gdh1504g.xn--e92h; ; ; # ≮𐹣.𝨿
+≮𐹣.𝨿; ≮𐹣.𝨿; [B1, B3, B6, P1, V5, V6]; xn--gdh1504g.xn--e92h; ; ; # ≮𐹣.𝨿
+≮𐹣.𝨿; ; [B1, B3, B6, P1, V5, V6]; xn--gdh1504g.xn--e92h; ; ; # ≮𐹣.𝨿
+≮𐹣.𝨿; ≮𐹣.𝨿; [B1, B3, B6, P1, V5, V6]; xn--gdh1504g.xn--e92h; ; ; # ≮𐹣.𝨿
+xn--gdh1504g.xn--e92h; ≮𐹣.𝨿; [B1, B3, B6, V5, V6]; xn--gdh1504g.xn--e92h; ; ; # ≮𐹣.𝨿
+𐹯ᯛ੍。脥; 𐹯ᯛ੍.脥; [B1]; xn--ybc101g3m1p.xn--740a; ; ; # 𐹯ᯛ੍.脥
+𐹯ᯛ੍。脥; 𐹯ᯛ੍.脥; [B1]; xn--ybc101g3m1p.xn--740a; ; ; # 𐹯ᯛ੍.脥
+xn--ybc101g3m1p.xn--740a; 𐹯ᯛ੍.脥; [B1]; xn--ybc101g3m1p.xn--740a; ; ; # 𐹯ᯛ੍.脥
+᭄ᅟ𞷿򃀍.-; ; [B1, B5, P1, V3, V5, V6]; xn--osd971cpx70btgt8b.-; ; ; # ᭄.-
+xn--osd971cpx70btgt8b.-; ᭄ᅟ𞷿򃀍.-; [B1, B5, V3, V5, V6]; xn--osd971cpx70btgt8b.-; ; ; # ᭄.-
+‌。͔; ‌.͔; [C1, V5]; xn--0ug.xn--yua; ; .xn--yua; [V5, A4_2] # .͔
+‌。͔; ‌.͔; [C1, V5]; xn--0ug.xn--yua; ; .xn--yua; [V5, A4_2] # .͔
+.xn--yua; .͔; [V5, X4_2]; .xn--yua; [V5, A4_2]; ; # .͔
+xn--0ug.xn--yua; ‌.͔; [C1, V5]; xn--0ug.xn--yua; ; ; # .͔
+𞤥󠅮.ᡄႮ; 𞤥.ᡄႮ; [P1, V6]; xn--de6h.xn--mnd799a; ; ; # 𞤥.ᡄႮ
+𞤥󠅮.ᡄႮ; 𞤥.ᡄႮ; [P1, V6]; xn--de6h.xn--mnd799a; ; ; # 𞤥.ᡄႮ
+𞤥󠅮.ᡄⴎ; 𞤥.ᡄⴎ; ; xn--de6h.xn--37e857h; ; ; # 𞤥.ᡄⴎ
+𞤃󠅮.ᡄႮ; 𞤥.ᡄႮ; [P1, V6]; xn--de6h.xn--mnd799a; ; ; # 𞤥.ᡄႮ
+𞤃󠅮.ᡄⴎ; 𞤥.ᡄⴎ; ; xn--de6h.xn--37e857h; ; ; # 𞤥.ᡄⴎ
+xn--de6h.xn--37e857h; 𞤥.ᡄⴎ; ; xn--de6h.xn--37e857h; ; ; # 𞤥.ᡄⴎ
+𞤥.ᡄⴎ; ; ; xn--de6h.xn--37e857h; ; ; # 𞤥.ᡄⴎ
+𞤃.ᡄႮ; 𞤥.ᡄႮ; [P1, V6]; xn--de6h.xn--mnd799a; ; ; # 𞤥.ᡄႮ
+𞤃.ᡄⴎ; 𞤥.ᡄⴎ; ; xn--de6h.xn--37e857h; ; ; # 𞤥.ᡄⴎ
+xn--de6h.xn--mnd799a; 𞤥.ᡄႮ; [V6]; xn--de6h.xn--mnd799a; ; ; # 𞤥.ᡄႮ
+𞤥󠅮.ᡄⴎ; 𞤥.ᡄⴎ; ; xn--de6h.xn--37e857h; ; ; # 𞤥.ᡄⴎ
+𞤃󠅮.ᡄႮ; 𞤥.ᡄႮ; [P1, V6]; xn--de6h.xn--mnd799a; ; ; # 𞤥.ᡄႮ
+𞤃󠅮.ᡄⴎ; 𞤥.ᡄⴎ; ; xn--de6h.xn--37e857h; ; ; # 𞤥.ᡄⴎ
+𞤥.ᡄႮ; ; [P1, V6]; xn--de6h.xn--mnd799a; ; ; # 𞤥.ᡄႮ
+𞤧𝨨Ξ.𪺏㛨❸; 𞤧𝨨ξ.𪺏㛨❸; [B2, B3, B6]; xn--zxa5691vboja.xn--bfi293ci119b; ; ; # 𞤧𝨨ξ.𪺏㛨❸
+𞤧𝨨Ξ.𪺏㛨❸; 𞤧𝨨ξ.𪺏㛨❸; [B2, B3, B6]; xn--zxa5691vboja.xn--bfi293ci119b; ; ; # 𞤧𝨨ξ.𪺏㛨❸
+𞤧𝨨ξ.𪺏㛨❸; ; [B2, B3, B6]; xn--zxa5691vboja.xn--bfi293ci119b; ; ; # 𞤧𝨨ξ.𪺏㛨❸
+𞤅𝨨Ξ.𪺏㛨❸; 𞤧𝨨ξ.𪺏㛨❸; [B2, B3, B6]; xn--zxa5691vboja.xn--bfi293ci119b; ; ; # 𞤧𝨨ξ.𪺏㛨❸
+𞤅𝨨ξ.𪺏㛨❸; 𞤧𝨨ξ.𪺏㛨❸; [B2, B3, B6]; xn--zxa5691vboja.xn--bfi293ci119b; ; ; # 𞤧𝨨ξ.𪺏㛨❸
+xn--zxa5691vboja.xn--bfi293ci119b; 𞤧𝨨ξ.𪺏㛨❸; [B2, B3, B6]; xn--zxa5691vboja.xn--bfi293ci119b; ; ; # 𞤧𝨨ξ.𪺏㛨❸
+𞤧𝨨ξ.𪺏㛨❸; 𞤧𝨨ξ.𪺏㛨❸; [B2, B3, B6]; xn--zxa5691vboja.xn--bfi293ci119b; ; ; # 𞤧𝨨ξ.𪺏㛨❸
+𞤅𝨨Ξ.𪺏㛨❸; 𞤧𝨨ξ.𪺏㛨❸; [B2, B3, B6]; xn--zxa5691vboja.xn--bfi293ci119b; ; ; # 𞤧𝨨ξ.𪺏㛨❸
+𞤅𝨨ξ.𪺏㛨❸; 𞤧𝨨ξ.𪺏㛨❸; [B2, B3, B6]; xn--zxa5691vboja.xn--bfi293ci119b; ; ; # 𞤧𝨨ξ.𪺏㛨❸
+᠆몆‌-。Ⴛ𐦅︒; ᠆몆‌-.Ⴛ𐦅︒; [B1, B5, B6, C1, P1, V3, V6]; xn----e3j425bsk1o.xn--znd2362jhgh; ; xn----e3j6620g.xn--znd2362jhgh; [B1, B5, B6, P1, V3, V6] # ᠆몆-.Ⴛ𐦅︒
+᠆몆‌-。Ⴛ𐦅︒; ᠆몆‌-.Ⴛ𐦅︒; [B1, B5, B6, C1, P1, V3, V6]; xn----e3j425bsk1o.xn--znd2362jhgh; ; xn----e3j6620g.xn--znd2362jhgh; [B1, B5, B6, P1, V3, V6] # ᠆몆-.Ⴛ𐦅︒
+᠆몆‌-。Ⴛ𐦅。; ᠆몆‌-.Ⴛ𐦅.; [B1, B5, B6, C1, P1, V3, V6]; xn----e3j425bsk1o.xn--znd4948j.; ; xn----e3j6620g.xn--znd4948j.; [B1, B5, B6, P1, V3, V6] # ᠆몆-.Ⴛ𐦅.
+᠆몆‌-。Ⴛ𐦅。; ᠆몆‌-.Ⴛ𐦅.; [B1, B5, B6, C1, P1, V3, V6]; xn----e3j425bsk1o.xn--znd4948j.; ; xn----e3j6620g.xn--znd4948j.; [B1, B5, B6, P1, V3, V6] # ᠆몆-.Ⴛ𐦅.
+᠆몆‌-。ⴛ𐦅。; ᠆몆‌-.ⴛ𐦅.; [B1, B5, B6, C1, P1, V3, V6]; xn----e3j425bsk1o.xn--jlju661e.; ; xn----e3j6620g.xn--jlju661e.; [B1, B5, B6, P1, V3, V6] # ᠆몆-.ⴛ𐦅.
+᠆몆‌-。ⴛ𐦅。; ᠆몆‌-.ⴛ𐦅.; [B1, B5, B6, C1, P1, V3, V6]; xn----e3j425bsk1o.xn--jlju661e.; ; xn----e3j6620g.xn--jlju661e.; [B1, B5, B6, P1, V3, V6] # ᠆몆-.ⴛ𐦅.
+xn----e3j6620g.xn--jlju661e.; ᠆몆-.ⴛ𐦅.; [B1, B5, B6, V3, V6]; xn----e3j6620g.xn--jlju661e.; ; ; # ᠆몆-.ⴛ𐦅.
+xn----e3j425bsk1o.xn--jlju661e.; ᠆몆‌-.ⴛ𐦅.; [B1, B5, B6, C1, V3, V6]; xn----e3j425bsk1o.xn--jlju661e.; ; ; # ᠆몆-.ⴛ𐦅.
+xn----e3j6620g.xn--znd4948j.; ᠆몆-.Ⴛ𐦅.; [B1, B5, B6, V3, V6]; xn----e3j6620g.xn--znd4948j.; ; ; # ᠆몆-.Ⴛ𐦅.
+xn----e3j425bsk1o.xn--znd4948j.; ᠆몆‌-.Ⴛ𐦅.; [B1, B5, B6, C1, V3, V6]; xn----e3j425bsk1o.xn--znd4948j.; ; ; # ᠆몆-.Ⴛ𐦅.
+᠆몆‌-。ⴛ𐦅︒; ᠆몆‌-.ⴛ𐦅︒; [B1, B5, B6, C1, P1, V3, V6]; xn----e3j425bsk1o.xn--jlj4997dhgh; ; xn----e3j6620g.xn--jlj4997dhgh; [B1, B5, B6, P1, V3, V6] # ᠆몆-.ⴛ𐦅︒
+᠆몆‌-。ⴛ𐦅︒; ᠆몆‌-.ⴛ𐦅︒; [B1, B5, B6, C1, P1, V3, V6]; xn----e3j425bsk1o.xn--jlj4997dhgh; ; xn----e3j6620g.xn--jlj4997dhgh; [B1, B5, B6, P1, V3, V6] # ᠆몆-.ⴛ𐦅︒
+xn----e3j6620g.xn--jlj4997dhgh; ᠆몆-.ⴛ𐦅︒; [B1, B5, B6, V3, V6]; xn----e3j6620g.xn--jlj4997dhgh; ; ; # ᠆몆-.ⴛ𐦅︒
+xn----e3j425bsk1o.xn--jlj4997dhgh; ᠆몆‌-.ⴛ𐦅︒; [B1, B5, B6, C1, V3, V6]; xn----e3j425bsk1o.xn--jlj4997dhgh; ; ; # ᠆몆-.ⴛ𐦅︒
+xn----e3j6620g.xn--znd2362jhgh; ᠆몆-.Ⴛ𐦅︒; [B1, B5, B6, V3, V6]; xn----e3j6620g.xn--znd2362jhgh; ; ; # ᠆몆-.Ⴛ𐦅︒
+xn----e3j425bsk1o.xn--znd2362jhgh; ᠆몆‌-.Ⴛ𐦅︒; [B1, B5, B6, C1, V3, V6]; xn----e3j425bsk1o.xn--znd2362jhgh; ; ; # ᠆몆-.Ⴛ𐦅︒
+󠾳.︒⥱‌𐹬; ; [B1, C1, P1, V6]; xn--uf66e.xn--0ugz28axl3pqxna; ; xn--uf66e.xn--qtiz073e3ik; [B1, P1, V6] # .︒⥱𐹬
+󠾳.。⥱‌𐹬; 󠾳..⥱‌𐹬; [B1, C1, P1, V6, X4_2]; xn--uf66e..xn--0ugz28as66q; [B1, C1, P1, V6, A4_2]; xn--uf66e..xn--qti2829e; [B1, P1, V6, A4_2] # ..⥱𐹬
+xn--uf66e..xn--qti2829e; 󠾳..⥱𐹬; [B1, V6, X4_2]; xn--uf66e..xn--qti2829e; [B1, V6, A4_2]; ; # ..⥱𐹬
+xn--uf66e..xn--0ugz28as66q; 󠾳..⥱‌𐹬; [B1, C1, V6, X4_2]; xn--uf66e..xn--0ugz28as66q; [B1, C1, V6, A4_2]; ; # ..⥱𐹬
+xn--uf66e.xn--qtiz073e3ik; 󠾳.︒⥱𐹬; [B1, V6]; xn--uf66e.xn--qtiz073e3ik; ; ; # .︒⥱𐹬
+xn--uf66e.xn--0ugz28axl3pqxna; 󠾳.︒⥱‌𐹬; [B1, C1, V6]; xn--uf66e.xn--0ugz28axl3pqxna; ; ; # .︒⥱𐹬
+𐯖.𐹠Ⴑ񚇜𐫊; ; [B1, P1, V6]; xn--n49c.xn--pnd4619jwicl862o; ; ; # .𐹠Ⴑ𐫊
+𐯖.𐹠ⴑ񚇜𐫊; ; [B1, P1, V6]; xn--n49c.xn--8kj8702ewicl862o; ; ; # .𐹠ⴑ𐫊
+xn--n49c.xn--8kj8702ewicl862o; 𐯖.𐹠ⴑ񚇜𐫊; [B1, V6]; xn--n49c.xn--8kj8702ewicl862o; ; ; # .𐹠ⴑ𐫊
+xn--n49c.xn--pnd4619jwicl862o; 𐯖.𐹠Ⴑ񚇜𐫊; [B1, V6]; xn--n49c.xn--pnd4619jwicl862o; ; ; # .𐹠Ⴑ𐫊
+ྤ񱤯.𝟭Ⴛ; ྤ񱤯.1Ⴛ; [P1, V5, V6]; xn--0fd40533g.xn--1-q1g; ; ; # ྤ.1Ⴛ
+ྤ񱤯.1Ⴛ; ; [P1, V5, V6]; xn--0fd40533g.xn--1-q1g; ; ; # ྤ.1Ⴛ
+ྤ񱤯.1ⴛ; ; [P1, V5, V6]; xn--0fd40533g.xn--1-tws; ; ; # ྤ.1ⴛ
+xn--0fd40533g.xn--1-tws; ྤ񱤯.1ⴛ; [V5, V6]; xn--0fd40533g.xn--1-tws; ; ; # ྤ.1ⴛ
+xn--0fd40533g.xn--1-q1g; ྤ񱤯.1Ⴛ; [V5, V6]; xn--0fd40533g.xn--1-q1g; ; ; # ྤ.1Ⴛ
+ྤ񱤯.𝟭ⴛ; ྤ񱤯.1ⴛ; [P1, V5, V6]; xn--0fd40533g.xn--1-tws; ; ; # ྤ.1ⴛ
+-ࠦ齀。릿𐸋; -ࠦ齀.릿𐸋; [B1, B5, B6, P1, V3, V6]; xn----6gd0617i.xn--7y2bm55m; ; ; # -ࠦ齀.릿
+-ࠦ齀。릿𐸋; -ࠦ齀.릿𐸋; [B1, B5, B6, P1, V3, V6]; xn----6gd0617i.xn--7y2bm55m; ; ; # -ࠦ齀.릿
+xn----6gd0617i.xn--7y2bm55m; -ࠦ齀.릿𐸋; [B1, B5, B6, V3, V6]; xn----6gd0617i.xn--7y2bm55m; ; ; # -ࠦ齀.릿
+󠔊ܜ鹝꾗。񾵐‍‍⏃; 󠔊ܜ鹝꾗.񾵐‍‍⏃; [B1, B6, C2, P1, V6]; xn--mnb6558e91kyq533a.xn--1uga46zs309y; ; xn--mnb6558e91kyq533a.xn--6mh27269e; [B1, B6, P1, V6] # ܜ鹝꾗.⏃
+󠔊ܜ鹝꾗。񾵐‍‍⏃; 󠔊ܜ鹝꾗.񾵐‍‍⏃; [B1, B6, C2, P1, V6]; xn--mnb6558e91kyq533a.xn--1uga46zs309y; ; xn--mnb6558e91kyq533a.xn--6mh27269e; [B1, B6, P1, V6] # ܜ鹝꾗.⏃
+xn--mnb6558e91kyq533a.xn--6mh27269e; 󠔊ܜ鹝꾗.񾵐⏃; [B1, B6, V6]; xn--mnb6558e91kyq533a.xn--6mh27269e; ; ; # ܜ鹝꾗.⏃
+xn--mnb6558e91kyq533a.xn--1uga46zs309y; 󠔊ܜ鹝꾗.񾵐‍‍⏃; [B1, B6, C2, V6]; xn--mnb6558e91kyq533a.xn--1uga46zs309y; ; ; # ܜ鹝꾗.⏃
+≮.-܈--; ≮.-܈--; [B1, P1, V2, V3, V6]; xn--gdh.xn------eqf; ; ; # ≮.-܈--
+≮.-܈--; ≮.-܈--; [B1, P1, V2, V3, V6]; xn--gdh.xn------eqf; ; ; # ≮.-܈--
+≮.-܈--; ; [B1, P1, V2, V3, V6]; xn--gdh.xn------eqf; ; ; # ≮.-܈--
+≮.-܈--; ≮.-܈--; [B1, P1, V2, V3, V6]; xn--gdh.xn------eqf; ; ; # ≮.-܈--
+xn--gdh.xn------eqf; ≮.-܈--; [B1, V2, V3, V6]; xn--gdh.xn------eqf; ; ; # ≮.-܈--
+𐹸󠋳。‍ς𝟩; 𐹸󠋳.‍ς7; [B1, C2, P1, V6]; xn--wo0di5177c.xn--7-xmb248s; ; xn--wo0di5177c.xn--7-zmb; [B1, P1, V6] # 𐹸.ς7
+𐹸󠋳。‍ς7; 𐹸󠋳.‍ς7; [B1, C2, P1, V6]; xn--wo0di5177c.xn--7-xmb248s; ; xn--wo0di5177c.xn--7-zmb; [B1, P1, V6] # 𐹸.ς7
+𐹸󠋳。‍Σ7; 𐹸󠋳.‍σ7; [B1, C2, P1, V6]; xn--wo0di5177c.xn--7-zmb938s; ; xn--wo0di5177c.xn--7-zmb; [B1, P1, V6] # 𐹸.σ7
+𐹸󠋳。‍σ7; 𐹸󠋳.‍σ7; [B1, C2, P1, V6]; xn--wo0di5177c.xn--7-zmb938s; ; xn--wo0di5177c.xn--7-zmb; [B1, P1, V6] # 𐹸.σ7
+xn--wo0di5177c.xn--7-zmb; 𐹸󠋳.σ7; [B1, V6]; xn--wo0di5177c.xn--7-zmb; ; ; # 𐹸.σ7
+xn--wo0di5177c.xn--7-zmb938s; 𐹸󠋳.‍σ7; [B1, C2, V6]; xn--wo0di5177c.xn--7-zmb938s; ; ; # 𐹸.σ7
+xn--wo0di5177c.xn--7-xmb248s; 𐹸󠋳.‍ς7; [B1, C2, V6]; xn--wo0di5177c.xn--7-xmb248s; ; ; # 𐹸.ς7
+𐹸󠋳。‍Σ𝟩; 𐹸󠋳.‍σ7; [B1, C2, P1, V6]; xn--wo0di5177c.xn--7-zmb938s; ; xn--wo0di5177c.xn--7-zmb; [B1, P1, V6] # 𐹸.σ7
+𐹸󠋳。‍σ𝟩; 𐹸󠋳.‍σ7; [B1, C2, P1, V6]; xn--wo0di5177c.xn--7-zmb938s; ; xn--wo0di5177c.xn--7-zmb; [B1, P1, V6] # 𐹸.σ7
+ς򅜌8.𞭤; ς򅜌8.𞭤; [P1, V6]; xn--8-xmb44974n.xn--su6h; ; xn--8-zmb14974n.xn--su6h; # ς8.
+ς򅜌8.𞭤; ; [P1, V6]; xn--8-xmb44974n.xn--su6h; ; xn--8-zmb14974n.xn--su6h; # ς8.
+Σ򅜌8.𞭤; σ򅜌8.𞭤; [P1, V6]; xn--8-zmb14974n.xn--su6h; ; ; # σ8.
+σ򅜌8.𞭤; ; [P1, V6]; xn--8-zmb14974n.xn--su6h; ; ; # σ8.
+xn--8-zmb14974n.xn--su6h; σ򅜌8.𞭤; [V6]; xn--8-zmb14974n.xn--su6h; ; ; # σ8.
+xn--8-xmb44974n.xn--su6h; ς򅜌8.𞭤; [V6]; xn--8-xmb44974n.xn--su6h; ; ; # ς8.
+Σ򅜌8.𞭤; σ򅜌8.𞭤; [P1, V6]; xn--8-zmb14974n.xn--su6h; ; ; # σ8.
+σ򅜌8.𞭤; σ򅜌8.𞭤; [P1, V6]; xn--8-zmb14974n.xn--su6h; ; ; # σ8.
+‌ᡑ🄀ڄ.-𐫄𑲤; ‌ᡑ🄀ڄ.-𐫄𑲤; [B1, C1, P1, V3, V6]; xn--9ib722gvtfi563c.xn----ek5i065b; ; xn--9ib722gbw95a.xn----ek5i065b; [B1, B5, B6, P1, V3, V6] # ᡑ🄀ڄ.-𐫄𑲤
+‌ᡑ0.ڄ.-𐫄𑲤; ; [B1, C1, V3]; xn--0-o7j263b.xn--9ib.xn----ek5i065b; ; xn--0-o7j.xn--9ib.xn----ek5i065b; [B1, V3] # ᡑ0.ڄ.-𐫄𑲤
+xn--0-o7j.xn--9ib.xn----ek5i065b; ᡑ0.ڄ.-𐫄𑲤; [B1, V3]; xn--0-o7j.xn--9ib.xn----ek5i065b; ; ; # ᡑ0.ڄ.-𐫄𑲤
+xn--0-o7j263b.xn--9ib.xn----ek5i065b; ‌ᡑ0.ڄ.-𐫄𑲤; [B1, C1, V3]; xn--0-o7j263b.xn--9ib.xn----ek5i065b; ; ; # ᡑ0.ڄ.-𐫄𑲤
+xn--9ib722gbw95a.xn----ek5i065b; ᡑ🄀ڄ.-𐫄𑲤; [B1, B5, B6, V3, V6]; xn--9ib722gbw95a.xn----ek5i065b; ; ; # ᡑ🄀ڄ.-𐫄𑲤
+xn--9ib722gvtfi563c.xn----ek5i065b; ‌ᡑ🄀ڄ.-𐫄𑲤; [B1, C1, V3, V6]; xn--9ib722gvtfi563c.xn----ek5i065b; ; ; # ᡑ🄀ڄ.-𐫄𑲤
+𖠍。𐪿넯򞵲; 𖠍.𐪿넯򞵲; [B2, B3, P1, V6]; xn--4e9e.xn--l60bj21opd57g; ; ; # 𖠍.넯
+𖠍。𐪿넯򞵲; 𖠍.𐪿넯򞵲; [B2, B3, P1, V6]; xn--4e9e.xn--l60bj21opd57g; ; ; # 𖠍.넯
+xn--4e9e.xn--l60bj21opd57g; 𖠍.𐪿넯򞵲; [B2, B3, V6]; xn--4e9e.xn--l60bj21opd57g; ; ; # 𖠍.넯
+᠇Ⴘ。؃Ⴈ𝆊; ᠇Ⴘ.؃Ⴈ𝆊; [B1, P1, V6]; xn--wnd558a.xn--lfb465c1v87a; ; ; # ᠇Ⴘ.Ⴈ𝆊
+᠇ⴘ。؃ⴈ𝆊; ᠇ⴘ.؃ⴈ𝆊; [B1, P1, V6]; xn--d6e009h.xn--lfb290rfu3z; ; ; # ᠇ⴘ.ⴈ𝆊
+xn--d6e009h.xn--lfb290rfu3z; ᠇ⴘ.؃ⴈ𝆊; [B1, V6]; xn--d6e009h.xn--lfb290rfu3z; ; ; # ᠇ⴘ.ⴈ𝆊
+xn--wnd558a.xn--lfb465c1v87a; ᠇Ⴘ.؃Ⴈ𝆊; [B1, V6]; xn--wnd558a.xn--lfb465c1v87a; ; ; # ᠇Ⴘ.Ⴈ𝆊
+⒚󠋑𞤰。牣٧Ⴜᣥ; ⒚󠋑𞤰.牣٧Ⴜᣥ; [B1, B5, P1, V6]; xn--cthy466n29j3e.xn--gib404ccxgh00h; ; ; # ⒚𞤰.牣٧Ⴜᣥ
+19.󠋑𞤰。牣٧Ⴜᣥ; 19.󠋑𞤰.牣٧Ⴜᣥ; [B1, B5, P1, V6]; 19.xn--oe6h75760c.xn--gib404ccxgh00h; ; ; # 19.𞤰.牣٧Ⴜᣥ
+19.󠋑𞤰。牣٧ⴜᣥ; 19.󠋑𞤰.牣٧ⴜᣥ; [B1, B5, P1, V6]; 19.xn--oe6h75760c.xn--gib285gtxo2l9d; ; ; # 19.𞤰.牣٧ⴜᣥ
+19.󠋑𞤎。牣٧Ⴜᣥ; 19.󠋑𞤰.牣٧Ⴜᣥ; [B1, B5, P1, V6]; 19.xn--oe6h75760c.xn--gib404ccxgh00h; ; ; # 19.𞤰.牣٧Ⴜᣥ
+19.󠋑𞤎。牣٧ⴜᣥ; 19.󠋑𞤰.牣٧ⴜᣥ; [B1, B5, P1, V6]; 19.xn--oe6h75760c.xn--gib285gtxo2l9d; ; ; # 19.𞤰.牣٧ⴜᣥ
+19.xn--oe6h75760c.xn--gib285gtxo2l9d; 19.󠋑𞤰.牣٧ⴜᣥ; [B1, B5, V6]; 19.xn--oe6h75760c.xn--gib285gtxo2l9d; ; ; # 19.𞤰.牣٧ⴜᣥ
+19.xn--oe6h75760c.xn--gib404ccxgh00h; 19.󠋑𞤰.牣٧Ⴜᣥ; [B1, B5, V6]; 19.xn--oe6h75760c.xn--gib404ccxgh00h; ; ; # 19.𞤰.牣٧Ⴜᣥ
+⒚󠋑𞤰。牣٧ⴜᣥ; ⒚󠋑𞤰.牣٧ⴜᣥ; [B1, B5, P1, V6]; xn--cthy466n29j3e.xn--gib285gtxo2l9d; ; ; # ⒚𞤰.牣٧ⴜᣥ
+⒚󠋑𞤎。牣٧Ⴜᣥ; ⒚󠋑𞤰.牣٧Ⴜᣥ; [B1, B5, P1, V6]; xn--cthy466n29j3e.xn--gib404ccxgh00h; ; ; # ⒚𞤰.牣٧Ⴜᣥ
+⒚󠋑𞤎。牣٧ⴜᣥ; ⒚󠋑𞤰.牣٧ⴜᣥ; [B1, B5, P1, V6]; xn--cthy466n29j3e.xn--gib285gtxo2l9d; ; ; # ⒚𞤰.牣٧ⴜᣥ
+xn--cthy466n29j3e.xn--gib285gtxo2l9d; ⒚󠋑𞤰.牣٧ⴜᣥ; [B1, B5, V6]; xn--cthy466n29j3e.xn--gib285gtxo2l9d; ; ; # ⒚𞤰.牣٧ⴜᣥ
+xn--cthy466n29j3e.xn--gib404ccxgh00h; ⒚󠋑𞤰.牣٧Ⴜᣥ; [B1, B5, V6]; xn--cthy466n29j3e.xn--gib404ccxgh00h; ; ; # ⒚𞤰.牣٧Ⴜᣥ
+-𐋱𐰽⒈.Ⴓ; ; [B1, P1, V3, V6]; xn----ecp0206g90h.xn--rnd; ; ; # -𐋱𐰽⒈.Ⴓ
+-𐋱𐰽1..Ⴓ; ; [B1, P1, V3, V6, X4_2]; xn---1-895nq11a..xn--rnd; [B1, P1, V3, V6, A4_2]; ; # -𐋱𐰽1..Ⴓ
+-𐋱𐰽1..ⴓ; ; [B1, V3, X4_2]; xn---1-895nq11a..xn--blj; [B1, V3, A4_2]; ; # -𐋱𐰽1..ⴓ
+xn---1-895nq11a..xn--blj; -𐋱𐰽1..ⴓ; [B1, V3, X4_2]; xn---1-895nq11a..xn--blj; [B1, V3, A4_2]; ; # -𐋱𐰽1..ⴓ
+xn---1-895nq11a..xn--rnd; -𐋱𐰽1..Ⴓ; [B1, V3, V6, X4_2]; xn---1-895nq11a..xn--rnd; [B1, V3, V6, A4_2]; ; # -𐋱𐰽1..Ⴓ
+-𐋱𐰽⒈.ⴓ; ; [B1, P1, V3, V6]; xn----ecp0206g90h.xn--blj; ; ; # -𐋱𐰽⒈.ⴓ
+xn----ecp0206g90h.xn--blj; -𐋱𐰽⒈.ⴓ; [B1, V3, V6]; xn----ecp0206g90h.xn--blj; ; ; # -𐋱𐰽⒈.ⴓ
+xn----ecp0206g90h.xn--rnd; -𐋱𐰽⒈.Ⴓ; [B1, V3, V6]; xn----ecp0206g90h.xn--rnd; ; ; # -𐋱𐰽⒈.Ⴓ
+‌긃.榶-; ; [C1, V3]; xn--0ug3307c.xn----d87b; ; xn--ej0b.xn----d87b; [V3] # 긃.榶-
+‌긃.榶-; ‌긃.榶-; [C1, V3]; xn--0ug3307c.xn----d87b; ; xn--ej0b.xn----d87b; [V3] # 긃.榶-
+xn--ej0b.xn----d87b; 긃.榶-; [V3]; xn--ej0b.xn----d87b; ; ; # 긃.榶-
+xn--0ug3307c.xn----d87b; ‌긃.榶-; [C1, V3]; xn--0ug3307c.xn----d87b; ; ; # 긃.榶-
+뉓泓𜵽.্‍; ; [P1, V5, V6]; xn--lwwp69lqs7m.xn--b7b605i; ; xn--lwwp69lqs7m.xn--b7b; # 뉓泓.্
+뉓泓𜵽.্‍; 뉓泓𜵽.্‍; [P1, V5, V6]; xn--lwwp69lqs7m.xn--b7b605i; ; xn--lwwp69lqs7m.xn--b7b; # 뉓泓.্
+xn--lwwp69lqs7m.xn--b7b; 뉓泓𜵽.্; [V5, V6]; xn--lwwp69lqs7m.xn--b7b; ; ; # 뉓泓.্
+xn--lwwp69lqs7m.xn--b7b605i; 뉓泓𜵽.্‍; [V5, V6]; xn--lwwp69lqs7m.xn--b7b605i; ; ; # 뉓泓.্
+‍𐹴ß。ິ⭵񪅌; ‍𐹴ß.ິ⭵񪅌; [B1, C2, P1, V5, V6]; xn--zca770nip7n.xn--57c638l8774i; ; xn--ss-ti3o.xn--57c638l8774i; [B1, P1, V5, V6] # 𐹴ß.ິ
+‍𐹴ß。ິ⭵񪅌; ‍𐹴ß.ິ⭵񪅌; [B1, C2, P1, V5, V6]; xn--zca770nip7n.xn--57c638l8774i; ; xn--ss-ti3o.xn--57c638l8774i; [B1, P1, V5, V6] # 𐹴ß.ິ
+‍𐹴SS。ິ⭵񪅌; ‍𐹴ss.ິ⭵񪅌; [B1, C2, P1, V5, V6]; xn--ss-l1t5169j.xn--57c638l8774i; ; xn--ss-ti3o.xn--57c638l8774i; [B1, P1, V5, V6] # 𐹴ss.ິ
+‍𐹴ss。ິ⭵񪅌; ‍𐹴ss.ິ⭵񪅌; [B1, C2, P1, V5, V6]; xn--ss-l1t5169j.xn--57c638l8774i; ; xn--ss-ti3o.xn--57c638l8774i; [B1, P1, V5, V6] # 𐹴ss.ິ
+‍𐹴Ss。ິ⭵񪅌; ‍𐹴ss.ິ⭵񪅌; [B1, C2, P1, V5, V6]; xn--ss-l1t5169j.xn--57c638l8774i; ; xn--ss-ti3o.xn--57c638l8774i; [B1, P1, V5, V6] # 𐹴ss.ິ
+xn--ss-ti3o.xn--57c638l8774i; 𐹴ss.ິ⭵񪅌; [B1, V5, V6]; xn--ss-ti3o.xn--57c638l8774i; ; ; # 𐹴ss.ິ
+xn--ss-l1t5169j.xn--57c638l8774i; ‍𐹴ss.ິ⭵񪅌; [B1, C2, V5, V6]; xn--ss-l1t5169j.xn--57c638l8774i; ; ; # 𐹴ss.ິ
+xn--zca770nip7n.xn--57c638l8774i; ‍𐹴ß.ິ⭵񪅌; [B1, C2, V5, V6]; xn--zca770nip7n.xn--57c638l8774i; ; ; # 𐹴ß.ິ
+‍𐹴SS。ິ⭵񪅌; ‍𐹴ss.ິ⭵񪅌; [B1, C2, P1, V5, V6]; xn--ss-l1t5169j.xn--57c638l8774i; ; xn--ss-ti3o.xn--57c638l8774i; [B1, P1, V5, V6] # 𐹴ss.ິ
+‍𐹴ss。ິ⭵񪅌; ‍𐹴ss.ິ⭵񪅌; [B1, C2, P1, V5, V6]; xn--ss-l1t5169j.xn--57c638l8774i; ; xn--ss-ti3o.xn--57c638l8774i; [B1, P1, V5, V6] # 𐹴ss.ິ
+‍𐹴Ss。ິ⭵񪅌; ‍𐹴ss.ິ⭵񪅌; [B1, C2, P1, V5, V6]; xn--ss-l1t5169j.xn--57c638l8774i; ; xn--ss-ti3o.xn--57c638l8774i; [B1, P1, V5, V6] # 𐹴ss.ິ
+᭄.᮪-≮≠; ᭄.᮪-≮≠; [P1, V5, V6]; xn--1uf.xn----nmlz65aub; ; ; # ᭄.᮪-≮≠
+᭄.᮪-≮≠; ᭄.᮪-≮≠; [P1, V5, V6]; xn--1uf.xn----nmlz65aub; ; ; # ᭄.᮪-≮≠
+᭄.᮪-≮≠; ; [P1, V5, V6]; xn--1uf.xn----nmlz65aub; ; ; # ᭄.᮪-≮≠
+᭄.᮪-≮≠; ᭄.᮪-≮≠; [P1, V5, V6]; xn--1uf.xn----nmlz65aub; ; ; # ᭄.᮪-≮≠
+xn--1uf.xn----nmlz65aub; ᭄.᮪-≮≠; [V5, V6]; xn--1uf.xn----nmlz65aub; ; ; # ᭄.᮪-≮≠
+᯳Ⴑᅟ.𑄴Ⅎ; ᯳Ⴑᅟ.𑄴Ⅎ; [P1, V5, V6]; xn--pnd26a55x.xn--f3g7465g; ; ; # ᯳Ⴑ.𑄴Ⅎ
+᯳Ⴑᅟ.𑄴Ⅎ; ; [P1, V5, V6]; xn--pnd26a55x.xn--f3g7465g; ; ; # ᯳Ⴑ.𑄴Ⅎ
+᯳ⴑᅟ.𑄴ⅎ; ; [P1, V5, V6]; xn--osd925cvyn.xn--73g3065g; ; ; # ᯳ⴑ.𑄴ⅎ
+᯳Ⴑᅟ.𑄴ⅎ; ; [P1, V5, V6]; xn--pnd26a55x.xn--73g3065g; ; ; # ᯳Ⴑ.𑄴ⅎ
+xn--pnd26a55x.xn--73g3065g; ᯳Ⴑᅟ.𑄴ⅎ; [V5, V6]; xn--pnd26a55x.xn--73g3065g; ; ; # ᯳Ⴑ.𑄴ⅎ
+xn--osd925cvyn.xn--73g3065g; ᯳ⴑᅟ.𑄴ⅎ; [V5, V6]; xn--osd925cvyn.xn--73g3065g; ; ; # ᯳ⴑ.𑄴ⅎ
+xn--pnd26a55x.xn--f3g7465g; ᯳Ⴑᅟ.𑄴Ⅎ; [V5, V6]; xn--pnd26a55x.xn--f3g7465g; ; ; # ᯳Ⴑ.𑄴Ⅎ
+᯳ⴑᅟ.𑄴ⅎ; ᯳ⴑᅟ.𑄴ⅎ; [P1, V5, V6]; xn--osd925cvyn.xn--73g3065g; ; ; # ᯳ⴑ.𑄴ⅎ
+᯳Ⴑᅟ.𑄴ⅎ; ᯳Ⴑᅟ.𑄴ⅎ; [P1, V5, V6]; xn--pnd26a55x.xn--73g3065g; ; ; # ᯳Ⴑ.𑄴ⅎ
+𜉆。Ⴃ𐴣𐹹똯; 𜉆.Ⴃ𐴣𐹹똯; [B5, P1, V6]; xn--187g.xn--bnd4785f8r8bdeb; ; ; # .Ⴃ𐴣𐹹똯
+𜉆。Ⴃ𐴣𐹹똯; 𜉆.Ⴃ𐴣𐹹똯; [B5, P1, V6]; xn--187g.xn--bnd4785f8r8bdeb; ; ; # .Ⴃ𐴣𐹹똯
+𜉆。ⴃ𐴣𐹹똯; 𜉆.ⴃ𐴣𐹹똯; [B5, P1, V6]; xn--187g.xn--ukjy205b8rscdeb; ; ; # .ⴃ𐴣𐹹똯
+𜉆。ⴃ𐴣𐹹똯; 𜉆.ⴃ𐴣𐹹똯; [B5, P1, V6]; xn--187g.xn--ukjy205b8rscdeb; ; ; # .ⴃ𐴣𐹹똯
+xn--187g.xn--ukjy205b8rscdeb; 𜉆.ⴃ𐴣𐹹똯; [B5, V6]; xn--187g.xn--ukjy205b8rscdeb; ; ; # .ⴃ𐴣𐹹똯
+xn--187g.xn--bnd4785f8r8bdeb; 𜉆.Ⴃ𐴣𐹹똯; [B5, V6]; xn--187g.xn--bnd4785f8r8bdeb; ; ; # .Ⴃ𐴣𐹹똯
+𐫀。⳻󠙾󠄷ㅤ; 𐫀.⳻󠙾ㅤ; [B1, P1, V6]; xn--pw9c.xn--mkj83l4v899a; ; ; # 𐫀.⳻
+𐫀。⳻󠙾󠄷ᅠ; 𐫀.⳻󠙾ᅠ; [B1, P1, V6]; xn--pw9c.xn--psd742lxt32w; ; ; # 𐫀.⳻
+xn--pw9c.xn--psd742lxt32w; 𐫀.⳻󠙾ᅠ; [B1, V6]; xn--pw9c.xn--psd742lxt32w; ; ; # 𐫀.⳻
+xn--pw9c.xn--mkj83l4v899a; 𐫀.⳻󠙾ㅤ; [B1, V6]; xn--pw9c.xn--mkj83l4v899a; ; ; # 𐫀.⳻
+ޚ⾇.ܞ-𐋰; ޚ舛.ܞ-𐋰; [B2, B3]; xn--7qb6383d.xn----20c3154q; ; ; # ޚ舛.ܞ-𐋰
+ޚ舛.ܞ-𐋰; ; [B2, B3]; xn--7qb6383d.xn----20c3154q; ; ; # ޚ舛.ܞ-𐋰
+xn--7qb6383d.xn----20c3154q; ޚ舛.ܞ-𐋰; [B2, B3]; xn--7qb6383d.xn----20c3154q; ; ; # ޚ舛.ܞ-𐋰
+Ⴉ猕󹛫≮.︒; Ⴉ猕󹛫≮.︒; [P1, V6]; xn--hnd212gz32d54x5r.xn--y86c; ; ; # Ⴉ猕≮.︒
+Ⴉ猕󹛫≮.︒; Ⴉ猕󹛫≮.︒; [P1, V6]; xn--hnd212gz32d54x5r.xn--y86c; ; ; # Ⴉ猕≮.︒
+Ⴉ猕󹛫≮.。; Ⴉ猕󹛫≮..; [P1, V6, X4_2]; xn--hnd212gz32d54x5r..; [P1, V6, A4_2]; ; # Ⴉ猕≮..
+Ⴉ猕󹛫≮.。; Ⴉ猕󹛫≮..; [P1, V6, X4_2]; xn--hnd212gz32d54x5r..; [P1, V6, A4_2]; ; # Ⴉ猕≮..
+ⴉ猕󹛫≮.。; ⴉ猕󹛫≮..; [P1, V6, X4_2]; xn--gdh892bbz0d5438s..; [P1, V6, A4_2]; ; # ⴉ猕≮..
+ⴉ猕󹛫≮.。; ⴉ猕󹛫≮..; [P1, V6, X4_2]; xn--gdh892bbz0d5438s..; [P1, V6, A4_2]; ; # ⴉ猕≮..
+xn--gdh892bbz0d5438s..; ⴉ猕󹛫≮..; [V6, X4_2]; xn--gdh892bbz0d5438s..; [V6, A4_2]; ; # ⴉ猕≮..
+xn--hnd212gz32d54x5r..; Ⴉ猕󹛫≮..; [V6, X4_2]; xn--hnd212gz32d54x5r..; [V6, A4_2]; ; # Ⴉ猕≮..
+ⴉ猕󹛫≮.︒; ⴉ猕󹛫≮.︒; [P1, V6]; xn--gdh892bbz0d5438s.xn--y86c; ; ; # ⴉ猕≮.︒
+ⴉ猕󹛫≮.︒; ⴉ猕󹛫≮.︒; [P1, V6]; xn--gdh892bbz0d5438s.xn--y86c; ; ; # ⴉ猕≮.︒
+xn--gdh892bbz0d5438s.xn--y86c; ⴉ猕󹛫≮.︒; [V6]; xn--gdh892bbz0d5438s.xn--y86c; ; ; # ⴉ猕≮.︒
+xn--hnd212gz32d54x5r.xn--y86c; Ⴉ猕󹛫≮.︒; [V6]; xn--hnd212gz32d54x5r.xn--y86c; ; ; # Ⴉ猕≮.︒
+🏮。ث鳳ߢ󠅉; 🏮.ث鳳ߢ; [B1, B2]; xn--8m8h.xn--qgb29f6z90a; ; ; # 🏮.ث鳳ߢ
+🏮。ث鳳ߢ󠅉; 🏮.ث鳳ߢ; [B1, B2]; xn--8m8h.xn--qgb29f6z90a; ; ; # 🏮.ث鳳ߢ
+xn--8m8h.xn--qgb29f6z90a; 🏮.ث鳳ߢ; [B1, B2]; xn--8m8h.xn--qgb29f6z90a; ; ; # 🏮.ث鳳ߢ
+‍𐹶。ß; ‍𐹶.ß; [B1, C2]; xn--1ug9105g.xn--zca; ; xn--uo0d.ss; [B1] # 𐹶.ß
+‍𐹶。SS; ‍𐹶.ss; [B1, C2]; xn--1ug9105g.ss; ; xn--uo0d.ss; [B1] # 𐹶.ss
+‍𐹶。ss; ‍𐹶.ss; [B1, C2]; xn--1ug9105g.ss; ; xn--uo0d.ss; [B1] # 𐹶.ss
+‍𐹶。Ss; ‍𐹶.ss; [B1, C2]; xn--1ug9105g.ss; ; xn--uo0d.ss; [B1] # 𐹶.ss
+xn--uo0d.ss; 𐹶.ss; [B1]; xn--uo0d.ss; ; ; # 𐹶.ss
+xn--1ug9105g.ss; ‍𐹶.ss; [B1, C2]; xn--1ug9105g.ss; ; ; # 𐹶.ss
+xn--1ug9105g.xn--zca; ‍𐹶.ß; [B1, C2]; xn--1ug9105g.xn--zca; ; ; # 𐹶.ß
+Å둄-.‌; å둄-.‌; [C1, V3]; xn----1fa1788k.xn--0ug; ; xn----1fa1788k.; [V3] # å둄-.
+Å둄-.‌; å둄-.‌; [C1, V3]; xn----1fa1788k.xn--0ug; ; xn----1fa1788k.; [V3] # å둄-.
+Å둄-.‌; å둄-.‌; [C1, V3]; xn----1fa1788k.xn--0ug; ; xn----1fa1788k.; [V3] # å둄-.
+Å둄-.‌; å둄-.‌; [C1, V3]; xn----1fa1788k.xn--0ug; ; xn----1fa1788k.; [V3] # å둄-.
+å둄-.‌; å둄-.‌; [C1, V3]; xn----1fa1788k.xn--0ug; ; xn----1fa1788k.; [V3] # å둄-.
+å둄-.‌; ; [C1, V3]; xn----1fa1788k.xn--0ug; ; xn----1fa1788k.; [V3] # å둄-.
+xn----1fa1788k.; å둄-.; [V3]; xn----1fa1788k.; ; ; # å둄-.
+xn----1fa1788k.xn--0ug; å둄-.‌; [C1, V3]; xn----1fa1788k.xn--0ug; ; ; # å둄-.
+å둄-.‌; å둄-.‌; [C1, V3]; xn----1fa1788k.xn--0ug; ; xn----1fa1788k.; [V3] # å둄-.
+å둄-.‌; å둄-.‌; [C1, V3]; xn----1fa1788k.xn--0ug; ; xn----1fa1788k.; [V3] # å둄-.
+゙򬎑ᷗ𞤀.򱲢-॓; ゙򬎑ᷗ𞤢.򱲢-॓; [B1, B6, P1, V5, V6]; xn--veg121fwg63altj9d.xn----eyd92688s; ; ; # ゙ᷗ𞤢.-॓
+゙򬎑ᷗ𞤢.򱲢-॓; ; [B1, B6, P1, V5, V6]; xn--veg121fwg63altj9d.xn----eyd92688s; ; ; # ゙ᷗ𞤢.-॓
+xn--veg121fwg63altj9d.xn----eyd92688s; ゙򬎑ᷗ𞤢.򱲢-॓; [B1, B6, V5, V6]; xn--veg121fwg63altj9d.xn----eyd92688s; ; ; # ゙ᷗ𞤢.-॓
+ς.ß񴱄۝⵿; ; [B5, B6, P1, V6]; xn--3xa.xn--zca281az71b8x73m; ; xn--4xa.xn--ss-y8d4760biv60n; # ς.ß⵿
+Σ.SS񴱄۝⵿; σ.ss񴱄۝⵿; [B5, B6, P1, V6]; xn--4xa.xn--ss-y8d4760biv60n; ; ; # σ.ss⵿
+σ.ss񴱄۝⵿; ; [B5, B6, P1, V6]; xn--4xa.xn--ss-y8d4760biv60n; ; ; # σ.ss⵿
+Σ.ss񴱄۝⵿; σ.ss񴱄۝⵿; [B5, B6, P1, V6]; xn--4xa.xn--ss-y8d4760biv60n; ; ; # σ.ss⵿
+xn--4xa.xn--ss-y8d4760biv60n; σ.ss񴱄۝⵿; [B5, B6, V6]; xn--4xa.xn--ss-y8d4760biv60n; ; ; # σ.ss⵿
+Σ.ß񴱄۝⵿; σ.ß񴱄۝⵿; [B5, B6, P1, V6]; xn--4xa.xn--zca281az71b8x73m; ; xn--4xa.xn--ss-y8d4760biv60n; # σ.ß⵿
+σ.ß񴱄۝⵿; ; [B5, B6, P1, V6]; xn--4xa.xn--zca281az71b8x73m; ; xn--4xa.xn--ss-y8d4760biv60n; # σ.ß⵿
+xn--4xa.xn--zca281az71b8x73m; σ.ß񴱄۝⵿; [B5, B6, V6]; xn--4xa.xn--zca281az71b8x73m; ; ; # σ.ß⵿
+xn--3xa.xn--zca281az71b8x73m; ς.ß񴱄۝⵿; [B5, B6, V6]; xn--3xa.xn--zca281az71b8x73m; ; ; # ς.ß⵿
+ꡀ𞀟。٫֙; ꡀ𞀟.٫֙; [B1]; xn--8b9a1720d.xn--kcb33b; ; ; # ꡀ𞀟.٫֙
+ꡀ𞀟。٫֙; ꡀ𞀟.٫֙; [B1]; xn--8b9a1720d.xn--kcb33b; ; ; # ꡀ𞀟.٫֙
+xn--8b9a1720d.xn--kcb33b; ꡀ𞀟.٫֙; [B1]; xn--8b9a1720d.xn--kcb33b; ; ; # ꡀ𞀟.٫֙
+򈛉‌ࢩ。⧅񘘡-𐭡; 򈛉‌ࢩ.⧅񘘡-𐭡; [B1, B5, B6, C1, P1, V6]; xn--yyb780jll63m.xn----zir1232guu71b; ; xn--yyb56242i.xn----zir1232guu71b; [B1, B5, B6, P1, V6] # ࢩ.⧅-𐭡
+򈛉‌ࢩ。⧅񘘡-𐭡; 򈛉‌ࢩ.⧅񘘡-𐭡; [B1, B5, B6, C1, P1, V6]; xn--yyb780jll63m.xn----zir1232guu71b; ; xn--yyb56242i.xn----zir1232guu71b; [B1, B5, B6, P1, V6] # ࢩ.⧅-𐭡
+xn--yyb56242i.xn----zir1232guu71b; 򈛉ࢩ.⧅񘘡-𐭡; [B1, B5, B6, V6]; xn--yyb56242i.xn----zir1232guu71b; ; ; # ࢩ.⧅-𐭡
+xn--yyb780jll63m.xn----zir1232guu71b; 򈛉‌ࢩ.⧅񘘡-𐭡; [B1, B5, B6, C1, V6]; xn--yyb780jll63m.xn----zir1232guu71b; ; ; # ࢩ.⧅-𐭡
+룱‍𰍨‌。𝨖︒; 룱‍𰍨‌.𝨖︒; [C1, C2, P1, V5, V6]; xn--0ugb3358ili2v.xn--y86cl899a; ; xn--ct2b0738h.xn--y86cl899a; [P1, V5, V6] # 룱𰍨.𝨖︒
+룱‍𰍨‌。𝨖︒; 룱‍𰍨‌.𝨖︒; [C1, C2, P1, V5, V6]; xn--0ugb3358ili2v.xn--y86cl899a; ; xn--ct2b0738h.xn--y86cl899a; [P1, V5, V6] # 룱𰍨.𝨖︒
+룱‍𰍨‌。𝨖。; 룱‍𰍨‌.𝨖.; [C1, C2, V5]; xn--0ugb3358ili2v.xn--772h.; ; xn--ct2b0738h.xn--772h.; [V5] # 룱𰍨.𝨖.
+룱‍𰍨‌。𝨖。; 룱‍𰍨‌.𝨖.; [C1, C2, V5]; xn--0ugb3358ili2v.xn--772h.; ; xn--ct2b0738h.xn--772h.; [V5] # 룱𰍨.𝨖.
+xn--ct2b0738h.xn--772h.; 룱𰍨.𝨖.; [V5]; xn--ct2b0738h.xn--772h.; ; ; # 룱𰍨.𝨖.
+xn--0ugb3358ili2v.xn--772h.; 룱‍𰍨‌.𝨖.; [C1, C2, V5]; xn--0ugb3358ili2v.xn--772h.; ; ; # 룱𰍨.𝨖.
+xn--ct2b0738h.xn--y86cl899a; 룱𰍨.𝨖︒; [V5, V6]; xn--ct2b0738h.xn--y86cl899a; ; ; # 룱𰍨.𝨖︒
+xn--0ugb3358ili2v.xn--y86cl899a; 룱‍𰍨‌.𝨖︒; [C1, C2, V5, V6]; xn--0ugb3358ili2v.xn--y86cl899a; ; ; # 룱𰍨.𝨖︒
+🄄.᳜⒈ß; 🄄.᳜⒈ß; [P1, V5, V6]; xn--x07h.xn--zca344lmif; ; xn--x07h.xn--ss-k1r094b; # 🄄.᳜⒈ß
+3,.᳜1.ß; ; [P1, V5, V6]; 3,.xn--1-43l.xn--zca; ; 3,.xn--1-43l.ss; # 3,.᳜1.ß
+3,.᳜1.SS; 3,.᳜1.ss; [P1, V5, V6]; 3,.xn--1-43l.ss; ; ; # 3,.᳜1.ss
+3,.᳜1.ss; ; [P1, V5, V6]; 3,.xn--1-43l.ss; ; ; # 3,.᳜1.ss
+3,.᳜1.Ss; 3,.᳜1.ss; [P1, V5, V6]; 3,.xn--1-43l.ss; ; ; # 3,.᳜1.ss
+3,.xn--1-43l.ss; 3,.᳜1.ss; [P1, V5, V6]; 3,.xn--1-43l.ss; ; ; # 3,.᳜1.ss
+3,.xn--1-43l.xn--zca; 3,.᳜1.ß; [P1, V5, V6]; 3,.xn--1-43l.xn--zca; ; ; # 3,.᳜1.ß
+🄄.᳜⒈SS; 🄄.᳜⒈ss; [P1, V5, V6]; xn--x07h.xn--ss-k1r094b; ; ; # 🄄.᳜⒈ss
+🄄.᳜⒈ss; 🄄.᳜⒈ss; [P1, V5, V6]; xn--x07h.xn--ss-k1r094b; ; ; # 🄄.᳜⒈ss
+🄄.᳜⒈Ss; 🄄.᳜⒈ss; [P1, V5, V6]; xn--x07h.xn--ss-k1r094b; ; ; # 🄄.᳜⒈ss
+xn--x07h.xn--ss-k1r094b; 🄄.᳜⒈ss; [V5, V6]; xn--x07h.xn--ss-k1r094b; ; ; # 🄄.᳜⒈ss
+xn--x07h.xn--zca344lmif; 🄄.᳜⒈ß; [V5, V6]; xn--x07h.xn--zca344lmif; ; ; # 🄄.᳜⒈ß
+񇌍⵿。𞼓򡄨𑐺; 񇌍⵿.𞼓򡄨𑐺; [B2, B3, P1, V6]; xn--eoj16016a.xn--0v1d3848a3lr0d; ; ; # ⵿.𑐺
+񇌍⵿。𞼓򡄨𑐺; 񇌍⵿.𞼓򡄨𑐺; [B2, B3, P1, V6]; xn--eoj16016a.xn--0v1d3848a3lr0d; ; ; # ⵿.𑐺
+xn--eoj16016a.xn--0v1d3848a3lr0d; 񇌍⵿.𞼓򡄨𑐺; [B2, B3, V6]; xn--eoj16016a.xn--0v1d3848a3lr0d; ; ; # ⵿.𑐺
+်्᷽.≠‍㇛; ်्᷽.≠‍㇛; [C2, P1, V5, V6]; xn--n3b956a9zm.xn--1ug63gz5w; ; xn--n3b956a9zm.xn--1ch912d; [P1, V5, V6] # ်्᷽.≠㇛
+်्᷽.≠‍㇛; ်्᷽.≠‍㇛; [C2, P1, V5, V6]; xn--n3b956a9zm.xn--1ug63gz5w; ; xn--n3b956a9zm.xn--1ch912d; [P1, V5, V6] # ်्᷽.≠㇛
+်्᷽.≠‍㇛; ်्᷽.≠‍㇛; [C2, P1, V5, V6]; xn--n3b956a9zm.xn--1ug63gz5w; ; xn--n3b956a9zm.xn--1ch912d; [P1, V5, V6] # ်्᷽.≠㇛
+်्᷽.≠‍㇛; ; [C2, P1, V5, V6]; xn--n3b956a9zm.xn--1ug63gz5w; ; xn--n3b956a9zm.xn--1ch912d; [P1, V5, V6] # ်्᷽.≠㇛
+်्᷽.≠‍㇛; ်्᷽.≠‍㇛; [C2, P1, V5, V6]; xn--n3b956a9zm.xn--1ug63gz5w; ; xn--n3b956a9zm.xn--1ch912d; [P1, V5, V6] # ်्᷽.≠㇛
+xn--n3b956a9zm.xn--1ch912d; ်्᷽.≠㇛; [V5, V6]; xn--n3b956a9zm.xn--1ch912d; ; ; # ်्᷽.≠㇛
+xn--n3b956a9zm.xn--1ug63gz5w; ်्᷽.≠‍㇛; [C2, V5, V6]; xn--n3b956a9zm.xn--1ug63gz5w; ; ; # ်्᷽.≠㇛
+Ⴁ𐋨娤.‍̼٢𑖿; ; [B1, C2, P1, V6]; xn--8md2578ag21g.xn--9ta62ngt6aou8t; ; xn--8md2578ag21g.xn--9ta62nrv36a; [B1, P1, V5, V6] # Ⴁ𐋨娤.̼٢𑖿
+ⴁ𐋨娤.‍̼٢𑖿; ; [B1, C2]; xn--skjw75lg29h.xn--9ta62ngt6aou8t; ; xn--skjw75lg29h.xn--9ta62nrv36a; [B1, V5] # ⴁ𐋨娤.̼٢𑖿
+xn--skjw75lg29h.xn--9ta62nrv36a; ⴁ𐋨娤.̼٢𑖿; [B1, V5]; xn--skjw75lg29h.xn--9ta62nrv36a; ; ; # ⴁ𐋨娤.̼٢𑖿
+xn--skjw75lg29h.xn--9ta62ngt6aou8t; ⴁ𐋨娤.‍̼٢𑖿; [B1, C2]; xn--skjw75lg29h.xn--9ta62ngt6aou8t; ; ; # ⴁ𐋨娤.̼٢𑖿
+xn--8md2578ag21g.xn--9ta62nrv36a; Ⴁ𐋨娤.̼٢𑖿; [B1, V5, V6]; xn--8md2578ag21g.xn--9ta62nrv36a; ; ; # Ⴁ𐋨娤.̼٢𑖿
+xn--8md2578ag21g.xn--9ta62ngt6aou8t; Ⴁ𐋨娤.‍̼٢𑖿; [B1, C2, V6]; xn--8md2578ag21g.xn--9ta62ngt6aou8t; ; ; # Ⴁ𐋨娤.̼٢𑖿
+🄀Ⴄ٩ࠠ。⒈ྶß; 🄀Ⴄ٩ࠠ.⒈ྶß; [B1, P1, V6]; xn--iib29f26o6n43c.xn--zca117e3vp; ; xn--iib29f26o6n43c.xn--ss-1sj588o; # 🄀Ⴄ٩ࠠ.⒈ྶß
+0.Ⴄ٩ࠠ。1.ྶß; 0.Ⴄ٩ࠠ.1.ྶß; [B1, B5, B6, P1, V5, V6]; 0.xn--iib29f26o.1.xn--zca117e; ; 0.xn--iib29f26o.1.xn--ss-1sj; # 0.Ⴄ٩ࠠ.1.ྶß
+0.ⴄ٩ࠠ。1.ྶß; 0.ⴄ٩ࠠ.1.ྶß; [B1, B5, B6, V5]; 0.xn--iib29fp25e.1.xn--zca117e; ; 0.xn--iib29fp25e.1.xn--ss-1sj; # 0.ⴄ٩ࠠ.1.ྶß
+0.Ⴄ٩ࠠ。1.ྶSS; 0.Ⴄ٩ࠠ.1.ྶss; [B1, B5, B6, P1, V5, V6]; 0.xn--iib29f26o.1.xn--ss-1sj; ; ; # 0.Ⴄ٩ࠠ.1.ྶss
+0.ⴄ٩ࠠ。1.ྶss; 0.ⴄ٩ࠠ.1.ྶss; [B1, B5, B6, V5]; 0.xn--iib29fp25e.1.xn--ss-1sj; ; ; # 0.ⴄ٩ࠠ.1.ྶss
+0.Ⴄ٩ࠠ。1.ྶSs; 0.Ⴄ٩ࠠ.1.ྶss; [B1, B5, B6, P1, V5, V6]; 0.xn--iib29f26o.1.xn--ss-1sj; ; ; # 0.Ⴄ٩ࠠ.1.ྶss
+0.xn--iib29f26o.1.xn--ss-1sj; 0.Ⴄ٩ࠠ.1.ྶss; [B1, B5, B6, V5, V6]; 0.xn--iib29f26o.1.xn--ss-1sj; ; ; # 0.Ⴄ٩ࠠ.1.ྶss
+0.xn--iib29fp25e.1.xn--ss-1sj; 0.ⴄ٩ࠠ.1.ྶss; [B1, B5, B6, V5]; 0.xn--iib29fp25e.1.xn--ss-1sj; ; ; # 0.ⴄ٩ࠠ.1.ྶss
+0.xn--iib29fp25e.1.xn--zca117e; 0.ⴄ٩ࠠ.1.ྶß; [B1, B5, B6, V5]; 0.xn--iib29fp25e.1.xn--zca117e; ; ; # 0.ⴄ٩ࠠ.1.ྶß
+0.xn--iib29f26o.1.xn--zca117e; 0.Ⴄ٩ࠠ.1.ྶß; [B1, B5, B6, V5, V6]; 0.xn--iib29f26o.1.xn--zca117e; ; ; # 0.Ⴄ٩ࠠ.1.ྶß
+🄀ⴄ٩ࠠ。⒈ྶß; 🄀ⴄ٩ࠠ.⒈ྶß; [B1, P1, V6]; xn--iib29fp25e0219a.xn--zca117e3vp; ; xn--iib29fp25e0219a.xn--ss-1sj588o; # 🄀ⴄ٩ࠠ.⒈ྶß
+🄀Ⴄ٩ࠠ。⒈ྶSS; 🄀Ⴄ٩ࠠ.⒈ྶss; [B1, P1, V6]; xn--iib29f26o6n43c.xn--ss-1sj588o; ; ; # 🄀Ⴄ٩ࠠ.⒈ྶss
+🄀ⴄ٩ࠠ。⒈ྶss; 🄀ⴄ٩ࠠ.⒈ྶss; [B1, P1, V6]; xn--iib29fp25e0219a.xn--ss-1sj588o; ; ; # 🄀ⴄ٩ࠠ.⒈ྶss
+🄀Ⴄ٩ࠠ。⒈ྶSs; 🄀Ⴄ٩ࠠ.⒈ྶss; [B1, P1, V6]; xn--iib29f26o6n43c.xn--ss-1sj588o; ; ; # 🄀Ⴄ٩ࠠ.⒈ྶss
+xn--iib29f26o6n43c.xn--ss-1sj588o; 🄀Ⴄ٩ࠠ.⒈ྶss; [B1, V6]; xn--iib29f26o6n43c.xn--ss-1sj588o; ; ; # 🄀Ⴄ٩ࠠ.⒈ྶss
+xn--iib29fp25e0219a.xn--ss-1sj588o; 🄀ⴄ٩ࠠ.⒈ྶss; [B1, V6]; xn--iib29fp25e0219a.xn--ss-1sj588o; ; ; # 🄀ⴄ٩ࠠ.⒈ྶss
+xn--iib29fp25e0219a.xn--zca117e3vp; 🄀ⴄ٩ࠠ.⒈ྶß; [B1, V6]; xn--iib29fp25e0219a.xn--zca117e3vp; ; ; # 🄀ⴄ٩ࠠ.⒈ྶß
+xn--iib29f26o6n43c.xn--zca117e3vp; 🄀Ⴄ٩ࠠ.⒈ྶß; [B1, V6]; xn--iib29f26o6n43c.xn--zca117e3vp; ; ; # 🄀Ⴄ٩ࠠ.⒈ྶß
+≠.‌-٫; ; [B1, C1, P1, V6]; xn--1ch.xn----vqc597q; ; xn--1ch.xn----vqc; [B1, P1, V3, V6] # ≠.-٫
+≠.‌-٫; ≠.‌-٫; [B1, C1, P1, V6]; xn--1ch.xn----vqc597q; ; xn--1ch.xn----vqc; [B1, P1, V3, V6] # ≠.-٫
+xn--1ch.xn----vqc; ≠.-٫; [B1, V3, V6]; xn--1ch.xn----vqc; ; ; # ≠.-٫
+xn--1ch.xn----vqc597q; ≠.‌-٫; [B1, C1, V6]; xn--1ch.xn----vqc597q; ; ; # ≠.-٫
+٠۱。󠳶𞠁٥; ٠۱.󠳶𞠁٥; [B1, P1, V6]; xn--8hb40a.xn--eib7967vner3e; ; ; # ٠۱.𞠁٥
+٠۱。󠳶𞠁٥; ٠۱.󠳶𞠁٥; [B1, P1, V6]; xn--8hb40a.xn--eib7967vner3e; ; ; # ٠۱.𞠁٥
+xn--8hb40a.xn--eib7967vner3e; ٠۱.󠳶𞠁٥; [B1, V6]; xn--8hb40a.xn--eib7967vner3e; ; ; # ٠۱.𞠁٥
+‌٣⒖。󱅉𽷛᯳; ‌٣⒖.󱅉𽷛᯳; [B1, C1, P1, V6]; xn--cib152kwgd.xn--1zf13512buy41d; ; xn--cib675m.xn--1zf13512buy41d; [B1, P1, V6] # ٣⒖.᯳
+‌٣15.。󱅉𽷛᯳; ‌٣15..󱅉𽷛᯳; [B1, C1, P1, V6, X4_2]; xn--15-gyd983x..xn--1zf13512buy41d; [B1, C1, P1, V6, A4_2]; xn--15-gyd..xn--1zf13512buy41d; [B1, P1, V6, A4_2] # ٣15..᯳
+xn--15-gyd..xn--1zf13512buy41d; ٣15..󱅉𽷛᯳; [B1, V6, X4_2]; xn--15-gyd..xn--1zf13512buy41d; [B1, V6, A4_2]; ; # ٣15..᯳
+xn--15-gyd983x..xn--1zf13512buy41d; ‌٣15..󱅉𽷛᯳; [B1, C1, V6, X4_2]; xn--15-gyd983x..xn--1zf13512buy41d; [B1, C1, V6, A4_2]; ; # ٣15..᯳
+xn--cib675m.xn--1zf13512buy41d; ٣⒖.󱅉𽷛᯳; [B1, V6]; xn--cib675m.xn--1zf13512buy41d; ; ; # ٣⒖.᯳
+xn--cib152kwgd.xn--1zf13512buy41d; ‌٣⒖.󱅉𽷛᯳; [B1, C1, V6]; xn--cib152kwgd.xn--1zf13512buy41d; ; ; # ٣⒖.᯳
+᯳.-逋񳦭󙙮; ; [P1, V3, V5, V6]; xn--1zf.xn----483d46987byr50b; ; ; # ᯳.-逋
+xn--1zf.xn----483d46987byr50b; ᯳.-逋񳦭󙙮; [V3, V5, V6]; xn--1zf.xn----483d46987byr50b; ; ; # ᯳.-逋
+ݖ。ㅤ‍ς; ݖ.ㅤ‍ς; [C2, P1, V6]; xn--9ob.xn--3xa995lq2l; ; xn--9ob.xn--4xa574u; [P1, V6] # ݖ.ς
+ݖ。ᅠ‍ς; ݖ.ᅠ‍ς; [C2, P1, V6]; xn--9ob.xn--3xa580ebol; ; xn--9ob.xn--4xa380e; [P1, V6] # ݖ.ς
+ݖ。ᅠ‍Σ; ݖ.ᅠ‍σ; [C2, P1, V6]; xn--9ob.xn--4xa380ebol; ; xn--9ob.xn--4xa380e; [P1, V6] # ݖ.σ
+ݖ。ᅠ‍σ; ݖ.ᅠ‍σ; [C2, P1, V6]; xn--9ob.xn--4xa380ebol; ; xn--9ob.xn--4xa380e; [P1, V6] # ݖ.σ
+xn--9ob.xn--4xa380e; ݖ.ᅠσ; [V6]; xn--9ob.xn--4xa380e; ; ; # ݖ.σ
+xn--9ob.xn--4xa380ebol; ݖ.ᅠ‍σ; [C2, V6]; xn--9ob.xn--4xa380ebol; ; ; # ݖ.σ
+xn--9ob.xn--3xa580ebol; ݖ.ᅠ‍ς; [C2, V6]; xn--9ob.xn--3xa580ebol; ; ; # ݖ.ς
+ݖ。ㅤ‍Σ; ݖ.ㅤ‍σ; [C2, P1, V6]; xn--9ob.xn--4xa795lq2l; ; xn--9ob.xn--4xa574u; [P1, V6] # ݖ.σ
+ݖ。ㅤ‍σ; ݖ.ㅤ‍σ; [C2, P1, V6]; xn--9ob.xn--4xa795lq2l; ; xn--9ob.xn--4xa574u; [P1, V6] # ݖ.σ
+xn--9ob.xn--4xa574u; ݖ.ㅤσ; [V6]; xn--9ob.xn--4xa574u; ; ; # ݖ.σ
+xn--9ob.xn--4xa795lq2l; ݖ.ㅤ‍σ; [C2, V6]; xn--9ob.xn--4xa795lq2l; ; ; # ݖ.σ
+xn--9ob.xn--3xa995lq2l; ݖ.ㅤ‍ς; [C2, V6]; xn--9ob.xn--3xa995lq2l; ; ; # ݖ.ς
+ᡆႣ。󞢧̕‍‍; ᡆႣ.󞢧̕‍‍; [C2, P1, V6]; xn--bnd320b.xn--5sa649la993427a; ; xn--bnd320b.xn--5sa98523p; [P1, V6] # ᡆႣ.̕
+ᡆႣ。󞢧̕‍‍; ᡆႣ.󞢧̕‍‍; [C2, P1, V6]; xn--bnd320b.xn--5sa649la993427a; ; xn--bnd320b.xn--5sa98523p; [P1, V6] # ᡆႣ.̕
+ᡆⴃ。󞢧̕‍‍; ᡆⴃ.󞢧̕‍‍; [C2, P1, V6]; xn--57e237h.xn--5sa649la993427a; ; xn--57e237h.xn--5sa98523p; [P1, V6] # ᡆⴃ.̕
+xn--57e237h.xn--5sa98523p; ᡆⴃ.󞢧̕; [V6]; xn--57e237h.xn--5sa98523p; ; ; # ᡆⴃ.̕
+xn--57e237h.xn--5sa649la993427a; ᡆⴃ.󞢧̕‍‍; [C2, V6]; xn--57e237h.xn--5sa649la993427a; ; ; # ᡆⴃ.̕
+xn--bnd320b.xn--5sa98523p; ᡆႣ.󞢧̕; [V6]; xn--bnd320b.xn--5sa98523p; ; ; # ᡆႣ.̕
+xn--bnd320b.xn--5sa649la993427a; ᡆႣ.󞢧̕‍‍; [C2, V6]; xn--bnd320b.xn--5sa649la993427a; ; ; # ᡆႣ.̕
+ᡆⴃ。󞢧̕‍‍; ᡆⴃ.󞢧̕‍‍; [C2, P1, V6]; xn--57e237h.xn--5sa649la993427a; ; xn--57e237h.xn--5sa98523p; [P1, V6] # ᡆⴃ.̕
+㭄‍ࡏ𑚵.ς𐮮‌‍; 㭄‍ࡏ𑚵.ς𐮮‌‍; [B5, B6, C1, C2]; xn--ewb962jfitku4r.xn--3xa895lda6932v; ; xn--ewb302xhu1l.xn--4xa0426k; [B5, B6] # 㭄ࡏ𑚵.ς𐮮
+㭄‍ࡏ𑚵.ς𐮮‌‍; ; [B5, B6, C1, C2]; xn--ewb962jfitku4r.xn--3xa895lda6932v; ; xn--ewb302xhu1l.xn--4xa0426k; [B5, B6] # 㭄ࡏ𑚵.ς𐮮
+㭄‍ࡏ𑚵.Σ𐮮‌‍; 㭄‍ࡏ𑚵.σ𐮮‌‍; [B5, B6, C1, C2]; xn--ewb962jfitku4r.xn--4xa695lda6932v; ; xn--ewb302xhu1l.xn--4xa0426k; [B5, B6] # 㭄ࡏ𑚵.σ𐮮
+㭄‍ࡏ𑚵.σ𐮮‌‍; ; [B5, B6, C1, C2]; xn--ewb962jfitku4r.xn--4xa695lda6932v; ; xn--ewb302xhu1l.xn--4xa0426k; [B5, B6] # 㭄ࡏ𑚵.σ𐮮
+xn--ewb302xhu1l.xn--4xa0426k; 㭄ࡏ𑚵.σ𐮮; [B5, B6]; xn--ewb302xhu1l.xn--4xa0426k; ; ; # 㭄ࡏ𑚵.σ𐮮
+xn--ewb962jfitku4r.xn--4xa695lda6932v; 㭄‍ࡏ𑚵.σ𐮮‌‍; [B5, B6, C1, C2]; xn--ewb962jfitku4r.xn--4xa695lda6932v; ; ; # 㭄ࡏ𑚵.σ𐮮
+xn--ewb962jfitku4r.xn--3xa895lda6932v; 㭄‍ࡏ𑚵.ς𐮮‌‍; [B5, B6, C1, C2]; xn--ewb962jfitku4r.xn--3xa895lda6932v; ; ; # 㭄ࡏ𑚵.ς𐮮
+㭄‍ࡏ𑚵.Σ𐮮‌‍; 㭄‍ࡏ𑚵.σ𐮮‌‍; [B5, B6, C1, C2]; xn--ewb962jfitku4r.xn--4xa695lda6932v; ; xn--ewb302xhu1l.xn--4xa0426k; [B5, B6] # 㭄ࡏ𑚵.σ𐮮
+㭄‍ࡏ𑚵.σ𐮮‌‍; 㭄‍ࡏ𑚵.σ𐮮‌‍; [B5, B6, C1, C2]; xn--ewb962jfitku4r.xn--4xa695lda6932v; ; xn--ewb302xhu1l.xn--4xa0426k; [B5, B6] # 㭄ࡏ𑚵.σ𐮮
+឵。𞯸ꡀ🄋; ឵.𞯸ꡀ🄋; [B1, B2, B3, B6, P1, V5, V6]; xn--03e.xn--8b9ar252dngd; ; ; # .ꡀ🄋
+xn--03e.xn--8b9ar252dngd; ឵.𞯸ꡀ🄋; [B1, B2, B3, B6, V5, V6]; xn--03e.xn--8b9ar252dngd; ; ; # .ꡀ🄋
+󐪺暑.⾑٨; 󐪺暑.襾٨; [B5, B6, P1, V6]; xn--tlvq3513e.xn--hib9228d; ; ; # 暑.襾٨
+󐪺暑.襾٨; ; [B5, B6, P1, V6]; xn--tlvq3513e.xn--hib9228d; ; ; # 暑.襾٨
+xn--tlvq3513e.xn--hib9228d; 󐪺暑.襾٨; [B5, B6, V6]; xn--tlvq3513e.xn--hib9228d; ; ; # 暑.襾٨
+󠄚≯ꡢ。࢑᷿; ≯ꡢ.࢑᷿; [B1, P1, V6]; xn--hdh7783c.xn--9xb680i; ; ; # ≯ꡢ.᷿
+󠄚≯ꡢ。࢑᷿; ≯ꡢ.࢑᷿; [B1, P1, V6]; xn--hdh7783c.xn--9xb680i; ; ; # ≯ꡢ.᷿
+xn--hdh7783c.xn--9xb680i; ≯ꡢ.࢑᷿; [B1, V6]; xn--hdh7783c.xn--9xb680i; ; ; # ≯ꡢ.᷿
+ﷃ𮁱୍𐨿.󐧤Ⴗ; كمم𮁱୍𐨿.󐧤Ⴗ; [B2, B3, P1, V6]; xn--fhbea662czx68a2tju.xn--vnd55511o; ; ; # كمم𮁱୍𐨿.Ⴗ
+كمم𮁱୍𐨿.󐧤Ⴗ; ; [B2, B3, P1, V6]; xn--fhbea662czx68a2tju.xn--vnd55511o; ; ; # كمم𮁱୍𐨿.Ⴗ
+كمم𮁱୍𐨿.󐧤ⴗ; ; [B2, B3, P1, V6]; xn--fhbea662czx68a2tju.xn--fljz2846h; ; ; # كمم𮁱୍𐨿.ⴗ
+xn--fhbea662czx68a2tju.xn--fljz2846h; كمم𮁱୍𐨿.󐧤ⴗ; [B2, B3, V6]; xn--fhbea662czx68a2tju.xn--fljz2846h; ; ; # كمم𮁱୍𐨿.ⴗ
+xn--fhbea662czx68a2tju.xn--vnd55511o; كمم𮁱୍𐨿.󐧤Ⴗ; [B2, B3, V6]; xn--fhbea662czx68a2tju.xn--vnd55511o; ; ; # كمم𮁱୍𐨿.Ⴗ
+ﷃ𮁱୍𐨿.󐧤ⴗ; كمم𮁱୍𐨿.󐧤ⴗ; [B2, B3, P1, V6]; xn--fhbea662czx68a2tju.xn--fljz2846h; ; ; # كمم𮁱୍𐨿.ⴗ
+𞀨。᭄򡛨𞎇; 𞀨.᭄򡛨𞎇; [P1, V5, V6]; xn--mi4h.xn--1uf6843smg20c; ; ; # 𞀨.᭄
+𞀨。᭄򡛨𞎇; 𞀨.᭄򡛨𞎇; [P1, V5, V6]; xn--mi4h.xn--1uf6843smg20c; ; ; # 𞀨.᭄
+xn--mi4h.xn--1uf6843smg20c; 𞀨.᭄򡛨𞎇; [V5, V6]; xn--mi4h.xn--1uf6843smg20c; ; ; # 𞀨.᭄
+󠣼‌.𐺰‌ᡟ; 󠣼‌.𐺰‌ᡟ; [B1, B2, B3, C1, P1, V6]; xn--0ug18531l.xn--v8e340bp21t; ; xn--q046e.xn--v8e7227j; [B1, B2, B3, P1, V6] # .𐺰ᡟ
+󠣼‌.𐺰‌ᡟ; ; [B1, B2, B3, C1, P1, V6]; xn--0ug18531l.xn--v8e340bp21t; ; xn--q046e.xn--v8e7227j; [B1, B2, B3, P1, V6] # .𐺰ᡟ
+xn--q046e.xn--v8e7227j; 󠣼.𐺰ᡟ; [B1, B2, B3, V6]; xn--q046e.xn--v8e7227j; ; ; # .𐺰ᡟ
+xn--0ug18531l.xn--v8e340bp21t; 󠣼‌.𐺰‌ᡟ; [B1, B2, B3, C1, V6]; xn--0ug18531l.xn--v8e340bp21t; ; ; # .𐺰ᡟ
+ᢛ󨅟ß.ጧ; ; [P1, V6]; xn--zca562jc642x.xn--p5d; ; xn--ss-7dp66033t.xn--p5d; # ᢛß.ጧ
+ᢛ󨅟SS.ጧ; ᢛ󨅟ss.ጧ; [P1, V6]; xn--ss-7dp66033t.xn--p5d; ; ; # ᢛss.ጧ
+ᢛ󨅟ss.ጧ; ; [P1, V6]; xn--ss-7dp66033t.xn--p5d; ; ; # ᢛss.ጧ
+ᢛ󨅟Ss.ጧ; ᢛ󨅟ss.ጧ; [P1, V6]; xn--ss-7dp66033t.xn--p5d; ; ; # ᢛss.ጧ
+xn--ss-7dp66033t.xn--p5d; ᢛ󨅟ss.ጧ; [V6]; xn--ss-7dp66033t.xn--p5d; ; ; # ᢛss.ጧ
+xn--zca562jc642x.xn--p5d; ᢛ󨅟ß.ጧ; [V6]; xn--zca562jc642x.xn--p5d; ; ; # ᢛß.ጧ
+⮒‌.񒚗‌; ; [C1, P1, V6]; xn--0ugx66b.xn--0ugz2871c; ; xn--b9i.xn--5p9y; [P1, V6] # ⮒.
+xn--b9i.xn--5p9y; ⮒.񒚗; [V6]; xn--b9i.xn--5p9y; ; ; # ⮒.
+xn--0ugx66b.xn--0ugz2871c; ⮒‌.񒚗‌; [C1, V6]; xn--0ugx66b.xn--0ugz2871c; ; ; # ⮒.
+𞤂񹞁𐹯。Ⴜ; 𞤤񹞁𐹯.Ⴜ; [B2, P1, V6]; xn--no0dr648a51o3b.xn--0nd; ; ; # 𞤤𐹯.Ⴜ
+𞤤񹞁𐹯。ⴜ; 𞤤񹞁𐹯.ⴜ; [B2, P1, V6]; xn--no0dr648a51o3b.xn--klj; ; ; # 𞤤𐹯.ⴜ
+xn--no0dr648a51o3b.xn--klj; 𞤤񹞁𐹯.ⴜ; [B2, V6]; xn--no0dr648a51o3b.xn--klj; ; ; # 𞤤𐹯.ⴜ
+xn--no0dr648a51o3b.xn--0nd; 𞤤񹞁𐹯.Ⴜ; [B2, V6]; xn--no0dr648a51o3b.xn--0nd; ; ; # 𞤤𐹯.Ⴜ
+𞤂񹞁𐹯。ⴜ; 𞤤񹞁𐹯.ⴜ; [B2, P1, V6]; xn--no0dr648a51o3b.xn--klj; ; ; # 𞤤𐹯.ⴜ
+𐹵⮣‌𑄰。񷴿ﲷ; 𐹵⮣‌𑄰.񷴿ضم; [B1, B5, B6, C1, P1, V6]; xn--0ug586bcj8p7jc.xn--1gb4a66004i; ; xn--s9i5458e7yb.xn--1gb4a66004i; [B1, B5, B6, P1, V6] # 𐹵⮣𑄰.ضم
+𐹵⮣‌𑄰。񷴿ضم; 𐹵⮣‌𑄰.񷴿ضم; [B1, B5, B6, C1, P1, V6]; xn--0ug586bcj8p7jc.xn--1gb4a66004i; ; xn--s9i5458e7yb.xn--1gb4a66004i; [B1, B5, B6, P1, V6] # 𐹵⮣𑄰.ضم
+xn--s9i5458e7yb.xn--1gb4a66004i; 𐹵⮣𑄰.񷴿ضم; [B1, B5, B6, V6]; xn--s9i5458e7yb.xn--1gb4a66004i; ; ; # 𐹵⮣𑄰.ضم
+xn--0ug586bcj8p7jc.xn--1gb4a66004i; 𐹵⮣‌𑄰.񷴿ضم; [B1, B5, B6, C1, V6]; xn--0ug586bcj8p7jc.xn--1gb4a66004i; ; ; # 𐹵⮣𑄰.ضم
+Ⴒ。デß𞤵్; Ⴒ.デß𞤵్; [B5, B6, P1, V6]; xn--qnd.xn--zca669cmr3a0f28a; ; xn--qnd.xn--ss-9nh3648ahh20b; # Ⴒ.デß𞤵్
+Ⴒ。デß𞤵్; Ⴒ.デß𞤵్; [B5, B6, P1, V6]; xn--qnd.xn--zca669cmr3a0f28a; ; xn--qnd.xn--ss-9nh3648ahh20b; # Ⴒ.デß𞤵్
+ⴒ。デß𞤵్; ⴒ.デß𞤵్; [B5, B6]; xn--9kj.xn--zca669cmr3a0f28a; ; xn--9kj.xn--ss-9nh3648ahh20b; # ⴒ.デß𞤵్
+ⴒ。デß𞤵్; ⴒ.デß𞤵్; [B5, B6]; xn--9kj.xn--zca669cmr3a0f28a; ; xn--9kj.xn--ss-9nh3648ahh20b; # ⴒ.デß𞤵్
+Ⴒ。デSS𞤓్; Ⴒ.デss𞤵్; [B5, B6, P1, V6]; xn--qnd.xn--ss-9nh3648ahh20b; ; ; # Ⴒ.デss𞤵్
+Ⴒ。デSS𞤓్; Ⴒ.デss𞤵్; [B5, B6, P1, V6]; xn--qnd.xn--ss-9nh3648ahh20b; ; ; # Ⴒ.デss𞤵్
+ⴒ。デss𞤵్; ⴒ.デss𞤵్; [B5, B6]; xn--9kj.xn--ss-9nh3648ahh20b; ; ; # ⴒ.デss𞤵్
+ⴒ。デss𞤵్; ⴒ.デss𞤵్; [B5, B6]; xn--9kj.xn--ss-9nh3648ahh20b; ; ; # ⴒ.デss𞤵్
+Ⴒ。デSs𞤵్; Ⴒ.デss𞤵్; [B5, B6, P1, V6]; xn--qnd.xn--ss-9nh3648ahh20b; ; ; # Ⴒ.デss𞤵్
+Ⴒ。デSs𞤵్; Ⴒ.デss𞤵్; [B5, B6, P1, V6]; xn--qnd.xn--ss-9nh3648ahh20b; ; ; # Ⴒ.デss𞤵్
+xn--qnd.xn--ss-9nh3648ahh20b; Ⴒ.デss𞤵్; [B5, B6, V6]; xn--qnd.xn--ss-9nh3648ahh20b; ; ; # Ⴒ.デss𞤵్
+xn--9kj.xn--ss-9nh3648ahh20b; ⴒ.デss𞤵్; [B5, B6]; xn--9kj.xn--ss-9nh3648ahh20b; ; ; # ⴒ.デss𞤵్
+xn--9kj.xn--zca669cmr3a0f28a; ⴒ.デß𞤵్; [B5, B6]; xn--9kj.xn--zca669cmr3a0f28a; ; ; # ⴒ.デß𞤵్
+xn--qnd.xn--zca669cmr3a0f28a; Ⴒ.デß𞤵్; [B5, B6, V6]; xn--qnd.xn--zca669cmr3a0f28a; ; ; # Ⴒ.デß𞤵్
+Ⴒ。デSS𞤵్; Ⴒ.デss𞤵్; [B5, B6, P1, V6]; xn--qnd.xn--ss-9nh3648ahh20b; ; ; # Ⴒ.デss𞤵్
+Ⴒ。デSS𞤵్; Ⴒ.デss𞤵్; [B5, B6, P1, V6]; xn--qnd.xn--ss-9nh3648ahh20b; ; ; # Ⴒ.デss𞤵్
+𑁿്.7-ߒ; 𑁿്.7-ߒ; [B1, B3, B6, V5]; xn--wxc1283k.xn--7--yue; ; ; # 𑁿്.7-ߒ
+𑁿്.7-ߒ; ; [B1, B3, B6, V5]; xn--wxc1283k.xn--7--yue; ; ; # 𑁿്.7-ߒ
+xn--wxc1283k.xn--7--yue; 𑁿്.7-ߒ; [B1, B3, B6, V5]; xn--wxc1283k.xn--7--yue; ; ; # 𑁿്.7-ߒ
+≯𑜫󠭇.᜴񒞤𑍬ᢧ; ; [P1, V5, V6]; xn--hdhx157g68o0g.xn--c0e65eu616c34o7a; ; ; # ≯𑜫.᜴𑍬ᢧ
+≯𑜫󠭇.᜴񒞤𑍬ᢧ; ≯𑜫󠭇.᜴񒞤𑍬ᢧ; [P1, V5, V6]; xn--hdhx157g68o0g.xn--c0e65eu616c34o7a; ; ; # ≯𑜫.᜴𑍬ᢧ
+xn--hdhx157g68o0g.xn--c0e65eu616c34o7a; ≯𑜫󠭇.᜴񒞤𑍬ᢧ; [V5, V6]; xn--hdhx157g68o0g.xn--c0e65eu616c34o7a; ; ; # ≯𑜫.᜴𑍬ᢧ
+ᷛ򎐙Ⴗ쏔。ށ; ᷛ򎐙Ⴗ쏔.ށ; [B1, P1, V5, V6]; xn--vnd148d733ky6n9e.xn--iqb; ; ; # ᷛႷ쏔.ށ
+ᷛ򎐙Ⴗ쏔。ށ; ᷛ򎐙Ⴗ쏔.ށ; [B1, P1, V5, V6]; xn--vnd148d733ky6n9e.xn--iqb; ; ; # ᷛႷ쏔.ށ
+ᷛ򎐙ⴗ쏔。ށ; ᷛ򎐙ⴗ쏔.ށ; [B1, P1, V5, V6]; xn--zegy26dw47iy6w2f.xn--iqb; ; ; # ᷛⴗ쏔.ށ
+ᷛ򎐙ⴗ쏔。ށ; ᷛ򎐙ⴗ쏔.ށ; [B1, P1, V5, V6]; xn--zegy26dw47iy6w2f.xn--iqb; ; ; # ᷛⴗ쏔.ށ
+xn--zegy26dw47iy6w2f.xn--iqb; ᷛ򎐙ⴗ쏔.ށ; [B1, V5, V6]; xn--zegy26dw47iy6w2f.xn--iqb; ; ; # ᷛⴗ쏔.ށ
+xn--vnd148d733ky6n9e.xn--iqb; ᷛ򎐙Ⴗ쏔.ށ; [B1, V5, V6]; xn--vnd148d733ky6n9e.xn--iqb; ; ; # ᷛႷ쏔.ށ
+ß。𐋳Ⴌྸ; ß.𐋳Ⴌྸ; [P1, V6]; xn--zca.xn--lgd10cu829c; ; ss.xn--lgd10cu829c; # ß.𐋳Ⴌྸ
+ß。𐋳Ⴌྸ; ß.𐋳Ⴌྸ; [P1, V6]; xn--zca.xn--lgd10cu829c; ; ss.xn--lgd10cu829c; # ß.𐋳Ⴌྸ
+ß。𐋳ⴌྸ; ß.𐋳ⴌྸ; ; xn--zca.xn--lgd921mvv0m; ; ss.xn--lgd921mvv0m; # ß.𐋳ⴌྸ
+SS。𐋳Ⴌྸ; ss.𐋳Ⴌྸ; [P1, V6]; ss.xn--lgd10cu829c; ; ; # ss.𐋳Ⴌྸ
+ss。𐋳ⴌྸ; ss.𐋳ⴌྸ; ; ss.xn--lgd921mvv0m; ; ; # ss.𐋳ⴌྸ
+Ss。𐋳Ⴌྸ; ss.𐋳Ⴌྸ; [P1, V6]; ss.xn--lgd10cu829c; ; ; # ss.𐋳Ⴌྸ
+ss.xn--lgd10cu829c; ss.𐋳Ⴌྸ; [V6]; ss.xn--lgd10cu829c; ; ; # ss.𐋳Ⴌྸ
+ss.xn--lgd921mvv0m; ss.𐋳ⴌྸ; ; ss.xn--lgd921mvv0m; ; ; # ss.𐋳ⴌྸ
+ss.𐋳ⴌྸ; ; ; ss.xn--lgd921mvv0m; ; ; # ss.𐋳ⴌྸ
+SS.𐋳Ⴌྸ; ss.𐋳Ⴌྸ; [P1, V6]; ss.xn--lgd10cu829c; ; ; # ss.𐋳Ⴌྸ
+Ss.𐋳Ⴌྸ; ss.𐋳Ⴌྸ; [P1, V6]; ss.xn--lgd10cu829c; ; ; # ss.𐋳Ⴌྸ
+xn--zca.xn--lgd921mvv0m; ß.𐋳ⴌྸ; ; xn--zca.xn--lgd921mvv0m; ; ; # ß.𐋳ⴌྸ
+ß.𐋳ⴌྸ; ; ; xn--zca.xn--lgd921mvv0m; ; ss.xn--lgd921mvv0m; # ß.𐋳ⴌྸ
+xn--zca.xn--lgd10cu829c; ß.𐋳Ⴌྸ; [V6]; xn--zca.xn--lgd10cu829c; ; ; # ß.𐋳Ⴌྸ
+ß。𐋳ⴌྸ; ß.𐋳ⴌྸ; ; xn--zca.xn--lgd921mvv0m; ; ss.xn--lgd921mvv0m; # ß.𐋳ⴌྸ
+SS。𐋳Ⴌྸ; ss.𐋳Ⴌྸ; [P1, V6]; ss.xn--lgd10cu829c; ; ; # ss.𐋳Ⴌྸ
+ss。𐋳ⴌྸ; ss.𐋳ⴌྸ; ; ss.xn--lgd921mvv0m; ; ; # ss.𐋳ⴌྸ
+Ss。𐋳Ⴌྸ; ss.𐋳Ⴌྸ; [P1, V6]; ss.xn--lgd10cu829c; ; ; # ss.𐋳Ⴌྸ
+-ڞ𐶡.‌⾝্; -ڞ𐶡.‌身্; [B1, C1, P1, V3, V6]; xn----stc7013r.xn--b7b305imj2f; ; xn----stc7013r.xn--b7b1419d; [B1, P1, V3, V6] # -ڞ.身্
+-ڞ𐶡.‌身্; ; [B1, C1, P1, V3, V6]; xn----stc7013r.xn--b7b305imj2f; ; xn----stc7013r.xn--b7b1419d; [B1, P1, V3, V6] # -ڞ.身্
+xn----stc7013r.xn--b7b1419d; -ڞ𐶡.身্; [B1, V3, V6]; xn----stc7013r.xn--b7b1419d; ; ; # -ڞ.身্
+xn----stc7013r.xn--b7b305imj2f; -ڞ𐶡.‌身্; [B1, C1, V3, V6]; xn----stc7013r.xn--b7b305imj2f; ; ; # -ڞ.身্
+😮ݤ𑈵𞀖.💅‍; 😮ݤ𑈵𞀖.💅‍; [B1, C2]; xn--opb4277kuc7elqsa.xn--1ug5265p; ; xn--opb4277kuc7elqsa.xn--kr8h; [B1] # 😮ݤ𑈵𞀖.💅
+😮ݤ𑈵𞀖.💅‍; ; [B1, C2]; xn--opb4277kuc7elqsa.xn--1ug5265p; ; xn--opb4277kuc7elqsa.xn--kr8h; [B1] # 😮ݤ𑈵𞀖.💅
+xn--opb4277kuc7elqsa.xn--kr8h; 😮ݤ𑈵𞀖.💅; [B1]; xn--opb4277kuc7elqsa.xn--kr8h; ; ; # 😮ݤ𑈵𞀖.💅
+xn--opb4277kuc7elqsa.xn--1ug5265p; 😮ݤ𑈵𞀖.💅‍; [B1, C2]; xn--opb4277kuc7elqsa.xn--1ug5265p; ; ; # 😮ݤ𑈵𞀖.💅
+ࣲ‍꙳ܒ.ᢏ‌󠍄; ; [B1, B6, C1, C2, P1, V5, V6]; xn--cnb37g904be26j.xn--89e849ax9363a; ; xn--cnb37gdy00a.xn--89e02253p; [B1, B6, P1, V5, V6] # ࣲ꙳ܒ.ᢏ
+xn--cnb37gdy00a.xn--89e02253p; ࣲ꙳ܒ.ᢏ󠍄; [B1, B6, V5, V6]; xn--cnb37gdy00a.xn--89e02253p; ; ; # ࣲ꙳ܒ.ᢏ
+xn--cnb37g904be26j.xn--89e849ax9363a; ࣲ‍꙳ܒ.ᢏ‌󠍄; [B1, B6, C1, C2, V5, V6]; xn--cnb37g904be26j.xn--89e849ax9363a; ; ; # ࣲ꙳ܒ.ᢏ
+Ⴑ.ڿ𞯓ᠲ; Ⴑ.ڿ𞯓ᠲ; [B2, B3, P1, V6]; xn--pnd.xn--ykb840gd555a; ; ; # Ⴑ.ڿᠲ
+Ⴑ.ڿ𞯓ᠲ; ; [B2, B3, P1, V6]; xn--pnd.xn--ykb840gd555a; ; ; # Ⴑ.ڿᠲ
+ⴑ.ڿ𞯓ᠲ; ; [B2, B3, P1, V6]; xn--8kj.xn--ykb840gd555a; ; ; # ⴑ.ڿᠲ
+xn--8kj.xn--ykb840gd555a; ⴑ.ڿ𞯓ᠲ; [B2, B3, V6]; xn--8kj.xn--ykb840gd555a; ; ; # ⴑ.ڿᠲ
+xn--pnd.xn--ykb840gd555a; Ⴑ.ڿ𞯓ᠲ; [B2, B3, V6]; xn--pnd.xn--ykb840gd555a; ; ; # Ⴑ.ڿᠲ
+ⴑ.ڿ𞯓ᠲ; ⴑ.ڿ𞯓ᠲ; [B2, B3, P1, V6]; xn--8kj.xn--ykb840gd555a; ; ; # ⴑ.ڿᠲ
+ᩚ𛦝్。𚝬𝟵; ᩚ𛦝్.𚝬9; [P1, V5, V6]; xn--lqc703ebm93a.xn--9-000p; ; ; # ᩚ్.9
+ᩚ𛦝్。𚝬9; ᩚ𛦝్.𚝬9; [P1, V5, V6]; xn--lqc703ebm93a.xn--9-000p; ; ; # ᩚ్.9
+xn--lqc703ebm93a.xn--9-000p; ᩚ𛦝్.𚝬9; [V5, V6]; xn--lqc703ebm93a.xn--9-000p; ; ; # ᩚ్.9
+‌ڠ𿺆𝟗。Ⴣ꒘ﳐ񐘖; ‌ڠ𿺆9.Ⴣ꒘مخ񐘖; [B1, B5, C1, P1, V6]; xn--9-vtc736qts91g.xn--tgb9bz61cfn8mw3t2c; ; xn--9-vtc42319e.xn--tgb9bz61cfn8mw3t2c; [B2, B5, P1, V6] # ڠ9.Ⴣ꒘مخ
+‌ڠ𿺆9。Ⴣ꒘مخ񐘖; ‌ڠ𿺆9.Ⴣ꒘مخ񐘖; [B1, B5, C1, P1, V6]; xn--9-vtc736qts91g.xn--tgb9bz61cfn8mw3t2c; ; xn--9-vtc42319e.xn--tgb9bz61cfn8mw3t2c; [B2, B5, P1, V6] # ڠ9.Ⴣ꒘مخ
+‌ڠ𿺆9。ⴣ꒘مخ񐘖; ‌ڠ𿺆9.ⴣ꒘مخ񐘖; [B1, B5, C1, P1, V6]; xn--9-vtc736qts91g.xn--tgb9bz87p833hw316c; ; xn--9-vtc42319e.xn--tgb9bz87p833hw316c; [B2, B5, P1, V6] # ڠ9.ⴣ꒘مخ
+xn--9-vtc42319e.xn--tgb9bz87p833hw316c; ڠ𿺆9.ⴣ꒘مخ񐘖; [B2, B5, V6]; xn--9-vtc42319e.xn--tgb9bz87p833hw316c; ; ; # ڠ9.ⴣ꒘مخ
+xn--9-vtc736qts91g.xn--tgb9bz87p833hw316c; ‌ڠ𿺆9.ⴣ꒘مخ񐘖; [B1, B5, C1, V6]; xn--9-vtc736qts91g.xn--tgb9bz87p833hw316c; ; ; # ڠ9.ⴣ꒘مخ
+xn--9-vtc42319e.xn--tgb9bz61cfn8mw3t2c; ڠ𿺆9.Ⴣ꒘مخ񐘖; [B2, B5, V6]; xn--9-vtc42319e.xn--tgb9bz61cfn8mw3t2c; ; ; # ڠ9.Ⴣ꒘مخ
+xn--9-vtc736qts91g.xn--tgb9bz61cfn8mw3t2c; ‌ڠ𿺆9.Ⴣ꒘مخ񐘖; [B1, B5, C1, V6]; xn--9-vtc736qts91g.xn--tgb9bz61cfn8mw3t2c; ; ; # ڠ9.Ⴣ꒘مخ
+‌ڠ𿺆𝟗。ⴣ꒘ﳐ񐘖; ‌ڠ𿺆9.ⴣ꒘مخ񐘖; [B1, B5, C1, P1, V6]; xn--9-vtc736qts91g.xn--tgb9bz87p833hw316c; ; xn--9-vtc42319e.xn--tgb9bz87p833hw316c; [B2, B5, P1, V6] # ڠ9.ⴣ꒘مخ
+ᡖ。̟񗛨ஂ-; ᡖ.̟񗛨ஂ-; [P1, V3, V5, V6]; xn--m8e.xn----mdb555dkk71m; ; ; # ᡖ.̟ஂ-
+ᡖ。̟񗛨ஂ-; ᡖ.̟񗛨ஂ-; [P1, V3, V5, V6]; xn--m8e.xn----mdb555dkk71m; ; ; # ᡖ.̟ஂ-
+xn--m8e.xn----mdb555dkk71m; ᡖ.̟񗛨ஂ-; [V3, V5, V6]; xn--m8e.xn----mdb555dkk71m; ; ; # ᡖ.̟ஂ-
+𞠠浘。絧𞀀; 𞠠浘.絧𞀀; [B2, B3]; xn--e0wp491f.xn--ud0a3573e; ; ; # 𞠠浘.絧𞀀
+xn--e0wp491f.xn--ud0a3573e; 𞠠浘.絧𞀀; [B2, B3]; xn--e0wp491f.xn--ud0a3573e; ; ; # 𞠠浘.絧𞀀
+֖Ⴋ.𝟳≯︒︊; ֖Ⴋ.7≯︒; [P1, V5, V6]; xn--hcb887c.xn--7-pgoy530h; ; ; # ֖Ⴋ.7≯︒
+֖Ⴋ.𝟳≯︒︊; ֖Ⴋ.7≯︒; [P1, V5, V6]; xn--hcb887c.xn--7-pgoy530h; ; ; # ֖Ⴋ.7≯︒
+֖Ⴋ.7≯。︊; ֖Ⴋ.7≯.; [P1, V5, V6]; xn--hcb887c.xn--7-pgo.; ; ; # ֖Ⴋ.7≯.
+֖Ⴋ.7≯。︊; ֖Ⴋ.7≯.; [P1, V5, V6]; xn--hcb887c.xn--7-pgo.; ; ; # ֖Ⴋ.7≯.
+֖ⴋ.7≯。︊; ֖ⴋ.7≯.; [P1, V5, V6]; xn--hcb613r.xn--7-pgo.; ; ; # ֖ⴋ.7≯.
+֖ⴋ.7≯。︊; ֖ⴋ.7≯.; [P1, V5, V6]; xn--hcb613r.xn--7-pgo.; ; ; # ֖ⴋ.7≯.
+xn--hcb613r.xn--7-pgo.; ֖ⴋ.7≯.; [V5, V6]; xn--hcb613r.xn--7-pgo.; ; ; # ֖ⴋ.7≯.
+xn--hcb887c.xn--7-pgo.; ֖Ⴋ.7≯.; [V5, V6]; xn--hcb887c.xn--7-pgo.; ; ; # ֖Ⴋ.7≯.
+֖ⴋ.𝟳≯︒︊; ֖ⴋ.7≯︒; [P1, V5, V6]; xn--hcb613r.xn--7-pgoy530h; ; ; # ֖ⴋ.7≯︒
+֖ⴋ.𝟳≯︒︊; ֖ⴋ.7≯︒; [P1, V5, V6]; xn--hcb613r.xn--7-pgoy530h; ; ; # ֖ⴋ.7≯︒
+xn--hcb613r.xn--7-pgoy530h; ֖ⴋ.7≯︒; [V5, V6]; xn--hcb613r.xn--7-pgoy530h; ; ; # ֖ⴋ.7≯︒
+xn--hcb887c.xn--7-pgoy530h; ֖Ⴋ.7≯︒; [V5, V6]; xn--hcb887c.xn--7-pgoy530h; ; ; # ֖Ⴋ.7≯︒
+‍F𑓂。󠺨︒ݾ𐹢; ‍f𑓂.󠺨︒ݾ𐹢; [B1, C2, P1, V6]; xn--f-tgn9761i.xn--fqb1637j8hky9452a; ; xn--f-kq9i.xn--fqb1637j8hky9452a; [B1, P1, V6] # f𑓂.︒ݾ𐹢
+‍F𑓂。󠺨。ݾ𐹢; ‍f𑓂.󠺨.ݾ𐹢; [B1, C2, P1, V6]; xn--f-tgn9761i.xn--7656e.xn--fqb4175k; ; xn--f-kq9i.xn--7656e.xn--fqb4175k; [B1, P1, V6] # f𑓂..ݾ𐹢
+‍f𑓂。󠺨。ݾ𐹢; ‍f𑓂.󠺨.ݾ𐹢; [B1, C2, P1, V6]; xn--f-tgn9761i.xn--7656e.xn--fqb4175k; ; xn--f-kq9i.xn--7656e.xn--fqb4175k; [B1, P1, V6] # f𑓂..ݾ𐹢
+xn--f-kq9i.xn--7656e.xn--fqb4175k; f𑓂.󠺨.ݾ𐹢; [B1, V6]; xn--f-kq9i.xn--7656e.xn--fqb4175k; ; ; # f𑓂..ݾ𐹢
+xn--f-tgn9761i.xn--7656e.xn--fqb4175k; ‍f𑓂.󠺨.ݾ𐹢; [B1, C2, V6]; xn--f-tgn9761i.xn--7656e.xn--fqb4175k; ; ; # f𑓂..ݾ𐹢
+‍f𑓂。󠺨︒ݾ𐹢; ‍f𑓂.󠺨︒ݾ𐹢; [B1, C2, P1, V6]; xn--f-tgn9761i.xn--fqb1637j8hky9452a; ; xn--f-kq9i.xn--fqb1637j8hky9452a; [B1, P1, V6] # f𑓂.︒ݾ𐹢
+xn--f-kq9i.xn--fqb1637j8hky9452a; f𑓂.󠺨︒ݾ𐹢; [B1, V6]; xn--f-kq9i.xn--fqb1637j8hky9452a; ; ; # f𑓂.︒ݾ𐹢
+xn--f-tgn9761i.xn--fqb1637j8hky9452a; ‍f𑓂.󠺨︒ݾ𐹢; [B1, C2, V6]; xn--f-tgn9761i.xn--fqb1637j8hky9452a; ; ; # f𑓂.︒ݾ𐹢
+ࡅ🄇𐼗︒。𐹻𑜫; ࡅ🄇𐼗︒.𐹻𑜫; [B1, B3, P1, V6]; xn--3vb4696jpxkjh7s.xn--zo0di2m; ; ; # ࡅ🄇𐼗︒.𐹻𑜫
+ࡅ6,𐼗。。𐹻𑜫; ࡅ6,𐼗..𐹻𑜫; [B1, P1, V6, X4_2]; xn--6,-r4e4420y..xn--zo0di2m; [B1, P1, V6, A4_2]; ; # ࡅ6,𐼗..𐹻𑜫
+xn--6,-r4e4420y..xn--zo0di2m; ࡅ6,𐼗..𐹻𑜫; [B1, P1, V6, X4_2]; xn--6,-r4e4420y..xn--zo0di2m; [B1, P1, V6, A4_2]; ; # ࡅ6,𐼗..𐹻𑜫
+xn--3vb4696jpxkjh7s.xn--zo0di2m; ࡅ🄇𐼗︒.𐹻𑜫; [B1, B3, V6]; xn--3vb4696jpxkjh7s.xn--zo0di2m; ; ; # ࡅ🄇𐼗︒.𐹻𑜫
+𐹈.᷀𑈱𐦭; ; [B1, P1, V5, V6]; xn--jn0d.xn--7dg0871h3lf; ; ; # .᷀𑈱𐦭
+xn--jn0d.xn--7dg0871h3lf; 𐹈.᷀𑈱𐦭; [B1, V5, V6]; xn--jn0d.xn--7dg0871h3lf; ; ; # .᷀𑈱𐦭
+Ⴂ䠺。𞤃񅏎󙮦ړ; Ⴂ䠺.𞤥񅏎󙮦ړ; [B2, P1, V6]; xn--9md875z.xn--pjb9818vg4xno967d; ; ; # Ⴂ䠺.𞤥ړ
+ⴂ䠺。𞤥񅏎󙮦ړ; ⴂ䠺.𞤥񅏎󙮦ړ; [B2, P1, V6]; xn--tkj638f.xn--pjb9818vg4xno967d; ; ; # ⴂ䠺.𞤥ړ
+xn--tkj638f.xn--pjb9818vg4xno967d; ⴂ䠺.𞤥񅏎󙮦ړ; [B2, V6]; xn--tkj638f.xn--pjb9818vg4xno967d; ; ; # ⴂ䠺.𞤥ړ
+xn--9md875z.xn--pjb9818vg4xno967d; Ⴂ䠺.𞤥񅏎󙮦ړ; [B2, V6]; xn--9md875z.xn--pjb9818vg4xno967d; ; ; # Ⴂ䠺.𞤥ړ
+ⴂ䠺。𞤃񅏎󙮦ړ; ⴂ䠺.𞤥񅏎󙮦ړ; [B2, P1, V6]; xn--tkj638f.xn--pjb9818vg4xno967d; ; ; # ⴂ䠺.𞤥ړ
+🄇伐︒.𜙚꣄; ; [P1, V6]; xn--woqs083bel0g.xn--0f9ao925c; ; ; # 🄇伐︒.꣄
+6,伐。.𜙚꣄; 6,伐..𜙚꣄; [P1, V6, X4_2]; xn--6,-7i3c..xn--0f9ao925c; [P1, V6, A4_2]; ; # 6,伐..꣄
+xn--6,-7i3c..xn--0f9ao925c; 6,伐..𜙚꣄; [P1, V6, X4_2]; xn--6,-7i3c..xn--0f9ao925c; [P1, V6, A4_2]; ; # 6,伐..꣄
+xn--woqs083bel0g.xn--0f9ao925c; 🄇伐︒.𜙚꣄; [V6]; xn--woqs083bel0g.xn--0f9ao925c; ; ; # 🄇伐︒.꣄
+‍𐹠꯭。‍𐫓Ⴚ𑂹; ‍𐹠꯭.‍𐫓Ⴚ𑂹; [B1, C2, P1, V6]; xn--1ugz126coy7bdbm.xn--ynd959evs1pv6e; ; xn--429az70n29i.xn--ynd3619jqyd; [B1, B2, B3, P1, V6] # 𐹠꯭.𐫓Ⴚ𑂹
+‍𐹠꯭。‍𐫓ⴚ𑂹; ‍𐹠꯭.‍𐫓ⴚ𑂹; [B1, C2, P1, V6]; xn--1ugz126coy7bdbm.xn--1ug062chv7ov6e; ; xn--429az70n29i.xn--ilj7702eqyd; [B1, B2, B3, P1, V6] # 𐹠꯭.𐫓ⴚ𑂹
+xn--429az70n29i.xn--ilj7702eqyd; 𐹠꯭.𐫓ⴚ𑂹; [B1, B2, B3, V6]; xn--429az70n29i.xn--ilj7702eqyd; ; ; # 𐹠꯭.𐫓ⴚ𑂹
+xn--1ugz126coy7bdbm.xn--1ug062chv7ov6e; ‍𐹠꯭.‍𐫓ⴚ𑂹; [B1, C2, V6]; xn--1ugz126coy7bdbm.xn--1ug062chv7ov6e; ; ; # 𐹠꯭.𐫓ⴚ𑂹
+xn--429az70n29i.xn--ynd3619jqyd; 𐹠꯭.𐫓Ⴚ𑂹; [B1, B2, B3, V6]; xn--429az70n29i.xn--ynd3619jqyd; ; ; # 𐹠꯭.𐫓Ⴚ𑂹
+xn--1ugz126coy7bdbm.xn--ynd959evs1pv6e; ‍𐹠꯭.‍𐫓Ⴚ𑂹; [B1, C2, V6]; xn--1ugz126coy7bdbm.xn--ynd959evs1pv6e; ; ; # 𐹠꯭.𐫓Ⴚ𑂹
+󠆠.񷐴󌟈; .񷐴󌟈; [P1, V6, X4_2]; .xn--rx21bhv12i; [P1, V6, A4_2]; ; # .
+󠆠.񷐴󌟈; .񷐴󌟈; [P1, V6, X4_2]; .xn--rx21bhv12i; [P1, V6, A4_2]; ; # .
+.xn--rx21bhv12i; .񷐴󌟈; [V6, X4_2]; .xn--rx21bhv12i; [V6, A4_2]; ; # .
+𐫃‌Ⴆ.≠𞷙; ; [B1, B2, B3, C1, P1, V6]; xn--end799ekr1p.xn--1ch2802p; ; xn--end1719j.xn--1ch2802p; [B1, B2, B3, P1, V6] # 𐫃Ⴆ.≠
+𐫃‌Ⴆ.≠𞷙; 𐫃‌Ⴆ.≠𞷙; [B1, B2, B3, C1, P1, V6]; xn--end799ekr1p.xn--1ch2802p; ; xn--end1719j.xn--1ch2802p; [B1, B2, B3, P1, V6] # 𐫃Ⴆ.≠
+𐫃‌ⴆ.≠𞷙; 𐫃‌ⴆ.≠𞷙; [B1, B2, B3, C1, P1, V6]; xn--0ug132csv7o.xn--1ch2802p; ; xn--xkjz802e.xn--1ch2802p; [B1, B2, B3, P1, V6] # 𐫃ⴆ.≠
+𐫃‌ⴆ.≠𞷙; ; [B1, B2, B3, C1, P1, V6]; xn--0ug132csv7o.xn--1ch2802p; ; xn--xkjz802e.xn--1ch2802p; [B1, B2, B3, P1, V6] # 𐫃ⴆ.≠
+xn--xkjz802e.xn--1ch2802p; 𐫃ⴆ.≠𞷙; [B1, B2, B3, V6]; xn--xkjz802e.xn--1ch2802p; ; ; # 𐫃ⴆ.≠
+xn--0ug132csv7o.xn--1ch2802p; 𐫃‌ⴆ.≠𞷙; [B1, B2, B3, C1, V6]; xn--0ug132csv7o.xn--1ch2802p; ; ; # 𐫃ⴆ.≠
+xn--end1719j.xn--1ch2802p; 𐫃Ⴆ.≠𞷙; [B1, B2, B3, V6]; xn--end1719j.xn--1ch2802p; ; ; # 𐫃Ⴆ.≠
+xn--end799ekr1p.xn--1ch2802p; 𐫃‌Ⴆ.≠𞷙; [B1, B2, B3, C1, V6]; xn--end799ekr1p.xn--1ch2802p; ; ; # 𐫃Ⴆ.≠
+󠁲𙩢𝟥ꘌ.ࡁ; 󠁲𙩢3ꘌ.ࡁ; [B1, P1, V6]; xn--3-0g3es485d8i15h.xn--zvb; ; ; # 3ꘌ.ࡁ
+󠁲𙩢3ꘌ.ࡁ; ; [B1, P1, V6]; xn--3-0g3es485d8i15h.xn--zvb; ; ; # 3ꘌ.ࡁ
+xn--3-0g3es485d8i15h.xn--zvb; 󠁲𙩢3ꘌ.ࡁ; [B1, V6]; xn--3-0g3es485d8i15h.xn--zvb; ; ; # 3ꘌ.ࡁ
+-.ᢆ󡲣-; ; [P1, V3, V5, V6]; -.xn----pbkx6497q; ; ; # -.ᢆ-
+-.xn----pbkx6497q; -.ᢆ󡲣-; [V3, V5, V6]; -.xn----pbkx6497q; ; ; # -.ᢆ-
+󲚗‌。‌𞰆ς; 󲚗‌.‌𞰆ς; [B1, B6, C1, P1, V6]; xn--0ug76062m.xn--3xa795lhn92a; ; xn--qp42f.xn--4xa3011w; [B2, B3, P1, V6] # .ς
+󲚗‌。‌𞰆ς; 󲚗‌.‌𞰆ς; [B1, B6, C1, P1, V6]; xn--0ug76062m.xn--3xa795lhn92a; ; xn--qp42f.xn--4xa3011w; [B2, B3, P1, V6] # .ς
+󲚗‌。‌𞰆Σ; 󲚗‌.‌𞰆σ; [B1, B6, C1, P1, V6]; xn--0ug76062m.xn--4xa595lhn92a; ; xn--qp42f.xn--4xa3011w; [B2, B3, P1, V6] # .σ
+󲚗‌。‌𞰆σ; 󲚗‌.‌𞰆σ; [B1, B6, C1, P1, V6]; xn--0ug76062m.xn--4xa595lhn92a; ; xn--qp42f.xn--4xa3011w; [B2, B3, P1, V6] # .σ
+xn--qp42f.xn--4xa3011w; 󲚗.𞰆σ; [B2, B3, V6]; xn--qp42f.xn--4xa3011w; ; ; # .σ
+xn--0ug76062m.xn--4xa595lhn92a; 󲚗‌.‌𞰆σ; [B1, B6, C1, V6]; xn--0ug76062m.xn--4xa595lhn92a; ; ; # .σ
+xn--0ug76062m.xn--3xa795lhn92a; 󲚗‌.‌𞰆ς; [B1, B6, C1, V6]; xn--0ug76062m.xn--3xa795lhn92a; ; ; # .ς
+󲚗‌。‌𞰆Σ; 󲚗‌.‌𞰆σ; [B1, B6, C1, P1, V6]; xn--0ug76062m.xn--4xa595lhn92a; ; xn--qp42f.xn--4xa3011w; [B2, B3, P1, V6] # .σ
+󲚗‌。‌𞰆σ; 󲚗‌.‌𞰆σ; [B1, B6, C1, P1, V6]; xn--0ug76062m.xn--4xa595lhn92a; ; xn--qp42f.xn--4xa3011w; [B2, B3, P1, V6] # .σ
+堕𑓂ᬂ。𐮇𞤽‌-; 堕𑓂ᬂ.𐮇𞤽‌-; [B3, C1, V3]; xn--5sf345zdk8h.xn----rgnt157hwl9g; ; xn--5sf345zdk8h.xn----iv5iw606c; [B3, V3] # 堕𑓂ᬂ.𐮇𞤽-
+堕𑓂ᬂ。𐮇𞤛‌-; 堕𑓂ᬂ.𐮇𞤽‌-; [B3, C1, V3]; xn--5sf345zdk8h.xn----rgnt157hwl9g; ; xn--5sf345zdk8h.xn----iv5iw606c; [B3, V3] # 堕𑓂ᬂ.𐮇𞤽-
+xn--5sf345zdk8h.xn----iv5iw606c; 堕𑓂ᬂ.𐮇𞤽-; [B3, V3]; xn--5sf345zdk8h.xn----iv5iw606c; ; ; # 堕𑓂ᬂ.𐮇𞤽-
+xn--5sf345zdk8h.xn----rgnt157hwl9g; 堕𑓂ᬂ.𐮇𞤽‌-; [B3, C1, V3]; xn--5sf345zdk8h.xn----rgnt157hwl9g; ; ; # 堕𑓂ᬂ.𐮇𞤽-
+𐹶𑁆ᡕ𞤢。ᡥςتς; 𐹶𑁆ᡕ𞤢.ᡥςتς; [B1, B5]; xn--l8e1317j1ebz456b.xn--3xaa16plx4a; ; xn--l8e1317j1ebz456b.xn--4xaa85plx4a; # 𐹶𑁆ᡕ𞤢.ᡥςتς
+𐹶𑁆ᡕ𞤢。ᡥςتς; 𐹶𑁆ᡕ𞤢.ᡥςتς; [B1, B5]; xn--l8e1317j1ebz456b.xn--3xaa16plx4a; ; xn--l8e1317j1ebz456b.xn--4xaa85plx4a; # 𐹶𑁆ᡕ𞤢.ᡥςتς
+𐹶𑁆ᡕ𞤀。ᡥΣتΣ; 𐹶𑁆ᡕ𞤢.ᡥσتσ; [B1, B5]; xn--l8e1317j1ebz456b.xn--4xaa85plx4a; ; ; # 𐹶𑁆ᡕ𞤢.ᡥσتσ
+𐹶𑁆ᡕ𞤢。ᡥσتσ; 𐹶𑁆ᡕ𞤢.ᡥσتσ; [B1, B5]; xn--l8e1317j1ebz456b.xn--4xaa85plx4a; ; ; # 𐹶𑁆ᡕ𞤢.ᡥσتσ
+xn--l8e1317j1ebz456b.xn--4xaa85plx4a; 𐹶𑁆ᡕ𞤢.ᡥσتσ; [B1, B5]; xn--l8e1317j1ebz456b.xn--4xaa85plx4a; ; ; # 𐹶𑁆ᡕ𞤢.ᡥσتσ
+xn--l8e1317j1ebz456b.xn--3xaa16plx4a; 𐹶𑁆ᡕ𞤢.ᡥςتς; [B1, B5]; xn--l8e1317j1ebz456b.xn--3xaa16plx4a; ; ; # 𐹶𑁆ᡕ𞤢.ᡥςتς
+𐹶𑁆ᡕ𞤀。ᡥΣتΣ; 𐹶𑁆ᡕ𞤢.ᡥσتσ; [B1, B5]; xn--l8e1317j1ebz456b.xn--4xaa85plx4a; ; ; # 𐹶𑁆ᡕ𞤢.ᡥσتσ
+𐹶𑁆ᡕ𞤢。ᡥσتσ; 𐹶𑁆ᡕ𞤢.ᡥσتσ; [B1, B5]; xn--l8e1317j1ebz456b.xn--4xaa85plx4a; ; ; # 𐹶𑁆ᡕ𞤢.ᡥσتσ
+𐹶𑁆ᡕ𞤢。ᡥΣتΣ; 𐹶𑁆ᡕ𞤢.ᡥσتσ; [B1, B5]; xn--l8e1317j1ebz456b.xn--4xaa85plx4a; ; ; # 𐹶𑁆ᡕ𞤢.ᡥσتσ
+𐹶𑁆ᡕ𞤢。ᡥΣتσ; 𐹶𑁆ᡕ𞤢.ᡥσتσ; [B1, B5]; xn--l8e1317j1ebz456b.xn--4xaa85plx4a; ; ; # 𐹶𑁆ᡕ𞤢.ᡥσتσ
+𐹶𑁆ᡕ𞤢。ᡥΣتς; 𐹶𑁆ᡕ𞤢.ᡥσتς; [B1, B5]; xn--l8e1317j1ebz456b.xn--3xab95plx4a; ; xn--l8e1317j1ebz456b.xn--4xaa85plx4a; # 𐹶𑁆ᡕ𞤢.ᡥσتς
+𐹶𑁆ᡕ𞤢。ᡥσتς; 𐹶𑁆ᡕ𞤢.ᡥσتς; [B1, B5]; xn--l8e1317j1ebz456b.xn--3xab95plx4a; ; xn--l8e1317j1ebz456b.xn--4xaa85plx4a; # 𐹶𑁆ᡕ𞤢.ᡥσتς
+xn--l8e1317j1ebz456b.xn--3xab95plx4a; 𐹶𑁆ᡕ𞤢.ᡥσتς; [B1, B5]; xn--l8e1317j1ebz456b.xn--3xab95plx4a; ; ; # 𐹶𑁆ᡕ𞤢.ᡥσتς
+𐹶𑁆ᡕ𞤢。ᡥΣتΣ; 𐹶𑁆ᡕ𞤢.ᡥσتσ; [B1, B5]; xn--l8e1317j1ebz456b.xn--4xaa85plx4a; ; ; # 𐹶𑁆ᡕ𞤢.ᡥσتσ
+𐹶𑁆ᡕ𞤢。ᡥΣتσ; 𐹶𑁆ᡕ𞤢.ᡥσتσ; [B1, B5]; xn--l8e1317j1ebz456b.xn--4xaa85plx4a; ; ; # 𐹶𑁆ᡕ𞤢.ᡥσتσ
+𐹶𑁆ᡕ𞤢。ᡥΣتς; 𐹶𑁆ᡕ𞤢.ᡥσتς; [B1, B5]; xn--l8e1317j1ebz456b.xn--3xab95plx4a; ; xn--l8e1317j1ebz456b.xn--4xaa85plx4a; # 𐹶𑁆ᡕ𞤢.ᡥσتς
+𐹶𑁆ᡕ𞤢。ᡥσتς; 𐹶𑁆ᡕ𞤢.ᡥσتς; [B1, B5]; xn--l8e1317j1ebz456b.xn--3xab95plx4a; ; xn--l8e1317j1ebz456b.xn--4xaa85plx4a; # 𐹶𑁆ᡕ𞤢.ᡥσتς
+󏒰.-𝟻ß; 󏒰.-5ß; [P1, V3, V6]; xn--t960e.xn---5-hia; ; xn--t960e.-5ss; # .-5ß
+󏒰.-5ß; ; [P1, V3, V6]; xn--t960e.xn---5-hia; ; xn--t960e.-5ss; # .-5ß
+󏒰.-5SS; 󏒰.-5ss; [P1, V3, V6]; xn--t960e.-5ss; ; ; # .-5ss
+󏒰.-5ss; ; [P1, V3, V6]; xn--t960e.-5ss; ; ; # .-5ss
+xn--t960e.-5ss; 󏒰.-5ss; [V3, V6]; xn--t960e.-5ss; ; ; # .-5ss
+xn--t960e.xn---5-hia; 󏒰.-5ß; [V3, V6]; xn--t960e.xn---5-hia; ; ; # .-5ß
+󏒰.-𝟻SS; 󏒰.-5ss; [P1, V3, V6]; xn--t960e.-5ss; ; ; # .-5ss
+󏒰.-𝟻ss; 󏒰.-5ss; [P1, V3, V6]; xn--t960e.-5ss; ; ; # .-5ss
+󏒰.-𝟻Ss; 󏒰.-5ss; [P1, V3, V6]; xn--t960e.-5ss; ; ; # .-5ss
+󏒰.-5Ss; 󏒰.-5ss; [P1, V3, V6]; xn--t960e.-5ss; ; ; # .-5ss
+‍𐨿.🤒Ⴥ򑮶; ; [C2, P1, V6]; xn--1ug9533g.xn--9nd3211w0gz4b; ; xn--0s9c.xn--9nd3211w0gz4b; [P1, V5, V6] # 𐨿.🤒Ⴥ
+‍𐨿.🤒ⴥ򑮶; ; [C2, P1, V6]; xn--1ug9533g.xn--tljz038l0gz4b; ; xn--0s9c.xn--tljz038l0gz4b; [P1, V5, V6] # 𐨿.🤒ⴥ
+xn--0s9c.xn--tljz038l0gz4b; 𐨿.🤒ⴥ򑮶; [V5, V6]; xn--0s9c.xn--tljz038l0gz4b; ; ; # 𐨿.🤒ⴥ
+xn--1ug9533g.xn--tljz038l0gz4b; ‍𐨿.🤒ⴥ򑮶; [C2, V6]; xn--1ug9533g.xn--tljz038l0gz4b; ; ; # 𐨿.🤒ⴥ
+xn--0s9c.xn--9nd3211w0gz4b; 𐨿.🤒Ⴥ򑮶; [V5, V6]; xn--0s9c.xn--9nd3211w0gz4b; ; ; # 𐨿.🤒Ⴥ
+xn--1ug9533g.xn--9nd3211w0gz4b; ‍𐨿.🤒Ⴥ򑮶; [C2, V6]; xn--1ug9533g.xn--9nd3211w0gz4b; ; ; # 𐨿.🤒Ⴥ
+𵋅。ß𬵩‍; 𵋅.ß𬵩‍; [C2, P1, V6]; xn--ey1p.xn--zca870nz438b; ; xn--ey1p.xn--ss-eq36b; [P1, V6] # .ß𬵩
+𵋅。SS𬵩‍; 𵋅.ss𬵩‍; [C2, P1, V6]; xn--ey1p.xn--ss-n1tx0508a; ; xn--ey1p.xn--ss-eq36b; [P1, V6] # .ss𬵩
+𵋅。ss𬵩‍; 𵋅.ss𬵩‍; [C2, P1, V6]; xn--ey1p.xn--ss-n1tx0508a; ; xn--ey1p.xn--ss-eq36b; [P1, V6] # .ss𬵩
+𵋅。Ss𬵩‍; 𵋅.ss𬵩‍; [C2, P1, V6]; xn--ey1p.xn--ss-n1tx0508a; ; xn--ey1p.xn--ss-eq36b; [P1, V6] # .ss𬵩
+xn--ey1p.xn--ss-eq36b; 𵋅.ss𬵩; [V6]; xn--ey1p.xn--ss-eq36b; ; ; # .ss𬵩
+xn--ey1p.xn--ss-n1tx0508a; 𵋅.ss𬵩‍; [C2, V6]; xn--ey1p.xn--ss-n1tx0508a; ; ; # .ss𬵩
+xn--ey1p.xn--zca870nz438b; 𵋅.ß𬵩‍; [C2, V6]; xn--ey1p.xn--zca870nz438b; ; ; # .ß𬵩
+‌𭉝。߱́𞹻; ‌𭉝.߱́غ; [B1, C1, V5]; xn--0ugy003y.xn--lsa46nuub; ; xn--634m.xn--lsa46nuub; [B1, V5] # 𭉝.߱́غ
+‌𭉝。߱́غ; ‌𭉝.߱́غ; [B1, C1, V5]; xn--0ugy003y.xn--lsa46nuub; ; xn--634m.xn--lsa46nuub; [B1, V5] # 𭉝.߱́غ
+xn--634m.xn--lsa46nuub; 𭉝.߱́غ; [B1, V5]; xn--634m.xn--lsa46nuub; ; ; # 𭉝.߱́غ
+xn--0ugy003y.xn--lsa46nuub; ‌𭉝.߱́غ; [B1, C1, V5]; xn--0ugy003y.xn--lsa46nuub; ; ; # 𭉝.߱́غ
+𞼌‌𑈶。𐹡; 𞼌‌𑈶.𐹡; [B1, B3, C1, P1, V6]; xn--0ug7946gzpxf.xn--8n0d; ; xn--9g1d1288a.xn--8n0d; [B1, P1, V6] # 𑈶.𐹡
+xn--9g1d1288a.xn--8n0d; 𞼌𑈶.𐹡; [B1, V6]; xn--9g1d1288a.xn--8n0d; ; ; # 𑈶.𐹡
+xn--0ug7946gzpxf.xn--8n0d; 𞼌‌𑈶.𐹡; [B1, B3, C1, V6]; xn--0ug7946gzpxf.xn--8n0d; ; ; # 𑈶.𐹡
+󠅯򇽭‌🜭。𑖿᪻ς≠; 򇽭‌🜭.𑖿᪻ς≠; [C1, P1, V5, V6]; xn--0ug3766p5nm1b.xn--3xa578i1mfjw7y; ; xn--zb9h5968x.xn--4xa378i1mfjw7y; [P1, V5, V6] # 🜭.𑖿᪻ς≠
+󠅯򇽭‌🜭。𑖿᪻ς≠; 򇽭‌🜭.𑖿᪻ς≠; [C1, P1, V5, V6]; xn--0ug3766p5nm1b.xn--3xa578i1mfjw7y; ; xn--zb9h5968x.xn--4xa378i1mfjw7y; [P1, V5, V6] # 🜭.𑖿᪻ς≠
+󠅯򇽭‌🜭。𑖿᪻ς≠; 򇽭‌🜭.𑖿᪻ς≠; [C1, P1, V5, V6]; xn--0ug3766p5nm1b.xn--3xa578i1mfjw7y; ; xn--zb9h5968x.xn--4xa378i1mfjw7y; [P1, V5, V6] # 🜭.𑖿᪻ς≠
+󠅯򇽭‌🜭。𑖿᪻ς≠; 򇽭‌🜭.𑖿᪻ς≠; [C1, P1, V5, V6]; xn--0ug3766p5nm1b.xn--3xa578i1mfjw7y; ; xn--zb9h5968x.xn--4xa378i1mfjw7y; [P1, V5, V6] # 🜭.𑖿᪻ς≠
+󠅯򇽭‌🜭。𑖿᪻Σ≠; 򇽭‌🜭.𑖿᪻σ≠; [C1, P1, V5, V6]; xn--0ug3766p5nm1b.xn--4xa378i1mfjw7y; ; xn--zb9h5968x.xn--4xa378i1mfjw7y; [P1, V5, V6] # 🜭.𑖿᪻σ≠
+󠅯򇽭‌🜭。𑖿᪻Σ≠; 򇽭‌🜭.𑖿᪻σ≠; [C1, P1, V5, V6]; xn--0ug3766p5nm1b.xn--4xa378i1mfjw7y; ; xn--zb9h5968x.xn--4xa378i1mfjw7y; [P1, V5, V6] # 🜭.𑖿᪻σ≠
+󠅯򇽭‌🜭。𑖿᪻σ≠; 򇽭‌🜭.𑖿᪻σ≠; [C1, P1, V5, V6]; xn--0ug3766p5nm1b.xn--4xa378i1mfjw7y; ; xn--zb9h5968x.xn--4xa378i1mfjw7y; [P1, V5, V6] # 🜭.𑖿᪻σ≠
+󠅯򇽭‌🜭。𑖿᪻σ≠; 򇽭‌🜭.𑖿᪻σ≠; [C1, P1, V5, V6]; xn--0ug3766p5nm1b.xn--4xa378i1mfjw7y; ; xn--zb9h5968x.xn--4xa378i1mfjw7y; [P1, V5, V6] # 🜭.𑖿᪻σ≠
+xn--zb9h5968x.xn--4xa378i1mfjw7y; 򇽭🜭.𑖿᪻σ≠; [V5, V6]; xn--zb9h5968x.xn--4xa378i1mfjw7y; ; ; # 🜭.𑖿᪻σ≠
+xn--0ug3766p5nm1b.xn--4xa378i1mfjw7y; 򇽭‌🜭.𑖿᪻σ≠; [C1, V5, V6]; xn--0ug3766p5nm1b.xn--4xa378i1mfjw7y; ; ; # 🜭.𑖿᪻σ≠
+xn--0ug3766p5nm1b.xn--3xa578i1mfjw7y; 򇽭‌🜭.𑖿᪻ς≠; [C1, V5, V6]; xn--0ug3766p5nm1b.xn--3xa578i1mfjw7y; ; ; # 🜭.𑖿᪻ς≠
+󠅯򇽭‌🜭。𑖿᪻Σ≠; 򇽭‌🜭.𑖿᪻σ≠; [C1, P1, V5, V6]; xn--0ug3766p5nm1b.xn--4xa378i1mfjw7y; ; xn--zb9h5968x.xn--4xa378i1mfjw7y; [P1, V5, V6] # 🜭.𑖿᪻σ≠
+󠅯򇽭‌🜭。𑖿᪻Σ≠; 򇽭‌🜭.𑖿᪻σ≠; [C1, P1, V5, V6]; xn--0ug3766p5nm1b.xn--4xa378i1mfjw7y; ; xn--zb9h5968x.xn--4xa378i1mfjw7y; [P1, V5, V6] # 🜭.𑖿᪻σ≠
+󠅯򇽭‌🜭。𑖿᪻σ≠; 򇽭‌🜭.𑖿᪻σ≠; [C1, P1, V5, V6]; xn--0ug3766p5nm1b.xn--4xa378i1mfjw7y; ; xn--zb9h5968x.xn--4xa378i1mfjw7y; [P1, V5, V6] # 🜭.𑖿᪻σ≠
+󠅯򇽭‌🜭。𑖿᪻σ≠; 򇽭‌🜭.𑖿᪻σ≠; [C1, P1, V5, V6]; xn--0ug3766p5nm1b.xn--4xa378i1mfjw7y; ; xn--zb9h5968x.xn--4xa378i1mfjw7y; [P1, V5, V6] # 🜭.𑖿᪻σ≠
+⒋。⒈‍򳴢; ⒋.⒈‍򳴢; [C2, P1, V6]; xn--wsh.xn--1ug58o74922a; ; xn--wsh.xn--tsh07994h; [P1, V6] # ⒋.⒈
+4.。1.‍򳴢; 4..1.‍򳴢; [C2, P1, V6, X4_2]; 4..1.xn--1ug64613i; [C2, P1, V6, A4_2]; 4..1.xn--sf51d; [P1, V6, A4_2] # 4..1.
+4..1.xn--sf51d; 4..1.򳴢; [V6, X4_2]; 4..1.xn--sf51d; [V6, A4_2]; ; # 4..1.
+4..1.xn--1ug64613i; 4..1.‍򳴢; [C2, V6, X4_2]; 4..1.xn--1ug64613i; [C2, V6, A4_2]; ; # 4..1.
+xn--wsh.xn--tsh07994h; ⒋.⒈򳴢; [V6]; xn--wsh.xn--tsh07994h; ; ; # ⒋.⒈
+xn--wsh.xn--1ug58o74922a; ⒋.⒈‍򳴢; [C2, V6]; xn--wsh.xn--1ug58o74922a; ; ; # ⒋.⒈
+لß。᩠𐇽򾅢𞤾; لß.᩠𐇽򾅢𞤾; [B1, B2, B3, P1, V5, V6]; xn--zca57y.xn--jof2298hn83fln78f; ; xn--ss-svd.xn--jof2298hn83fln78f; # لß.᩠𐇽𞤾
+لß。᩠𐇽򾅢𞤾; لß.᩠𐇽򾅢𞤾; [B1, B2, B3, P1, V5, V6]; xn--zca57y.xn--jof2298hn83fln78f; ; xn--ss-svd.xn--jof2298hn83fln78f; # لß.᩠𐇽𞤾
+لß。᩠𐇽򾅢𞤾; لß.᩠𐇽򾅢𞤾; [B1, B2, B3, P1, V5, V6]; xn--zca57y.xn--jof2298hn83fln78f; ; xn--ss-svd.xn--jof2298hn83fln78f; # لß.᩠𐇽𞤾
+لSS。᩠𐇽򾅢𞤜; لss.᩠𐇽򾅢𞤾; [B1, B2, B3, P1, V5, V6]; xn--ss-svd.xn--jof2298hn83fln78f; ; ; # لss.᩠𐇽𞤾
+لss。᩠𐇽򾅢𞤾; لss.᩠𐇽򾅢𞤾; [B1, B2, B3, P1, V5, V6]; xn--ss-svd.xn--jof2298hn83fln78f; ; ; # لss.᩠𐇽𞤾
+لss。᩠𐇽򾅢𞤜; لss.᩠𐇽򾅢𞤾; [B1, B2, B3, P1, V5, V6]; xn--ss-svd.xn--jof2298hn83fln78f; ; ; # لss.᩠𐇽𞤾
+xn--ss-svd.xn--jof2298hn83fln78f; لss.᩠𐇽򾅢𞤾; [B1, B2, B3, V5, V6]; xn--ss-svd.xn--jof2298hn83fln78f; ; ; # لss.᩠𐇽𞤾
+لß。᩠𐇽򾅢𞤜; لß.᩠𐇽򾅢𞤾; [B1, B2, B3, P1, V5, V6]; xn--zca57y.xn--jof2298hn83fln78f; ; xn--ss-svd.xn--jof2298hn83fln78f; # لß.᩠𐇽𞤾
+xn--zca57y.xn--jof2298hn83fln78f; لß.᩠𐇽򾅢𞤾; [B1, B2, B3, V5, V6]; xn--zca57y.xn--jof2298hn83fln78f; ; ; # لß.᩠𐇽𞤾
+لSS。᩠𐇽򾅢𞤜; لss.᩠𐇽򾅢𞤾; [B1, B2, B3, P1, V5, V6]; xn--ss-svd.xn--jof2298hn83fln78f; ; ; # لss.᩠𐇽𞤾
+لss。᩠𐇽򾅢𞤾; لss.᩠𐇽򾅢𞤾; [B1, B2, B3, P1, V5, V6]; xn--ss-svd.xn--jof2298hn83fln78f; ; ; # لss.᩠𐇽𞤾
+لss。᩠𐇽򾅢𞤜; لss.᩠𐇽򾅢𞤾; [B1, B2, B3, P1, V5, V6]; xn--ss-svd.xn--jof2298hn83fln78f; ; ; # لss.᩠𐇽𞤾
+لß。᩠𐇽򾅢𞤜; لß.᩠𐇽򾅢𞤾; [B1, B2, B3, P1, V5, V6]; xn--zca57y.xn--jof2298hn83fln78f; ; xn--ss-svd.xn--jof2298hn83fln78f; # لß.᩠𐇽𞤾
+لSS。᩠𐇽򾅢𞤜; لss.᩠𐇽򾅢𞤾; [B1, B2, B3, P1, V5, V6]; xn--ss-svd.xn--jof2298hn83fln78f; ; ; # لss.᩠𐇽𞤾
+لss。᩠𐇽򾅢𞤾; لss.᩠𐇽򾅢𞤾; [B1, B2, B3, P1, V5, V6]; xn--ss-svd.xn--jof2298hn83fln78f; ; ; # لss.᩠𐇽𞤾
+لss。᩠𐇽򾅢𞤜; لss.᩠𐇽򾅢𞤾; [B1, B2, B3, P1, V5, V6]; xn--ss-svd.xn--jof2298hn83fln78f; ; ; # لss.᩠𐇽𞤾
+لß。᩠𐇽򾅢𞤜; لß.᩠𐇽򾅢𞤾; [B1, B2, B3, P1, V5, V6]; xn--zca57y.xn--jof2298hn83fln78f; ; xn--ss-svd.xn--jof2298hn83fln78f; # لß.᩠𐇽𞤾
+لSS。᩠𐇽򾅢𞤾; لss.᩠𐇽򾅢𞤾; [B1, B2, B3, P1, V5, V6]; xn--ss-svd.xn--jof2298hn83fln78f; ; ; # لss.᩠𐇽𞤾
+لSs。᩠𐇽򾅢𞤾; لss.᩠𐇽򾅢𞤾; [B1, B2, B3, P1, V5, V6]; xn--ss-svd.xn--jof2298hn83fln78f; ; ; # لss.᩠𐇽𞤾
+لSS。᩠𐇽򾅢𞤾; لss.᩠𐇽򾅢𞤾; [B1, B2, B3, P1, V5, V6]; xn--ss-svd.xn--jof2298hn83fln78f; ; ; # لss.᩠𐇽𞤾
+لSs。᩠𐇽򾅢𞤾; لss.᩠𐇽򾅢𞤾; [B1, B2, B3, P1, V5, V6]; xn--ss-svd.xn--jof2298hn83fln78f; ; ; # لss.᩠𐇽𞤾
+لSS。᩠𐇽򾅢𞤾; لss.᩠𐇽򾅢𞤾; [B1, B2, B3, P1, V5, V6]; xn--ss-svd.xn--jof2298hn83fln78f; ; ; # لss.᩠𐇽𞤾
+لSs。᩠𐇽򾅢𞤾; لss.᩠𐇽򾅢𞤾; [B1, B2, B3, P1, V5, V6]; xn--ss-svd.xn--jof2298hn83fln78f; ; ; # لss.᩠𐇽𞤾
+𐹽𑄳񼜲.ᷟី꠆𑜫; ; [B1, B3, B6, P1, V5, V6]; xn--1o0di0c0652w.xn--33e362arr1l153d; ; ; # 𐹽𑄳.ᷟី꠆𑜫
+xn--1o0di0c0652w.xn--33e362arr1l153d; 𐹽𑄳񼜲.ᷟី꠆𑜫; [B1, B3, B6, V5, V6]; xn--1o0di0c0652w.xn--33e362arr1l153d; ; ; # 𐹽𑄳.ᷟី꠆𑜫
+Ⴓ𑜫‍򗭓.ڧ𑰶; Ⴓ𑜫‍򗭓.ڧ𑰶; [P1, V6]; xn--rnd479ep20q7x12e.xn--9jb4223l; ; xn--rnd8945ky009c.xn--9jb4223l; # Ⴓ𑜫.ڧ𑰶
+Ⴓ𑜫‍򗭓.ڧ𑰶; ; [P1, V6]; xn--rnd479ep20q7x12e.xn--9jb4223l; ; xn--rnd8945ky009c.xn--9jb4223l; # Ⴓ𑜫.ڧ𑰶
+ⴓ𑜫‍򗭓.ڧ𑰶; ; [P1, V6]; xn--1ugy52cym7p7xu5e.xn--9jb4223l; ; xn--blj6306ey091d.xn--9jb4223l; # ⴓ𑜫.ڧ𑰶
+xn--blj6306ey091d.xn--9jb4223l; ⴓ𑜫򗭓.ڧ𑰶; [V6]; xn--blj6306ey091d.xn--9jb4223l; ; ; # ⴓ𑜫.ڧ𑰶
+xn--1ugy52cym7p7xu5e.xn--9jb4223l; ⴓ𑜫‍򗭓.ڧ𑰶; [V6]; xn--1ugy52cym7p7xu5e.xn--9jb4223l; ; ; # ⴓ𑜫.ڧ𑰶
+xn--rnd8945ky009c.xn--9jb4223l; Ⴓ𑜫򗭓.ڧ𑰶; [V6]; xn--rnd8945ky009c.xn--9jb4223l; ; ; # Ⴓ𑜫.ڧ𑰶
+xn--rnd479ep20q7x12e.xn--9jb4223l; Ⴓ𑜫‍򗭓.ڧ𑰶; [V6]; xn--rnd479ep20q7x12e.xn--9jb4223l; ; ; # Ⴓ𑜫.ڧ𑰶
+ⴓ𑜫‍򗭓.ڧ𑰶; ⴓ𑜫‍򗭓.ڧ𑰶; [P1, V6]; xn--1ugy52cym7p7xu5e.xn--9jb4223l; ; xn--blj6306ey091d.xn--9jb4223l; # ⴓ𑜫.ڧ𑰶
+𐨿.🄆—; ; [P1, V5, V6]; xn--0s9c.xn--8ug8324p; ; ; # 𐨿.🄆—
+𐨿.5,—; ; [P1, V5, V6]; xn--0s9c.xn--5,-81t; ; ; # 𐨿.5,—
+xn--0s9c.xn--5,-81t; 𐨿.5,—; [P1, V5, V6]; xn--0s9c.xn--5,-81t; ; ; # 𐨿.5,—
+xn--0s9c.xn--8ug8324p; 𐨿.🄆—; [V5, V6]; xn--0s9c.xn--8ug8324p; ; ; # 𐨿.🄆—
+򔊱񁦮۸。󠾭-; 򔊱񁦮۸.󠾭-; [P1, V3, V6]; xn--lmb18944c0g2z.xn----2k81m; ; ; # ۸.-
+xn--lmb18944c0g2z.xn----2k81m; 򔊱񁦮۸.󠾭-; [V3, V6]; xn--lmb18944c0g2z.xn----2k81m; ; ; # ۸.-
+𼗸ߍ𐹮。۝ᡎᠴ; 𼗸ߍ𐹮.۝ᡎᠴ; [B1, B5, B6, P1, V6]; xn--osb0855kcc2r.xn--tlb299fhc; ; ; # ߍ𐹮.ᡎᠴ
+xn--osb0855kcc2r.xn--tlb299fhc; 𼗸ߍ𐹮.۝ᡎᠴ; [B1, B5, B6, V6]; xn--osb0855kcc2r.xn--tlb299fhc; ; ; # ߍ𐹮.ᡎᠴ
+‍ᠮႾ🄂.🚗ࡁ𮹌‌; ; [B1, C1, C2, P1, V6]; xn--2nd129ay2gnw71c.xn--zvb692j9664aic1g; ; xn--2nd129ai554b.xn--zvb3124wpkpf; [B1, P1, V6] # ᠮႾ🄂.🚗ࡁ
+‍ᠮႾ1,.🚗ࡁ𮹌‌; ; [B1, C1, C2, P1, V6]; xn--1,-ogkx89c39j.xn--zvb692j9664aic1g; ; xn--1,-ogkx89c.xn--zvb3124wpkpf; [B1, B6, P1, V6] # ᠮႾ1,.🚗ࡁ
+‍ᠮⴞ1,.🚗ࡁ𮹌‌; ; [B1, C1, C2, P1, V6]; xn--1,-v3o161c53q.xn--zvb692j9664aic1g; ; xn--1,-v3o625k.xn--zvb3124wpkpf; [B1, B6, P1, V6] # ᠮⴞ1,.🚗ࡁ
+xn--1,-v3o625k.xn--zvb3124wpkpf; ᠮⴞ1,.🚗ࡁ𮹌; [B1, B6, P1, V6]; xn--1,-v3o625k.xn--zvb3124wpkpf; ; ; # ᠮⴞ1,.🚗ࡁ
+xn--1,-v3o161c53q.xn--zvb692j9664aic1g; ‍ᠮⴞ1,.🚗ࡁ𮹌‌; [B1, C1, C2, P1, V6]; xn--1,-v3o161c53q.xn--zvb692j9664aic1g; ; ; # ᠮⴞ1,.🚗ࡁ
+xn--1,-ogkx89c.xn--zvb3124wpkpf; ᠮႾ1,.🚗ࡁ𮹌; [B1, B6, P1, V6]; xn--1,-ogkx89c.xn--zvb3124wpkpf; ; ; # ᠮႾ1,.🚗ࡁ
+xn--1,-ogkx89c39j.xn--zvb692j9664aic1g; ‍ᠮႾ1,.🚗ࡁ𮹌‌; [B1, C1, C2, P1, V6]; xn--1,-ogkx89c39j.xn--zvb692j9664aic1g; ; ; # ᠮႾ1,.🚗ࡁ
+‍ᠮⴞ🄂.🚗ࡁ𮹌‌; ; [B1, C1, C2, P1, V6]; xn--h7e341b0wlbv45b.xn--zvb692j9664aic1g; ; xn--h7e438h1p44a.xn--zvb3124wpkpf; [B1, P1, V6] # ᠮⴞ🄂.🚗ࡁ
+xn--h7e438h1p44a.xn--zvb3124wpkpf; ᠮⴞ🄂.🚗ࡁ𮹌; [B1, V6]; xn--h7e438h1p44a.xn--zvb3124wpkpf; ; ; # ᠮⴞ🄂.🚗ࡁ
+xn--h7e341b0wlbv45b.xn--zvb692j9664aic1g; ‍ᠮⴞ🄂.🚗ࡁ𮹌‌; [B1, C1, C2, V6]; xn--h7e341b0wlbv45b.xn--zvb692j9664aic1g; ; ; # ᠮⴞ🄂.🚗ࡁ
+xn--2nd129ai554b.xn--zvb3124wpkpf; ᠮႾ🄂.🚗ࡁ𮹌; [B1, V6]; xn--2nd129ai554b.xn--zvb3124wpkpf; ; ; # ᠮႾ🄂.🚗ࡁ
+xn--2nd129ay2gnw71c.xn--zvb692j9664aic1g; ‍ᠮႾ🄂.🚗ࡁ𮹌‌; [B1, C1, C2, V6]; xn--2nd129ay2gnw71c.xn--zvb692j9664aic1g; ; ; # ᠮႾ🄂.🚗ࡁ
+؁ڗ.𑚶񼡷⾆; ؁ڗ.𑚶񼡷舌; [B1, P1, V5, V6]; xn--jfb41a.xn--tc1ap851axo39c; ; ; # ڗ.𑚶舌
+؁ڗ.𑚶񼡷舌; ; [B1, P1, V5, V6]; xn--jfb41a.xn--tc1ap851axo39c; ; ; # ڗ.𑚶舌
+xn--jfb41a.xn--tc1ap851axo39c; ؁ڗ.𑚶񼡷舌; [B1, V5, V6]; xn--jfb41a.xn--tc1ap851axo39c; ; ; # ڗ.𑚶舌
+🞅󠳡󜍙.񲖷; ; [P1, V6]; xn--ie9hi1349bqdlb.xn--oj69a; ; ; # 🞅.
+xn--ie9hi1349bqdlb.xn--oj69a; 🞅󠳡󜍙.񲖷; [V6]; xn--ie9hi1349bqdlb.xn--oj69a; ; ; # 🞅.
+⃧񯡎-򫣝.4Ⴄ‌; ; [C1, P1, V5, V6]; xn----9snu5320fi76w.xn--4-f0g649i; ; xn----9snu5320fi76w.xn--4-f0g; [P1, V5, V6] # ⃧-.4Ⴄ
+⃧񯡎-򫣝.4ⴄ‌; ; [C1, P1, V5, V6]; xn----9snu5320fi76w.xn--4-sgn589c; ; xn----9snu5320fi76w.xn--4-ivs; [P1, V5, V6] # ⃧-.4ⴄ
+xn----9snu5320fi76w.xn--4-ivs; ⃧񯡎-򫣝.4ⴄ; [V5, V6]; xn----9snu5320fi76w.xn--4-ivs; ; ; # ⃧-.4ⴄ
+xn----9snu5320fi76w.xn--4-sgn589c; ⃧񯡎-򫣝.4ⴄ‌; [C1, V5, V6]; xn----9snu5320fi76w.xn--4-sgn589c; ; ; # ⃧-.4ⴄ
+xn----9snu5320fi76w.xn--4-f0g; ⃧񯡎-򫣝.4Ⴄ; [V5, V6]; xn----9snu5320fi76w.xn--4-f0g; ; ; # ⃧-.4Ⴄ
+xn----9snu5320fi76w.xn--4-f0g649i; ⃧񯡎-򫣝.4Ⴄ‌; [C1, V5, V6]; xn----9snu5320fi76w.xn--4-f0g649i; ; ; # ⃧-.4Ⴄ
+ᚭ。𝌠ß𖫱; ᚭ.𝌠ß𖫱; ; xn--hwe.xn--zca4946pblnc; ; xn--hwe.xn--ss-ci1ub261a; # ᚭ.𝌠ß𖫱
+ᚭ。𝌠ß𖫱; ᚭ.𝌠ß𖫱; ; xn--hwe.xn--zca4946pblnc; ; xn--hwe.xn--ss-ci1ub261a; # ᚭ.𝌠ß𖫱
+ᚭ。𝌠SS𖫱; ᚭ.𝌠ss𖫱; ; xn--hwe.xn--ss-ci1ub261a; ; ; # ᚭ.𝌠ss𖫱
+ᚭ。𝌠ss𖫱; ᚭ.𝌠ss𖫱; ; xn--hwe.xn--ss-ci1ub261a; ; ; # ᚭ.𝌠ss𖫱
+ᚭ。𝌠Ss𖫱; ᚭ.𝌠ss𖫱; ; xn--hwe.xn--ss-ci1ub261a; ; ; # ᚭ.𝌠ss𖫱
+xn--hwe.xn--ss-ci1ub261a; ᚭ.𝌠ss𖫱; ; xn--hwe.xn--ss-ci1ub261a; ; ; # ᚭ.𝌠ss𖫱
+ᚭ.𝌠ss𖫱; ; ; xn--hwe.xn--ss-ci1ub261a; ; ; # ᚭ.𝌠ss𖫱
+ᚭ.𝌠SS𖫱; ᚭ.𝌠ss𖫱; ; xn--hwe.xn--ss-ci1ub261a; ; ; # ᚭ.𝌠ss𖫱
+ᚭ.𝌠Ss𖫱; ᚭ.𝌠ss𖫱; ; xn--hwe.xn--ss-ci1ub261a; ; ; # ᚭ.𝌠ss𖫱
+xn--hwe.xn--zca4946pblnc; ᚭ.𝌠ß𖫱; ; xn--hwe.xn--zca4946pblnc; ; ; # ᚭ.𝌠ß𖫱
+ᚭ.𝌠ß𖫱; ; ; xn--hwe.xn--zca4946pblnc; ; xn--hwe.xn--ss-ci1ub261a; # ᚭ.𝌠ß𖫱
+ᚭ。𝌠SS𖫱; ᚭ.𝌠ss𖫱; ; xn--hwe.xn--ss-ci1ub261a; ; ; # ᚭ.𝌠ss𖫱
+ᚭ。𝌠ss𖫱; ᚭ.𝌠ss𖫱; ; xn--hwe.xn--ss-ci1ub261a; ; ; # ᚭ.𝌠ss𖫱
+ᚭ。𝌠Ss𖫱; ᚭ.𝌠ss𖫱; ; xn--hwe.xn--ss-ci1ub261a; ; ; # ᚭ.𝌠ss𖫱
+₁。𞤫ꡪ; 1.𞤫ꡪ; [B1, B2, B3]; 1.xn--gd9al691d; ; ; # 1.𞤫ꡪ
+1。𞤫ꡪ; 1.𞤫ꡪ; [B1, B2, B3]; 1.xn--gd9al691d; ; ; # 1.𞤫ꡪ
+1。𞤉ꡪ; 1.𞤫ꡪ; [B1, B2, B3]; 1.xn--gd9al691d; ; ; # 1.𞤫ꡪ
+1.xn--gd9al691d; 1.𞤫ꡪ; [B1, B2, B3]; 1.xn--gd9al691d; ; ; # 1.𞤫ꡪ
+₁。𞤉ꡪ; 1.𞤫ꡪ; [B1, B2, B3]; 1.xn--gd9al691d; ; ; # 1.𞤫ꡪ
+𯻼‌.𞶞򻙤񥘇; ; [B2, B3, B6, C1, P1, V6]; xn--0ug27500a.xn--2b7hs861pl540a; ; xn--kg4n.xn--2b7hs861pl540a; [B2, B3, P1, V6] # .
+xn--kg4n.xn--2b7hs861pl540a; 𯻼.𞶞򻙤񥘇; [B2, B3, V6]; xn--kg4n.xn--2b7hs861pl540a; ; ; # .
+xn--0ug27500a.xn--2b7hs861pl540a; 𯻼‌.𞶞򻙤񥘇; [B2, B3, B6, C1, V6]; xn--0ug27500a.xn--2b7hs861pl540a; ; ; # .
+𑑄≯。𑜤; 𑑄≯.𑜤; [P1, V5, V6]; xn--hdh5636g.xn--ci2d; ; ; # 𑑄≯.𑜤
+𑑄≯。𑜤; 𑑄≯.𑜤; [P1, V5, V6]; xn--hdh5636g.xn--ci2d; ; ; # 𑑄≯.𑜤
+𑑄≯。𑜤; 𑑄≯.𑜤; [P1, V5, V6]; xn--hdh5636g.xn--ci2d; ; ; # 𑑄≯.𑜤
+𑑄≯。𑜤; 𑑄≯.𑜤; [P1, V5, V6]; xn--hdh5636g.xn--ci2d; ; ; # 𑑄≯.𑜤
+xn--hdh5636g.xn--ci2d; 𑑄≯.𑜤; [V5, V6]; xn--hdh5636g.xn--ci2d; ; ; # 𑑄≯.𑜤
+Ⴋ≮𱲆。‍ާ𐋣; Ⴋ≮𱲆.‍ާ𐋣; [C2, P1, V6]; xn--jnd802gsm17c.xn--lrb506jqr4n; ; xn--jnd802gsm17c.xn--lrb6479j; [P1, V5, V6] # Ⴋ≮.ާ𐋣
+Ⴋ≮𱲆。‍ާ𐋣; Ⴋ≮𱲆.‍ާ𐋣; [C2, P1, V6]; xn--jnd802gsm17c.xn--lrb506jqr4n; ; xn--jnd802gsm17c.xn--lrb6479j; [P1, V5, V6] # Ⴋ≮.ާ𐋣
+ⴋ≮𱲆。‍ާ𐋣; ⴋ≮𱲆.‍ާ𐋣; [C2, P1, V6]; xn--gdhz03bxt42d.xn--lrb506jqr4n; ; xn--gdhz03bxt42d.xn--lrb6479j; [P1, V5, V6] # ⴋ≮.ާ𐋣
+ⴋ≮𱲆。‍ާ𐋣; ⴋ≮𱲆.‍ާ𐋣; [C2, P1, V6]; xn--gdhz03bxt42d.xn--lrb506jqr4n; ; xn--gdhz03bxt42d.xn--lrb6479j; [P1, V5, V6] # ⴋ≮.ާ𐋣
+xn--gdhz03bxt42d.xn--lrb6479j; ⴋ≮𱲆.ާ𐋣; [V5, V6]; xn--gdhz03bxt42d.xn--lrb6479j; ; ; # ⴋ≮.ާ𐋣
+xn--gdhz03bxt42d.xn--lrb506jqr4n; ⴋ≮𱲆.‍ާ𐋣; [C2, V6]; xn--gdhz03bxt42d.xn--lrb506jqr4n; ; ; # ⴋ≮.ާ𐋣
+xn--jnd802gsm17c.xn--lrb6479j; Ⴋ≮𱲆.ާ𐋣; [V5, V6]; xn--jnd802gsm17c.xn--lrb6479j; ; ; # Ⴋ≮.ާ𐋣
+xn--jnd802gsm17c.xn--lrb506jqr4n; Ⴋ≮𱲆.‍ާ𐋣; [C2, V6]; xn--jnd802gsm17c.xn--lrb506jqr4n; ; ; # Ⴋ≮.ާ𐋣
+្.򆽒≯; ; [P1, V5, V6]; xn--u4e.xn--hdhx0084f; ; ; # ្.≯
+្.򆽒≯; ្.򆽒≯; [P1, V5, V6]; xn--u4e.xn--hdhx0084f; ; ; # ្.≯
+xn--u4e.xn--hdhx0084f; ្.򆽒≯; [V5, V6]; xn--u4e.xn--hdhx0084f; ; ; # ្.≯
+񏁇᜴.𐨺É⬓𑄴; 񏁇᜴.𐨺é⬓𑄴; [P1, V5, V6]; xn--c0e34564d.xn--9ca207st53lg3f; ; ; # ᜴.𐨺é⬓𑄴
+񏁇᜴.𐨺É⬓𑄴; 񏁇᜴.𐨺é⬓𑄴; [P1, V5, V6]; xn--c0e34564d.xn--9ca207st53lg3f; ; ; # ᜴.𐨺é⬓𑄴
+񏁇᜴.𐨺É⬓𑄴; 񏁇᜴.𐨺é⬓𑄴; [P1, V5, V6]; xn--c0e34564d.xn--9ca207st53lg3f; ; ; # ᜴.𐨺é⬓𑄴
+񏁇᜴.𐨺É⬓𑄴; 񏁇᜴.𐨺é⬓𑄴; [P1, V5, V6]; xn--c0e34564d.xn--9ca207st53lg3f; ; ; # ᜴.𐨺é⬓𑄴
+񏁇᜴.𐨺é⬓𑄴; 񏁇᜴.𐨺é⬓𑄴; [P1, V5, V6]; xn--c0e34564d.xn--9ca207st53lg3f; ; ; # ᜴.𐨺é⬓𑄴
+񏁇᜴.𐨺é⬓𑄴; ; [P1, V5, V6]; xn--c0e34564d.xn--9ca207st53lg3f; ; ; # ᜴.𐨺é⬓𑄴
+xn--c0e34564d.xn--9ca207st53lg3f; 񏁇᜴.𐨺é⬓𑄴; [V5, V6]; xn--c0e34564d.xn--9ca207st53lg3f; ; ; # ᜴.𐨺é⬓𑄴
+񏁇᜴.𐨺é⬓𑄴; 񏁇᜴.𐨺é⬓𑄴; [P1, V5, V6]; xn--c0e34564d.xn--9ca207st53lg3f; ; ; # ᜴.𐨺é⬓𑄴
+񏁇᜴.𐨺é⬓𑄴; 񏁇᜴.𐨺é⬓𑄴; [P1, V5, V6]; xn--c0e34564d.xn--9ca207st53lg3f; ; ; # ᜴.𐨺é⬓𑄴
+ᢇ‍꣄。︒𞤺; ᢇ‍꣄.︒𞤺; [B1, B6, C2, P1, V6]; xn--09e669a6x8j.xn--y86cv562b; ; xn--09e4694e.xn--y86cv562b; [B1, P1, V6] # ᢇ꣄.︒𞤺
+ᢇ‍꣄。。𞤺; ᢇ‍꣄..𞤺; [B6, C2, X4_2]; xn--09e669a6x8j..xn--ye6h; [B6, C2, A4_2]; xn--09e4694e..xn--ye6h; [A4_2] # ᢇ꣄..𞤺
+ᢇ‍꣄。。𞤘; ᢇ‍꣄..𞤺; [B6, C2, X4_2]; xn--09e669a6x8j..xn--ye6h; [B6, C2, A4_2]; xn--09e4694e..xn--ye6h; [A4_2] # ᢇ꣄..𞤺
+xn--09e4694e..xn--ye6h; ᢇ꣄..𞤺; [X4_2]; xn--09e4694e..xn--ye6h; [A4_2]; ; # ᢇ꣄..𞤺
+xn--09e669a6x8j..xn--ye6h; ᢇ‍꣄..𞤺; [B6, C2, X4_2]; xn--09e669a6x8j..xn--ye6h; [B6, C2, A4_2]; ; # ᢇ꣄..𞤺
+ᢇ‍꣄。︒𞤘; ᢇ‍꣄.︒𞤺; [B1, B6, C2, P1, V6]; xn--09e669a6x8j.xn--y86cv562b; ; xn--09e4694e.xn--y86cv562b; [B1, P1, V6] # ᢇ꣄.︒𞤺
+xn--09e4694e.xn--y86cv562b; ᢇ꣄.︒𞤺; [B1, V6]; xn--09e4694e.xn--y86cv562b; ; ; # ᢇ꣄.︒𞤺
+xn--09e669a6x8j.xn--y86cv562b; ᢇ‍꣄.︒𞤺; [B1, B6, C2, V6]; xn--09e669a6x8j.xn--y86cv562b; ; ; # ᢇ꣄.︒𞤺
+𞩬򖙱᜔‌。رު≮; 𞩬򖙱᜔‌.رު≮; [B2, B3, P1, V6]; xn--fze607b9651bjwl7c.xn--wgb86el10d; ; xn--fze3930v7hz6b.xn--wgb86el10d; # ᜔.رު≮
+𞩬򖙱᜔‌。رު≮; 𞩬򖙱᜔‌.رު≮; [B2, B3, P1, V6]; xn--fze607b9651bjwl7c.xn--wgb86el10d; ; xn--fze3930v7hz6b.xn--wgb86el10d; # ᜔.رު≮
+𞩬򖙱᜔‌。رު≮; 𞩬򖙱᜔‌.رު≮; [B2, B3, P1, V6]; xn--fze607b9651bjwl7c.xn--wgb86el10d; ; xn--fze3930v7hz6b.xn--wgb86el10d; # ᜔.رު≮
+𞩬򖙱᜔‌。رު≮; 𞩬򖙱᜔‌.رު≮; [B2, B3, P1, V6]; xn--fze607b9651bjwl7c.xn--wgb86el10d; ; xn--fze3930v7hz6b.xn--wgb86el10d; # ᜔.رު≮
+xn--fze3930v7hz6b.xn--wgb86el10d; 𞩬򖙱᜔.رު≮; [B2, B3, V6]; xn--fze3930v7hz6b.xn--wgb86el10d; ; ; # ᜔.رު≮
+xn--fze607b9651bjwl7c.xn--wgb86el10d; 𞩬򖙱᜔‌.رު≮; [B2, B3, V6]; xn--fze607b9651bjwl7c.xn--wgb86el10d; ; ; # ᜔.رު≮
+Ⴣ.ٓᢤ; Ⴣ.ٓᢤ; [P1, V5, V6]; xn--7nd.xn--vhb294g; ; ; # Ⴣ.ٓᢤ
+Ⴣ.ٓᢤ; ; [P1, V5, V6]; xn--7nd.xn--vhb294g; ; ; # Ⴣ.ٓᢤ
+ⴣ.ٓᢤ; ; [V5]; xn--rlj.xn--vhb294g; ; ; # ⴣ.ٓᢤ
+xn--rlj.xn--vhb294g; ⴣ.ٓᢤ; [V5]; xn--rlj.xn--vhb294g; ; ; # ⴣ.ٓᢤ
+xn--7nd.xn--vhb294g; Ⴣ.ٓᢤ; [V5, V6]; xn--7nd.xn--vhb294g; ; ; # Ⴣ.ٓᢤ
+ⴣ.ٓᢤ; ⴣ.ٓᢤ; [V5]; xn--rlj.xn--vhb294g; ; ; # ⴣ.ٓᢤ
+󠄈ࠓ.싉򄆻Ⴤ򂡐; ࠓ.싉򄆻Ⴤ򂡐; [P1, V6]; xn--oub.xn--8nd9522gpe69cviva; ; ; # ࠓ.싉Ⴤ
+󠄈ࠓ.싉򄆻Ⴤ򂡐; ࠓ.싉򄆻Ⴤ򂡐; [P1, V6]; xn--oub.xn--8nd9522gpe69cviva; ; ; # ࠓ.싉Ⴤ
+󠄈ࠓ.싉򄆻Ⴤ򂡐; ࠓ.싉򄆻Ⴤ򂡐; [P1, V6]; xn--oub.xn--8nd9522gpe69cviva; ; ; # ࠓ.싉Ⴤ
+󠄈ࠓ.싉򄆻Ⴤ򂡐; ࠓ.싉򄆻Ⴤ򂡐; [P1, V6]; xn--oub.xn--8nd9522gpe69cviva; ; ; # ࠓ.싉Ⴤ
+󠄈ࠓ.싉򄆻ⴤ򂡐; ࠓ.싉򄆻ⴤ򂡐; [P1, V6]; xn--oub.xn--sljz109bpe25dviva; ; ; # ࠓ.싉ⴤ
+󠄈ࠓ.싉򄆻ⴤ򂡐; ࠓ.싉򄆻ⴤ򂡐; [P1, V6]; xn--oub.xn--sljz109bpe25dviva; ; ; # ࠓ.싉ⴤ
+xn--oub.xn--sljz109bpe25dviva; ࠓ.싉򄆻ⴤ򂡐; [V6]; xn--oub.xn--sljz109bpe25dviva; ; ; # ࠓ.싉ⴤ
+xn--oub.xn--8nd9522gpe69cviva; ࠓ.싉򄆻Ⴤ򂡐; [V6]; xn--oub.xn--8nd9522gpe69cviva; ; ; # ࠓ.싉Ⴤ
+󠄈ࠓ.싉򄆻ⴤ򂡐; ࠓ.싉򄆻ⴤ򂡐; [P1, V6]; xn--oub.xn--sljz109bpe25dviva; ; ; # ࠓ.싉ⴤ
+󠄈ࠓ.싉򄆻ⴤ򂡐; ࠓ.싉򄆻ⴤ򂡐; [P1, V6]; xn--oub.xn--sljz109bpe25dviva; ; ; # ࠓ.싉ⴤ
+ꨬ𑲫≮.⤂; ꨬ𑲫≮.⤂; [P1, V5, V6]; xn--gdh1854cn19c.xn--kqi; ; ; # ꨬ𑲫≮.⤂
+ꨬ𑲫≮.⤂; ꨬ𑲫≮.⤂; [P1, V5, V6]; xn--gdh1854cn19c.xn--kqi; ; ; # ꨬ𑲫≮.⤂
+ꨬ𑲫≮.⤂; ; [P1, V5, V6]; xn--gdh1854cn19c.xn--kqi; ; ; # ꨬ𑲫≮.⤂
+ꨬ𑲫≮.⤂; ꨬ𑲫≮.⤂; [P1, V5, V6]; xn--gdh1854cn19c.xn--kqi; ; ; # ꨬ𑲫≮.⤂
+xn--gdh1854cn19c.xn--kqi; ꨬ𑲫≮.⤂; [V5, V6]; xn--gdh1854cn19c.xn--kqi; ; ; # ꨬ𑲫≮.⤂
+؄𐩔≮Ⴢ.Ⴃ; ؄𐩔≮Ⴢ.Ⴃ; [B1, P1, V6]; xn--mfb416c0jox02t.xn--bnd; ; ; # 𐩔≮Ⴢ.Ⴃ
+؄𐩔≮Ⴢ.Ⴃ; ؄𐩔≮Ⴢ.Ⴃ; [B1, P1, V6]; xn--mfb416c0jox02t.xn--bnd; ; ; # 𐩔≮Ⴢ.Ⴃ
+؄𐩔≮Ⴢ.Ⴃ; ; [B1, P1, V6]; xn--mfb416c0jox02t.xn--bnd; ; ; # 𐩔≮Ⴢ.Ⴃ
+؄𐩔≮Ⴢ.Ⴃ; ؄𐩔≮Ⴢ.Ⴃ; [B1, P1, V6]; xn--mfb416c0jox02t.xn--bnd; ; ; # 𐩔≮Ⴢ.Ⴃ
+؄𐩔≮ⴢ.ⴃ; ؄𐩔≮ⴢ.ⴃ; [B1, P1, V6]; xn--mfb266l4khr54u.xn--ukj; ; ; # 𐩔≮ⴢ.ⴃ
+؄𐩔≮ⴢ.ⴃ; ; [B1, P1, V6]; xn--mfb266l4khr54u.xn--ukj; ; ; # 𐩔≮ⴢ.ⴃ
+؄𐩔≮Ⴢ.ⴃ; ; [B1, P1, V6]; xn--mfb416c0jox02t.xn--ukj; ; ; # 𐩔≮Ⴢ.ⴃ
+؄𐩔≮Ⴢ.ⴃ; ؄𐩔≮Ⴢ.ⴃ; [B1, P1, V6]; xn--mfb416c0jox02t.xn--ukj; ; ; # 𐩔≮Ⴢ.ⴃ
+xn--mfb416c0jox02t.xn--ukj; ؄𐩔≮Ⴢ.ⴃ; [B1, V6]; xn--mfb416c0jox02t.xn--ukj; ; ; # 𐩔≮Ⴢ.ⴃ
+xn--mfb266l4khr54u.xn--ukj; ؄𐩔≮ⴢ.ⴃ; [B1, V6]; xn--mfb266l4khr54u.xn--ukj; ; ; # 𐩔≮ⴢ.ⴃ
+xn--mfb416c0jox02t.xn--bnd; ؄𐩔≮Ⴢ.Ⴃ; [B1, V6]; xn--mfb416c0jox02t.xn--bnd; ; ; # 𐩔≮Ⴢ.Ⴃ
+؄𐩔≮ⴢ.ⴃ; ؄𐩔≮ⴢ.ⴃ; [B1, P1, V6]; xn--mfb266l4khr54u.xn--ukj; ; ; # 𐩔≮ⴢ.ⴃ
+؄𐩔≮ⴢ.ⴃ; ؄𐩔≮ⴢ.ⴃ; [B1, P1, V6]; xn--mfb266l4khr54u.xn--ukj; ; ; # 𐩔≮ⴢ.ⴃ
+؄𐩔≮Ⴢ.ⴃ; ؄𐩔≮Ⴢ.ⴃ; [B1, P1, V6]; xn--mfb416c0jox02t.xn--ukj; ; ; # 𐩔≮Ⴢ.ⴃ
+؄𐩔≮Ⴢ.ⴃ; ؄𐩔≮Ⴢ.ⴃ; [B1, P1, V6]; xn--mfb416c0jox02t.xn--ukj; ; ; # 𐩔≮Ⴢ.ⴃ
+𑁅。-; 𑁅.-; [V3, V5]; xn--210d.-; ; ; # 𑁅.-
+xn--210d.-; 𑁅.-; [V3, V5]; xn--210d.-; ; ; # 𑁅.-
+්򕸽󠧱。饈≠٤; ්򕸽󠧱.饈≠٤; [B1, B5, B6, P1, V5, V6]; xn--h1c25913jfwov.xn--dib144ler5f; ; ; # ්.饈≠٤
+්򕸽󠧱。饈≠٤; ්򕸽󠧱.饈≠٤; [B1, B5, B6, P1, V5, V6]; xn--h1c25913jfwov.xn--dib144ler5f; ; ; # ්.饈≠٤
+්򕸽󠧱。饈≠٤; ්򕸽󠧱.饈≠٤; [B1, B5, B6, P1, V5, V6]; xn--h1c25913jfwov.xn--dib144ler5f; ; ; # ්.饈≠٤
+්򕸽󠧱。饈≠٤; ්򕸽󠧱.饈≠٤; [B1, B5, B6, P1, V5, V6]; xn--h1c25913jfwov.xn--dib144ler5f; ; ; # ්.饈≠٤
+xn--h1c25913jfwov.xn--dib144ler5f; ්򕸽󠧱.饈≠٤; [B1, B5, B6, V5, V6]; xn--h1c25913jfwov.xn--dib144ler5f; ; ; # ්.饈≠٤
+𞥃ᠠ⁷。≯邅⬻4; 𞥃ᠠ7.≯邅⬻4; [B1, B2, P1, V6]; xn--7-v4j2826w.xn--4-ogoy01bou3i; ; ; # 𞥃ᠠ7.≯邅⬻4
+𞥃ᠠ⁷。≯邅⬻4; 𞥃ᠠ7.≯邅⬻4; [B1, B2, P1, V6]; xn--7-v4j2826w.xn--4-ogoy01bou3i; ; ; # 𞥃ᠠ7.≯邅⬻4
+𞥃ᠠ7。≯邅⬻4; 𞥃ᠠ7.≯邅⬻4; [B1, B2, P1, V6]; xn--7-v4j2826w.xn--4-ogoy01bou3i; ; ; # 𞥃ᠠ7.≯邅⬻4
+𞥃ᠠ7。≯邅⬻4; 𞥃ᠠ7.≯邅⬻4; [B1, B2, P1, V6]; xn--7-v4j2826w.xn--4-ogoy01bou3i; ; ; # 𞥃ᠠ7.≯邅⬻4
+𞤡ᠠ7。≯邅⬻4; 𞥃ᠠ7.≯邅⬻4; [B1, B2, P1, V6]; xn--7-v4j2826w.xn--4-ogoy01bou3i; ; ; # 𞥃ᠠ7.≯邅⬻4
+𞤡ᠠ7。≯邅⬻4; 𞥃ᠠ7.≯邅⬻4; [B1, B2, P1, V6]; xn--7-v4j2826w.xn--4-ogoy01bou3i; ; ; # 𞥃ᠠ7.≯邅⬻4
+xn--7-v4j2826w.xn--4-ogoy01bou3i; 𞥃ᠠ7.≯邅⬻4; [B1, B2, V6]; xn--7-v4j2826w.xn--4-ogoy01bou3i; ; ; # 𞥃ᠠ7.≯邅⬻4
+𞤡ᠠ⁷。≯邅⬻4; 𞥃ᠠ7.≯邅⬻4; [B1, B2, P1, V6]; xn--7-v4j2826w.xn--4-ogoy01bou3i; ; ; # 𞥃ᠠ7.≯邅⬻4
+𞤡ᠠ⁷。≯邅⬻4; 𞥃ᠠ7.≯邅⬻4; [B1, B2, P1, V6]; xn--7-v4j2826w.xn--4-ogoy01bou3i; ; ; # 𞥃ᠠ7.≯邅⬻4
+򠿯ᡳ-𑐻.𐹴𐋫؅󑎳; ; [B1, B6, P1, V6]; xn----m9j3429kxmy7e.xn--nfb7950kdihrp812a; ; ; # ᡳ-𑐻.𐹴𐋫
+xn----m9j3429kxmy7e.xn--nfb7950kdihrp812a; 򠿯ᡳ-𑐻.𐹴𐋫؅󑎳; [B1, B6, V6]; xn----m9j3429kxmy7e.xn--nfb7950kdihrp812a; ; ; # ᡳ-𑐻.𐹴𐋫
+򠶆ࡅੑ.넨-󶧈; ; [B5, B6, P1, V6]; xn--3vb26hb6834b.xn----i37ez0957g; ; ; # ࡅੑ.넨-
+򠶆ࡅੑ.넨-󶧈; 򠶆ࡅੑ.넨-󶧈; [B5, B6, P1, V6]; xn--3vb26hb6834b.xn----i37ez0957g; ; ; # ࡅੑ.넨-
+xn--3vb26hb6834b.xn----i37ez0957g; 򠶆ࡅੑ.넨-󶧈; [B5, B6, V6]; xn--3vb26hb6834b.xn----i37ez0957g; ; ; # ࡅੑ.넨-
+ꡦᡑ‍⒈。𐋣-; ꡦᡑ‍⒈.𐋣-; [C2, P1, V3, V6]; xn--h8e470bl0d838o.xn----381i; ; xn--h8e863drj7h.xn----381i; [P1, V3, V6] # ꡦᡑ⒈.𐋣-
+ꡦᡑ‍1.。𐋣-; ꡦᡑ‍1..𐋣-; [C2, V3, X4_2]; xn--1-o7j663bdl7m..xn----381i; [C2, V3, A4_2]; xn--1-o7j0610f..xn----381i; [V3, A4_2] # ꡦᡑ1..𐋣-
+xn--1-o7j0610f..xn----381i; ꡦᡑ1..𐋣-; [V3, X4_2]; xn--1-o7j0610f..xn----381i; [V3, A4_2]; ; # ꡦᡑ1..𐋣-
+xn--1-o7j663bdl7m..xn----381i; ꡦᡑ‍1..𐋣-; [C2, V3, X4_2]; xn--1-o7j663bdl7m..xn----381i; [C2, V3, A4_2]; ; # ꡦᡑ1..𐋣-
+xn--h8e863drj7h.xn----381i; ꡦᡑ⒈.𐋣-; [V3, V6]; xn--h8e863drj7h.xn----381i; ; ; # ꡦᡑ⒈.𐋣-
+xn--h8e470bl0d838o.xn----381i; ꡦᡑ‍⒈.𐋣-; [C2, V3, V6]; xn--h8e470bl0d838o.xn----381i; ; ; # ꡦᡑ⒈.𐋣-
+Ⴌ。􍼠ﭩ; Ⴌ.􍼠ٹ; [B5, B6, P1, V6]; xn--knd.xn--yib19191t; ; ; # Ⴌ.ٹ
+Ⴌ。􍼠ٹ; Ⴌ.􍼠ٹ; [B5, B6, P1, V6]; xn--knd.xn--yib19191t; ; ; # Ⴌ.ٹ
+ⴌ。􍼠ٹ; ⴌ.􍼠ٹ; [B5, B6, P1, V6]; xn--3kj.xn--yib19191t; ; ; # ⴌ.ٹ
+xn--3kj.xn--yib19191t; ⴌ.􍼠ٹ; [B5, B6, V6]; xn--3kj.xn--yib19191t; ; ; # ⴌ.ٹ
+xn--knd.xn--yib19191t; Ⴌ.􍼠ٹ; [B5, B6, V6]; xn--knd.xn--yib19191t; ; ; # Ⴌ.ٹ
+ⴌ。􍼠ﭩ; ⴌ.􍼠ٹ; [B5, B6, P1, V6]; xn--3kj.xn--yib19191t; ; ; # ⴌ.ٹ
+𐮁𐭱.྄፞-ᳺ; ; [B1, V5]; xn--r19c5a.xn----xjg270ag3m; ; ; # 𐮁𐭱.྄፞-ᳺ
+xn--r19c5a.xn----xjg270ag3m; 𐮁𐭱.྄፞-ᳺ; [B1, V5]; xn--r19c5a.xn----xjg270ag3m; ; ; # 𐮁𐭱.྄፞-ᳺ
+⒈䰹‍-。웈; ⒈䰹‍-.웈; [C2, P1, V3, V6]; xn----tgnx5rjr6c.xn--kp5b; ; xn----dcp160o.xn--kp5b; [P1, V3, V6] # ⒈䰹-.웈
+⒈䰹‍-。웈; ⒈䰹‍-.웈; [C2, P1, V3, V6]; xn----tgnx5rjr6c.xn--kp5b; ; xn----dcp160o.xn--kp5b; [P1, V3, V6] # ⒈䰹-.웈
+1.䰹‍-。웈; 1.䰹‍-.웈; [C2, V3]; 1.xn----tgnz80r.xn--kp5b; ; 1.xn----zw5a.xn--kp5b; [V3] # 1.䰹-.웈
+1.䰹‍-。웈; 1.䰹‍-.웈; [C2, V3]; 1.xn----tgnz80r.xn--kp5b; ; 1.xn----zw5a.xn--kp5b; [V3] # 1.䰹-.웈
+1.xn----zw5a.xn--kp5b; 1.䰹-.웈; [V3]; 1.xn----zw5a.xn--kp5b; ; ; # 1.䰹-.웈
+1.xn----tgnz80r.xn--kp5b; 1.䰹‍-.웈; [C2, V3]; 1.xn----tgnz80r.xn--kp5b; ; ; # 1.䰹-.웈
+xn----dcp160o.xn--kp5b; ⒈䰹-.웈; [V3, V6]; xn----dcp160o.xn--kp5b; ; ; # ⒈䰹-.웈
+xn----tgnx5rjr6c.xn--kp5b; ⒈䰹‍-.웈; [C2, V3, V6]; xn----tgnx5rjr6c.xn--kp5b; ; ; # ⒈䰹-.웈
+て。‌󠳽߳; て.‌󠳽߳; [C1, P1, V6]; xn--m9j.xn--rtb154j9l73w; ; xn--m9j.xn--rtb10784p; [P1, V6] # て.߳
+xn--m9j.xn--rtb10784p; て.󠳽߳; [V6]; xn--m9j.xn--rtb10784p; ; ; # て.߳
+xn--m9j.xn--rtb154j9l73w; て.‌󠳽߳; [C1, V6]; xn--m9j.xn--rtb154j9l73w; ; ; # て.߳
+ς。꧀ۧ; ς.꧀ۧ; [V5]; xn--3xa.xn--3lb1944f; ; xn--4xa.xn--3lb1944f; # ς.꧀ۧ
+ς。꧀ۧ; ς.꧀ۧ; [V5]; xn--3xa.xn--3lb1944f; ; xn--4xa.xn--3lb1944f; # ς.꧀ۧ
+Σ。꧀ۧ; σ.꧀ۧ; [V5]; xn--4xa.xn--3lb1944f; ; ; # σ.꧀ۧ
+σ。꧀ۧ; σ.꧀ۧ; [V5]; xn--4xa.xn--3lb1944f; ; ; # σ.꧀ۧ
+xn--4xa.xn--3lb1944f; σ.꧀ۧ; [V5]; xn--4xa.xn--3lb1944f; ; ; # σ.꧀ۧ
+xn--3xa.xn--3lb1944f; ς.꧀ۧ; [V5]; xn--3xa.xn--3lb1944f; ; ; # ς.꧀ۧ
+Σ。꧀ۧ; σ.꧀ۧ; [V5]; xn--4xa.xn--3lb1944f; ; ; # σ.꧀ۧ
+σ。꧀ۧ; σ.꧀ۧ; [V5]; xn--4xa.xn--3lb1944f; ; ; # σ.꧀ۧ
+்󥫅򌉑.ႢႵ; ; [P1, V5, V6]; xn--xmc83135idcxza.xn--9md2b; ; ; # ்.ႢႵ
+்󥫅򌉑.ⴂⴕ; ; [P1, V5, V6]; xn--xmc83135idcxza.xn--tkjwb; ; ; # ்.ⴂⴕ
+்󥫅򌉑.Ⴂⴕ; ; [P1, V5, V6]; xn--xmc83135idcxza.xn--9md086l; ; ; # ்.Ⴂⴕ
+xn--xmc83135idcxza.xn--9md086l; ்󥫅򌉑.Ⴂⴕ; [V5, V6]; xn--xmc83135idcxza.xn--9md086l; ; ; # ்.Ⴂⴕ
+xn--xmc83135idcxza.xn--tkjwb; ்󥫅򌉑.ⴂⴕ; [V5, V6]; xn--xmc83135idcxza.xn--tkjwb; ; ; # ்.ⴂⴕ
+xn--xmc83135idcxza.xn--9md2b; ்󥫅򌉑.ႢႵ; [V5, V6]; xn--xmc83135idcxza.xn--9md2b; ; ; # ்.ႢႵ
+ᰲ🄈⾛֦.‍򯥤߽; ᰲ🄈走֦.‍򯥤߽; [C2, P1, V5, V6]; xn--xcb756i493fwi5o.xn--1tb334j1197q; ; xn--xcb756i493fwi5o.xn--1tb13454l; [P1, V5, V6] # ᰲ🄈走֦.߽
+ᰲ7,走֦.‍򯥤߽; ; [C2, P1, V5, V6]; xn--7,-bid991urn3k.xn--1tb334j1197q; ; xn--7,-bid991urn3k.xn--1tb13454l; [P1, V5, V6] # ᰲ7,走֦.߽
+xn--7,-bid991urn3k.xn--1tb13454l; ᰲ7,走֦.򯥤߽; [P1, V5, V6]; xn--7,-bid991urn3k.xn--1tb13454l; ; ; # ᰲ7,走֦.߽
+xn--7,-bid991urn3k.xn--1tb334j1197q; ᰲ7,走֦.‍򯥤߽; [C2, P1, V5, V6]; xn--7,-bid991urn3k.xn--1tb334j1197q; ; ; # ᰲ7,走֦.߽
+xn--xcb756i493fwi5o.xn--1tb13454l; ᰲ🄈走֦.򯥤߽; [V5, V6]; xn--xcb756i493fwi5o.xn--1tb13454l; ; ; # ᰲ🄈走֦.߽
+xn--xcb756i493fwi5o.xn--1tb334j1197q; ᰲ🄈走֦.‍򯥤߽; [C2, V5, V6]; xn--xcb756i493fwi5o.xn--1tb334j1197q; ; ; # ᰲ🄈走֦.߽
+ᢗ。Ӏ񝄻; ᢗ.Ӏ񝄻; [P1, V6]; xn--hbf.xn--d5a86117e; ; ; # ᢗ.Ӏ
+ᢗ。Ӏ񝄻; ᢗ.Ӏ񝄻; [P1, V6]; xn--hbf.xn--d5a86117e; ; ; # ᢗ.Ӏ
+ᢗ。ӏ񝄻; ᢗ.ӏ񝄻; [P1, V6]; xn--hbf.xn--s5a83117e; ; ; # ᢗ.ӏ
+xn--hbf.xn--s5a83117e; ᢗ.ӏ񝄻; [V6]; xn--hbf.xn--s5a83117e; ; ; # ᢗ.ӏ
+xn--hbf.xn--d5a86117e; ᢗ.Ӏ񝄻; [V6]; xn--hbf.xn--d5a86117e; ; ; # ᢗ.Ӏ
+ᢗ。ӏ񝄻; ᢗ.ӏ񝄻; [P1, V6]; xn--hbf.xn--s5a83117e; ; ; # ᢗ.ӏ
+٨-。񠏇🝆ᄾ; ٨-.񠏇🝆ᄾ; [B1, P1, V3, V6]; xn----oqc.xn--qrd1699v327w; ; ; # ٨-.🝆ᄾ
+xn----oqc.xn--qrd1699v327w; ٨-.񠏇🝆ᄾ; [B1, V3, V6]; xn----oqc.xn--qrd1699v327w; ; ; # ٨-.🝆ᄾ
+-𐋷𖾑。󠆬; -𐋷𖾑.; [V3]; xn----991iq40y.; ; ; # -𐋷𖾑.
+xn----991iq40y.; -𐋷𖾑.; [V3]; xn----991iq40y.; ; ; # -𐋷𖾑.
+‌𐹳🐴멈.꯭񐡼; ; [B1, C1, P1, V5, V6]; xn--0ug6681d406b7bwk.xn--429a8682s; ; xn--422b325mqb6i.xn--429a8682s; [B1, P1, V5, V6] # 𐹳🐴멈.꯭
+‌𐹳🐴멈.꯭񐡼; ‌𐹳🐴멈.꯭񐡼; [B1, C1, P1, V5, V6]; xn--0ug6681d406b7bwk.xn--429a8682s; ; xn--422b325mqb6i.xn--429a8682s; [B1, P1, V5, V6] # 𐹳🐴멈.꯭
+xn--422b325mqb6i.xn--429a8682s; 𐹳🐴멈.꯭񐡼; [B1, V5, V6]; xn--422b325mqb6i.xn--429a8682s; ; ; # 𐹳🐴멈.꯭
+xn--0ug6681d406b7bwk.xn--429a8682s; ‌𐹳🐴멈.꯭񐡼; [B1, C1, V5, V6]; xn--0ug6681d406b7bwk.xn--429a8682s; ; ; # 𐹳🐴멈.꯭
+≮.ݩ؃; ; [B1, P1, V6]; xn--gdh.xn--lfb92e; ; ; # ≮.ݩ
+≮.ݩ؃; ≮.ݩ؃; [B1, P1, V6]; xn--gdh.xn--lfb92e; ; ; # ≮.ݩ
+xn--gdh.xn--lfb92e; ≮.ݩ؃; [B1, V6]; xn--gdh.xn--lfb92e; ; ; # ≮.ݩ
+𐶭⾆。‌𑚶򟱃𞰘; 𐶭舌.‌𑚶򟱃𞰘; [B1, B2, B3, C1, P1, V6]; xn--tc1ao37z.xn--0ugx728gi1nfwqz2e; ; xn--tc1ao37z.xn--6e2dw557azds2d; [B2, B3, B5, B6, P1, V5, V6] # 舌.𑚶
+𐶭舌。‌𑚶򟱃𞰘; 𐶭舌.‌𑚶򟱃𞰘; [B1, B2, B3, C1, P1, V6]; xn--tc1ao37z.xn--0ugx728gi1nfwqz2e; ; xn--tc1ao37z.xn--6e2dw557azds2d; [B2, B3, B5, B6, P1, V5, V6] # 舌.𑚶
+xn--tc1ao37z.xn--6e2dw557azds2d; 𐶭舌.𑚶򟱃𞰘; [B2, B3, B5, B6, V5, V6]; xn--tc1ao37z.xn--6e2dw557azds2d; ; ; # 舌.𑚶
+xn--tc1ao37z.xn--0ugx728gi1nfwqz2e; 𐶭舌.‌𑚶򟱃𞰘; [B1, B2, B3, C1, V6]; xn--tc1ao37z.xn--0ugx728gi1nfwqz2e; ; ; # 舌.𑚶
+‌Ⴠ-.𝟷ς𞴺ς; ‌Ⴠ-.1ς𞴺ς; [B1, C1, P1, V3, V6]; xn----z1g168i.xn--1-ymba92321c; ; xn----z1g.xn--1-0mba52321c; [B1, B6, P1, V3, V6] # Ⴠ-.1ς𞴺ς
+‌Ⴠ-.1ς𞴺ς; ; [B1, C1, P1, V3, V6]; xn----z1g168i.xn--1-ymba92321c; ; xn----z1g.xn--1-0mba52321c; [B1, B6, P1, V3, V6] # Ⴠ-.1ς𞴺ς
+‌ⴠ-.1ς𞴺ς; ; [B1, C1, V3]; xn----rgn530d.xn--1-ymba92321c; ; xn----2ws.xn--1-0mba52321c; [B1, B6, V3] # ⴠ-.1ς𞴺ς
+‌Ⴠ-.1Σ𞴺Σ; ‌Ⴠ-.1σ𞴺σ; [B1, C1, P1, V3, V6]; xn----z1g168i.xn--1-0mba52321c; ; xn----z1g.xn--1-0mba52321c; [B1, B6, P1, V3, V6] # Ⴠ-.1σ𞴺σ
+‌ⴠ-.1σ𞴺σ; ; [B1, C1, V3]; xn----rgn530d.xn--1-0mba52321c; ; xn----2ws.xn--1-0mba52321c; [B1, B6, V3] # ⴠ-.1σ𞴺σ
+‌Ⴠ-.1σ𞴺Σ; ‌Ⴠ-.1σ𞴺σ; [B1, C1, P1, V3, V6]; xn----z1g168i.xn--1-0mba52321c; ; xn----z1g.xn--1-0mba52321c; [B1, B6, P1, V3, V6] # Ⴠ-.1σ𞴺σ
+xn----z1g.xn--1-0mba52321c; Ⴠ-.1σ𞴺σ; [B1, B6, V3, V6]; xn----z1g.xn--1-0mba52321c; ; ; # Ⴠ-.1σ𞴺σ
+xn----z1g168i.xn--1-0mba52321c; ‌Ⴠ-.1σ𞴺σ; [B1, C1, V3, V6]; xn----z1g168i.xn--1-0mba52321c; ; ; # Ⴠ-.1σ𞴺σ
+xn----2ws.xn--1-0mba52321c; ⴠ-.1σ𞴺σ; [B1, B6, V3]; xn----2ws.xn--1-0mba52321c; ; ; # ⴠ-.1σ𞴺σ
+xn----rgn530d.xn--1-0mba52321c; ‌ⴠ-.1σ𞴺σ; [B1, C1, V3]; xn----rgn530d.xn--1-0mba52321c; ; ; # ⴠ-.1σ𞴺σ
+‌Ⴠ-.1ς𞴺Σ; ‌Ⴠ-.1ς𞴺σ; [B1, C1, P1, V3, V6]; xn----z1g168i.xn--1-ymbd52321c; ; xn----z1g.xn--1-0mba52321c; [B1, B6, P1, V3, V6] # Ⴠ-.1ς𞴺σ
+‌ⴠ-.1ς𞴺σ; ; [B1, C1, V3]; xn----rgn530d.xn--1-ymbd52321c; ; xn----2ws.xn--1-0mba52321c; [B1, B6, V3] # ⴠ-.1ς𞴺σ
+xn----rgn530d.xn--1-ymbd52321c; ‌ⴠ-.1ς𞴺σ; [B1, C1, V3]; xn----rgn530d.xn--1-ymbd52321c; ; ; # ⴠ-.1ς𞴺σ
+xn----z1g168i.xn--1-ymbd52321c; ‌Ⴠ-.1ς𞴺σ; [B1, C1, V3, V6]; xn----z1g168i.xn--1-ymbd52321c; ; ; # Ⴠ-.1ς𞴺σ
+xn----rgn530d.xn--1-ymba92321c; ‌ⴠ-.1ς𞴺ς; [B1, C1, V3]; xn----rgn530d.xn--1-ymba92321c; ; ; # ⴠ-.1ς𞴺ς
+xn----z1g168i.xn--1-ymba92321c; ‌Ⴠ-.1ς𞴺ς; [B1, C1, V3, V6]; xn----z1g168i.xn--1-ymba92321c; ; ; # Ⴠ-.1ς𞴺ς
+‌ⴠ-.𝟷ς𞴺ς; ‌ⴠ-.1ς𞴺ς; [B1, C1, V3]; xn----rgn530d.xn--1-ymba92321c; ; xn----2ws.xn--1-0mba52321c; [B1, B6, V3] # ⴠ-.1ς𞴺ς
+‌Ⴠ-.𝟷Σ𞴺Σ; ‌Ⴠ-.1σ𞴺σ; [B1, C1, P1, V3, V6]; xn----z1g168i.xn--1-0mba52321c; ; xn----z1g.xn--1-0mba52321c; [B1, B6, P1, V3, V6] # Ⴠ-.1σ𞴺σ
+‌ⴠ-.𝟷σ𞴺σ; ‌ⴠ-.1σ𞴺σ; [B1, C1, V3]; xn----rgn530d.xn--1-0mba52321c; ; xn----2ws.xn--1-0mba52321c; [B1, B6, V3] # ⴠ-.1σ𞴺σ
+‌Ⴠ-.𝟷σ𞴺Σ; ‌Ⴠ-.1σ𞴺σ; [B1, C1, P1, V3, V6]; xn----z1g168i.xn--1-0mba52321c; ; xn----z1g.xn--1-0mba52321c; [B1, B6, P1, V3, V6] # Ⴠ-.1σ𞴺σ
+‌Ⴠ-.𝟷ς𞴺Σ; ‌Ⴠ-.1ς𞴺σ; [B1, C1, P1, V3, V6]; xn----z1g168i.xn--1-ymbd52321c; ; xn----z1g.xn--1-0mba52321c; [B1, B6, P1, V3, V6] # Ⴠ-.1ς𞴺σ
+‌ⴠ-.𝟷ς𞴺σ; ‌ⴠ-.1ς𞴺σ; [B1, C1, V3]; xn----rgn530d.xn--1-ymbd52321c; ; xn----2ws.xn--1-0mba52321c; [B1, B6, V3] # ⴠ-.1ς𞴺σ
+𑲘󠄒𓑡。𝟪Ⴜ; 𑲘𓑡.8Ⴜ; [P1, V5, V6]; xn--7m3d291b.xn--8-s1g; ; ; # 𑲘.8Ⴜ
+𑲘󠄒𓑡。8Ⴜ; 𑲘𓑡.8Ⴜ; [P1, V5, V6]; xn--7m3d291b.xn--8-s1g; ; ; # 𑲘.8Ⴜ
+𑲘󠄒𓑡。8ⴜ; 𑲘𓑡.8ⴜ; [P1, V5, V6]; xn--7m3d291b.xn--8-vws; ; ; # 𑲘.8ⴜ
+xn--7m3d291b.xn--8-vws; 𑲘𓑡.8ⴜ; [V5, V6]; xn--7m3d291b.xn--8-vws; ; ; # 𑲘.8ⴜ
+xn--7m3d291b.xn--8-s1g; 𑲘𓑡.8Ⴜ; [V5, V6]; xn--7m3d291b.xn--8-s1g; ; ; # 𑲘.8Ⴜ
+𑲘󠄒𓑡。𝟪ⴜ; 𑲘𓑡.8ⴜ; [P1, V5, V6]; xn--7m3d291b.xn--8-vws; ; ; # 𑲘.8ⴜ
+䪏ګߠु。뭕ᢝឹ; 䪏ګߠु.뭕ᢝឹ; [B5, B6]; xn--ekb23dj4at01n.xn--43e96bh910b; ; ; # 䪏ګߠु.뭕ᢝឹ
+䪏ګߠु。뭕ᢝឹ; 䪏ګߠु.뭕ᢝឹ; [B5, B6]; xn--ekb23dj4at01n.xn--43e96bh910b; ; ; # 䪏ګߠु.뭕ᢝឹ
+䪏ګߠु。뭕ᢝឹ; 䪏ګߠु.뭕ᢝឹ; [B5, B6]; xn--ekb23dj4at01n.xn--43e96bh910b; ; ; # 䪏ګߠु.뭕ᢝឹ
+䪏ګߠु。뭕ᢝឹ; 䪏ګߠु.뭕ᢝឹ; [B5, B6]; xn--ekb23dj4at01n.xn--43e96bh910b; ; ; # 䪏ګߠु.뭕ᢝឹ
+xn--ekb23dj4at01n.xn--43e96bh910b; 䪏ګߠु.뭕ᢝឹ; [B5, B6]; xn--ekb23dj4at01n.xn--43e96bh910b; ; ; # 䪏ګߠु.뭕ᢝឹ
+᮫。🂉󠁰; ᮫.🂉󠁰; [P1, V5, V6]; xn--zxf.xn--fx7ho0250c; ; ; # ᮫.🂉
+᮫。🂉󠁰; ᮫.🂉󠁰; [P1, V5, V6]; xn--zxf.xn--fx7ho0250c; ; ; # ᮫.🂉
+xn--zxf.xn--fx7ho0250c; ᮫.🂉󠁰; [V5, V6]; xn--zxf.xn--fx7ho0250c; ; ; # ᮫.🂉
+󩎃ૄ。ς‍𐹮𑈵; 󩎃ૄ.ς‍𐹮𑈵; [B5, C2, P1, V6]; xn--dfc53161q.xn--3xa006lzo7nsfd; ; xn--dfc53161q.xn--4xa8467k5mc; [B5, P1, V6] # ૄ.ς𐹮𑈵
+󩎃ૄ。Σ‍𐹮𑈵; 󩎃ૄ.σ‍𐹮𑈵; [B5, C2, P1, V6]; xn--dfc53161q.xn--4xa895lzo7nsfd; ; xn--dfc53161q.xn--4xa8467k5mc; [B5, P1, V6] # ૄ.σ𐹮𑈵
+󩎃ૄ。σ‍𐹮𑈵; 󩎃ૄ.σ‍𐹮𑈵; [B5, C2, P1, V6]; xn--dfc53161q.xn--4xa895lzo7nsfd; ; xn--dfc53161q.xn--4xa8467k5mc; [B5, P1, V6] # ૄ.σ𐹮𑈵
+xn--dfc53161q.xn--4xa8467k5mc; 󩎃ૄ.σ𐹮𑈵; [B5, V6]; xn--dfc53161q.xn--4xa8467k5mc; ; ; # ૄ.σ𐹮𑈵
+xn--dfc53161q.xn--4xa895lzo7nsfd; 󩎃ૄ.σ‍𐹮𑈵; [B5, C2, V6]; xn--dfc53161q.xn--4xa895lzo7nsfd; ; ; # ૄ.σ𐹮𑈵
+xn--dfc53161q.xn--3xa006lzo7nsfd; 󩎃ૄ.ς‍𐹮𑈵; [B5, C2, V6]; xn--dfc53161q.xn--3xa006lzo7nsfd; ; ; # ૄ.ς𐹮𑈵
+𐫀ᡂ𑜫.𑘿; 𐫀ᡂ𑜫.𑘿; [B1, B2, B3, B6, V5]; xn--17e9625js1h.xn--sb2d; ; ; # 𐫀ᡂ𑜫.𑘿
+𐫀ᡂ𑜫.𑘿; ; [B1, B2, B3, B6, V5]; xn--17e9625js1h.xn--sb2d; ; ; # 𐫀ᡂ𑜫.𑘿
+xn--17e9625js1h.xn--sb2d; 𐫀ᡂ𑜫.𑘿; [B1, B2, B3, B6, V5]; xn--17e9625js1h.xn--sb2d; ; ; # 𐫀ᡂ𑜫.𑘿
+󬚶󸋖򖩰-。‌; 󬚶󸋖򖩰-.‌; [C1, P1, V3, V6]; xn----7i12hu122k9ire.xn--0ug; ; xn----7i12hu122k9ire.; [P1, V3, V6] # -.
+xn----7i12hu122k9ire.; 󬚶󸋖򖩰-.; [V3, V6]; xn----7i12hu122k9ire.; ; ; # -.
+xn----7i12hu122k9ire.xn--0ug; 󬚶󸋖򖩰-.‌; [C1, V3, V6]; xn----7i12hu122k9ire.xn--0ug; ; ; # -.
+𐹣.߂; 𐹣.߂; [B1]; xn--bo0d.xn--dsb; ; ; # 𐹣.߂
+𐹣.߂; ; [B1]; xn--bo0d.xn--dsb; ; ; # 𐹣.߂
+xn--bo0d.xn--dsb; 𐹣.߂; [B1]; xn--bo0d.xn--dsb; ; ; # 𐹣.߂
+-ߡ。Ↄ; -ߡ.Ↄ; [B1, P1, V3, V6]; xn----8cd.xn--q5g; ; ; # -ߡ.Ↄ
+-ߡ。Ↄ; -ߡ.Ↄ; [B1, P1, V3, V6]; xn----8cd.xn--q5g; ; ; # -ߡ.Ↄ
+-ߡ。ↄ; -ߡ.ↄ; [B1, V3]; xn----8cd.xn--r5g; ; ; # -ߡ.ↄ
+xn----8cd.xn--r5g; -ߡ.ↄ; [B1, V3]; xn----8cd.xn--r5g; ; ; # -ߡ.ↄ
+xn----8cd.xn--q5g; -ߡ.Ↄ; [B1, V3, V6]; xn----8cd.xn--q5g; ; ; # -ߡ.Ↄ
+-ߡ。ↄ; -ߡ.ↄ; [B1, V3]; xn----8cd.xn--r5g; ; ; # -ߡ.ↄ
+‍-︒󠄄。ß哑‌𐵿; ‍-︒.ß哑‌𐵿; [B1, B5, B6, C1, C2, P1, V6]; xn----tgnt341h.xn--zca670n5f0binyk; ; xn----o89h.xn--ss-h46c5711e; [B1, B5, B6, P1, V3, V6] # -︒.ß哑
+‍-。󠄄。ß哑‌𐵿; ‍-..ß哑‌𐵿; [B1, B5, B6, C1, C2, P1, V3, V6, X4_2]; xn----tgn..xn--zca670n5f0binyk; [B1, B5, B6, C1, C2, P1, V3, V6, A4_2]; -..xn--ss-h46c5711e; [B1, B5, B6, P1, V3, V6, A4_2] # -..ß哑
+‍-。󠄄。SS哑‌𐵿; ‍-..ss哑‌𐵿; [B1, B5, B6, C1, C2, P1, V3, V6, X4_2]; xn----tgn..xn--ss-k1ts75zb8ym; [B1, B5, B6, C1, C2, P1, V3, V6, A4_2]; -..xn--ss-h46c5711e; [B1, B5, B6, P1, V3, V6, A4_2] # -..ss哑
+‍-。󠄄。ss哑‌𐵿; ‍-..ss哑‌𐵿; [B1, B5, B6, C1, C2, P1, V3, V6, X4_2]; xn----tgn..xn--ss-k1ts75zb8ym; [B1, B5, B6, C1, C2, P1, V3, V6, A4_2]; -..xn--ss-h46c5711e; [B1, B5, B6, P1, V3, V6, A4_2] # -..ss哑
+‍-。󠄄。Ss哑‌𐵿; ‍-..ss哑‌𐵿; [B1, B5, B6, C1, C2, P1, V3, V6, X4_2]; xn----tgn..xn--ss-k1ts75zb8ym; [B1, B5, B6, C1, C2, P1, V3, V6, A4_2]; -..xn--ss-h46c5711e; [B1, B5, B6, P1, V3, V6, A4_2] # -..ss哑
+-..xn--ss-h46c5711e; -..ss哑𐵿; [B1, B5, B6, V3, V6, X4_2]; -..xn--ss-h46c5711e; [B1, B5, B6, V3, V6, A4_2]; ; # -..ss哑
+xn----tgn..xn--ss-k1ts75zb8ym; ‍-..ss哑‌𐵿; [B1, B5, B6, C1, C2, V3, V6, X4_2]; xn----tgn..xn--ss-k1ts75zb8ym; [B1, B5, B6, C1, C2, V3, V6, A4_2]; ; # -..ss哑
+xn----tgn..xn--zca670n5f0binyk; ‍-..ß哑‌𐵿; [B1, B5, B6, C1, C2, V3, V6, X4_2]; xn----tgn..xn--zca670n5f0binyk; [B1, B5, B6, C1, C2, V3, V6, A4_2]; ; # -..ß哑
+‍-︒󠄄。SS哑‌𐵿; ‍-︒.ss哑‌𐵿; [B1, B5, B6, C1, C2, P1, V6]; xn----tgnt341h.xn--ss-k1ts75zb8ym; ; xn----o89h.xn--ss-h46c5711e; [B1, B5, B6, P1, V3, V6] # -︒.ss哑
+‍-︒󠄄。ss哑‌𐵿; ‍-︒.ss哑‌𐵿; [B1, B5, B6, C1, C2, P1, V6]; xn----tgnt341h.xn--ss-k1ts75zb8ym; ; xn----o89h.xn--ss-h46c5711e; [B1, B5, B6, P1, V3, V6] # -︒.ss哑
+‍-︒󠄄。Ss哑‌𐵿; ‍-︒.ss哑‌𐵿; [B1, B5, B6, C1, C2, P1, V6]; xn----tgnt341h.xn--ss-k1ts75zb8ym; ; xn----o89h.xn--ss-h46c5711e; [B1, B5, B6, P1, V3, V6] # -︒.ss哑
+xn----o89h.xn--ss-h46c5711e; -︒.ss哑𐵿; [B1, B5, B6, V3, V6]; xn----o89h.xn--ss-h46c5711e; ; ; # -︒.ss哑
+xn----tgnt341h.xn--ss-k1ts75zb8ym; ‍-︒.ss哑‌𐵿; [B1, B5, B6, C1, C2, V6]; xn----tgnt341h.xn--ss-k1ts75zb8ym; ; ; # -︒.ss哑
+xn----tgnt341h.xn--zca670n5f0binyk; ‍-︒.ß哑‌𐵿; [B1, B5, B6, C1, C2, V6]; xn----tgnt341h.xn--zca670n5f0binyk; ; ; # -︒.ß哑
+︒.𑑂︯; ︒.𑑂︯; [P1, V5, V6]; xn--y86c.xn--s96cu30b; ; ; # ︒.𑑂︯
+︒.𑑂︯; ︒.𑑂︯; [P1, V5, V6]; xn--y86c.xn--s96cu30b; ; ; # ︒.𑑂︯
+。.𑑂︯; ..𑑂︯; [V5, X4_2]; ..xn--s96cu30b; [V5, A4_2]; ; # ..𑑂︯
+..xn--s96cu30b; ..𑑂︯; [V5, X4_2]; ..xn--s96cu30b; [V5, A4_2]; ; # ..𑑂︯
+xn--y86c.xn--s96cu30b; ︒.𑑂︯; [V5, V6]; xn--y86c.xn--s96cu30b; ; ; # ︒.𑑂︯
+꤬。‍; ꤬.‍; [C2, V5]; xn--zi9a.xn--1ug; ; xn--zi9a.; [V5] # ꤬.
+xn--zi9a.; ꤬.; [V5]; xn--zi9a.; ; ; # ꤬.
+xn--zi9a.xn--1ug; ꤬.‍; [C2, V5]; xn--zi9a.xn--1ug; ; ; # ꤬.
+‍󠸡。ﳗ; ‍󠸡.هج; [B1, C2, P1, V6]; xn--1ug80651l.xn--rgb7c; ; xn--d356e.xn--rgb7c; [B1, P1, V6] # .هج
+‍󠸡。هج; ‍󠸡.هج; [B1, C2, P1, V6]; xn--1ug80651l.xn--rgb7c; ; xn--d356e.xn--rgb7c; [B1, P1, V6] # .هج
+xn--d356e.xn--rgb7c; 󠸡.هج; [B1, V6]; xn--d356e.xn--rgb7c; ; ; # .هج
+xn--1ug80651l.xn--rgb7c; ‍󠸡.هج; [B1, C2, V6]; xn--1ug80651l.xn--rgb7c; ; ; # .هج
+-Ⴄ𝟢٣.𑍴ς; -Ⴄ0٣.𑍴ς; [B1, P1, V3, V5, V6]; xn---0-iyd216h.xn--3xa1220l; ; xn---0-iyd216h.xn--4xa9120l; # -Ⴄ0٣.𑍴ς
+-Ⴄ0٣.𑍴ς; ; [B1, P1, V3, V5, V6]; xn---0-iyd216h.xn--3xa1220l; ; xn---0-iyd216h.xn--4xa9120l; # -Ⴄ0٣.𑍴ς
+-ⴄ0٣.𑍴ς; ; [B1, V3, V5]; xn---0-iyd8660b.xn--3xa1220l; ; xn---0-iyd8660b.xn--4xa9120l; # -ⴄ0٣.𑍴ς
+-Ⴄ0٣.𑍴Σ; -Ⴄ0٣.𑍴σ; [B1, P1, V3, V5, V6]; xn---0-iyd216h.xn--4xa9120l; ; ; # -Ⴄ0٣.𑍴σ
+-ⴄ0٣.𑍴σ; ; [B1, V3, V5]; xn---0-iyd8660b.xn--4xa9120l; ; ; # -ⴄ0٣.𑍴σ
+xn---0-iyd8660b.xn--4xa9120l; -ⴄ0٣.𑍴σ; [B1, V3, V5]; xn---0-iyd8660b.xn--4xa9120l; ; ; # -ⴄ0٣.𑍴σ
+xn---0-iyd216h.xn--4xa9120l; -Ⴄ0٣.𑍴σ; [B1, V3, V5, V6]; xn---0-iyd216h.xn--4xa9120l; ; ; # -Ⴄ0٣.𑍴σ
+xn---0-iyd8660b.xn--3xa1220l; -ⴄ0٣.𑍴ς; [B1, V3, V5]; xn---0-iyd8660b.xn--3xa1220l; ; ; # -ⴄ0٣.𑍴ς
+xn---0-iyd216h.xn--3xa1220l; -Ⴄ0٣.𑍴ς; [B1, V3, V5, V6]; xn---0-iyd216h.xn--3xa1220l; ; ; # -Ⴄ0٣.𑍴ς
+-ⴄ𝟢٣.𑍴ς; -ⴄ0٣.𑍴ς; [B1, V3, V5]; xn---0-iyd8660b.xn--3xa1220l; ; xn---0-iyd8660b.xn--4xa9120l; # -ⴄ0٣.𑍴ς
+-Ⴄ𝟢٣.𑍴Σ; -Ⴄ0٣.𑍴σ; [B1, P1, V3, V5, V6]; xn---0-iyd216h.xn--4xa9120l; ; ; # -Ⴄ0٣.𑍴σ
+-ⴄ𝟢٣.𑍴σ; -ⴄ0٣.𑍴σ; [B1, V3, V5]; xn---0-iyd8660b.xn--4xa9120l; ; ; # -ⴄ0٣.𑍴σ
+󦈄。-; 󦈄.-; [P1, V3, V6]; xn--xm38e.-; ; ; # .-
+xn--xm38e.-; 󦈄.-; [V3, V6]; xn--xm38e.-; ; ; # .-
+⋠𐋮.򶈮༘ß≯; ⋠𐋮.򶈮༘ß≯; [P1, V6]; xn--pgh4639f.xn--zca593eo6oc013y; ; xn--pgh4639f.xn--ss-ifj426nle504a; # ⋠𐋮.༘ß≯
+⋠𐋮.򶈮༘ß≯; ⋠𐋮.򶈮༘ß≯; [P1, V6]; xn--pgh4639f.xn--zca593eo6oc013y; ; xn--pgh4639f.xn--ss-ifj426nle504a; # ⋠𐋮.༘ß≯
+⋠𐋮.򶈮༘ß≯; ; [P1, V6]; xn--pgh4639f.xn--zca593eo6oc013y; ; xn--pgh4639f.xn--ss-ifj426nle504a; # ⋠𐋮.༘ß≯
+⋠𐋮.򶈮༘ß≯; ⋠𐋮.򶈮༘ß≯; [P1, V6]; xn--pgh4639f.xn--zca593eo6oc013y; ; xn--pgh4639f.xn--ss-ifj426nle504a; # ⋠𐋮.༘ß≯
+⋠𐋮.򶈮༘SS≯; ⋠𐋮.򶈮༘ss≯; [P1, V6]; xn--pgh4639f.xn--ss-ifj426nle504a; ; ; # ⋠𐋮.༘ss≯
+⋠𐋮.򶈮༘SS≯; ⋠𐋮.򶈮༘ss≯; [P1, V6]; xn--pgh4639f.xn--ss-ifj426nle504a; ; ; # ⋠𐋮.༘ss≯
+⋠𐋮.򶈮༘ss≯; ; [P1, V6]; xn--pgh4639f.xn--ss-ifj426nle504a; ; ; # ⋠𐋮.༘ss≯
+⋠𐋮.򶈮༘ss≯; ⋠𐋮.򶈮༘ss≯; [P1, V6]; xn--pgh4639f.xn--ss-ifj426nle504a; ; ; # ⋠𐋮.༘ss≯
+⋠𐋮.򶈮༘Ss≯; ⋠𐋮.򶈮༘ss≯; [P1, V6]; xn--pgh4639f.xn--ss-ifj426nle504a; ; ; # ⋠𐋮.༘ss≯
+⋠𐋮.򶈮༘Ss≯; ⋠𐋮.򶈮༘ss≯; [P1, V6]; xn--pgh4639f.xn--ss-ifj426nle504a; ; ; # ⋠𐋮.༘ss≯
+xn--pgh4639f.xn--ss-ifj426nle504a; ⋠𐋮.򶈮༘ss≯; [V6]; xn--pgh4639f.xn--ss-ifj426nle504a; ; ; # ⋠𐋮.༘ss≯
+xn--pgh4639f.xn--zca593eo6oc013y; ⋠𐋮.򶈮༘ß≯; [V6]; xn--pgh4639f.xn--zca593eo6oc013y; ; ; # ⋠𐋮.༘ß≯
+⋠𐋮.򶈮༘SS≯; ⋠𐋮.򶈮༘ss≯; [P1, V6]; xn--pgh4639f.xn--ss-ifj426nle504a; ; ; # ⋠𐋮.༘ss≯
+⋠𐋮.򶈮༘SS≯; ⋠𐋮.򶈮༘ss≯; [P1, V6]; xn--pgh4639f.xn--ss-ifj426nle504a; ; ; # ⋠𐋮.༘ss≯
+⋠𐋮.򶈮༘ss≯; ⋠𐋮.򶈮༘ss≯; [P1, V6]; xn--pgh4639f.xn--ss-ifj426nle504a; ; ; # ⋠𐋮.༘ss≯
+⋠𐋮.򶈮༘ss≯; ⋠𐋮.򶈮༘ss≯; [P1, V6]; xn--pgh4639f.xn--ss-ifj426nle504a; ; ; # ⋠𐋮.༘ss≯
+⋠𐋮.򶈮༘Ss≯; ⋠𐋮.򶈮༘ss≯; [P1, V6]; xn--pgh4639f.xn--ss-ifj426nle504a; ; ; # ⋠𐋮.༘ss≯
+⋠𐋮.򶈮༘Ss≯; ⋠𐋮.򶈮༘ss≯; [P1, V6]; xn--pgh4639f.xn--ss-ifj426nle504a; ; ; # ⋠𐋮.༘ss≯
+1𐋸٤。󠢮ﮤ񷝊; 1𐋸٤.󠢮ۀ񷝊; [B1, P1, V6]; xn--1-hqc3905q.xn--zkb83268gqee4a; ; ; # 1𐋸٤.ۀ
+1𐋸٤。󠢮ۀ񷝊; 1𐋸٤.󠢮ۀ񷝊; [B1, P1, V6]; xn--1-hqc3905q.xn--zkb83268gqee4a; ; ; # 1𐋸٤.ۀ
+1𐋸٤。󠢮ۀ񷝊; 1𐋸٤.󠢮ۀ񷝊; [B1, P1, V6]; xn--1-hqc3905q.xn--zkb83268gqee4a; ; ; # 1𐋸٤.ۀ
+xn--1-hqc3905q.xn--zkb83268gqee4a; 1𐋸٤.󠢮ۀ񷝊; [B1, V6]; xn--1-hqc3905q.xn--zkb83268gqee4a; ; ; # 1𐋸٤.ۀ
+儭-。𐹴Ⴢ񥳠‌; 儭-.𐹴Ⴢ񥳠‌; [B1, B6, C1, P1, V3, V6]; xn----gz7a.xn--6nd249ejl4pusr7b; ; xn----gz7a.xn--6nd5001kyw98a; [B1, B6, P1, V3, V6] # 儭-.𐹴Ⴢ
+儭-。𐹴Ⴢ񥳠‌; 儭-.𐹴Ⴢ񥳠‌; [B1, B6, C1, P1, V3, V6]; xn----gz7a.xn--6nd249ejl4pusr7b; ; xn----gz7a.xn--6nd5001kyw98a; [B1, B6, P1, V3, V6] # 儭-.𐹴Ⴢ
+儭-。𐹴ⴢ񥳠‌; 儭-.𐹴ⴢ񥳠‌; [B1, B6, C1, P1, V3, V6]; xn----gz7a.xn--0ug472cfq0pus98b; ; xn----gz7a.xn--qlj9223eywx0b; [B1, B6, P1, V3, V6] # 儭-.𐹴ⴢ
+xn----gz7a.xn--qlj9223eywx0b; 儭-.𐹴ⴢ񥳠; [B1, B6, V3, V6]; xn----gz7a.xn--qlj9223eywx0b; ; ; # 儭-.𐹴ⴢ
+xn----gz7a.xn--0ug472cfq0pus98b; 儭-.𐹴ⴢ񥳠‌; [B1, B6, C1, V3, V6]; xn----gz7a.xn--0ug472cfq0pus98b; ; ; # 儭-.𐹴ⴢ
+xn----gz7a.xn--6nd5001kyw98a; 儭-.𐹴Ⴢ񥳠; [B1, B6, V3, V6]; xn----gz7a.xn--6nd5001kyw98a; ; ; # 儭-.𐹴Ⴢ
+xn----gz7a.xn--6nd249ejl4pusr7b; 儭-.𐹴Ⴢ񥳠‌; [B1, B6, C1, V3, V6]; xn----gz7a.xn--6nd249ejl4pusr7b; ; ; # 儭-.𐹴Ⴢ
+儭-。𐹴ⴢ񥳠‌; 儭-.𐹴ⴢ񥳠‌; [B1, B6, C1, P1, V3, V6]; xn----gz7a.xn--0ug472cfq0pus98b; ; xn----gz7a.xn--qlj9223eywx0b; [B1, B6, P1, V3, V6] # 儭-.𐹴ⴢ
+𝟺𐋷ڹ.𞤭򿍡; 4𐋷ڹ.𞤭򿍡; [B1, B2, B3, P1, V6]; xn--4-cvc5384q.xn--le6hi7322b; ; ; # 4𐋷ڹ.𞤭
+4𐋷ڹ.𞤭򿍡; ; [B1, B2, B3, P1, V6]; xn--4-cvc5384q.xn--le6hi7322b; ; ; # 4𐋷ڹ.𞤭
+4𐋷ڹ.𞤋򿍡; 4𐋷ڹ.𞤭򿍡; [B1, B2, B3, P1, V6]; xn--4-cvc5384q.xn--le6hi7322b; ; ; # 4𐋷ڹ.𞤭
+xn--4-cvc5384q.xn--le6hi7322b; 4𐋷ڹ.𞤭򿍡; [B1, B2, B3, V6]; xn--4-cvc5384q.xn--le6hi7322b; ; ; # 4𐋷ڹ.𞤭
+𝟺𐋷ڹ.𞤋򿍡; 4𐋷ڹ.𞤭򿍡; [B1, B2, B3, P1, V6]; xn--4-cvc5384q.xn--le6hi7322b; ; ; # 4𐋷ڹ.𞤭
+≯-ꡋ𑲣.⒈𐹭; ; [B1, P1, V6]; xn----ogox061d5i8d.xn--tsh0666f; ; ; # ≯-ꡋ𑲣.⒈𐹭
+≯-ꡋ𑲣.⒈𐹭; ≯-ꡋ𑲣.⒈𐹭; [B1, P1, V6]; xn----ogox061d5i8d.xn--tsh0666f; ; ; # ≯-ꡋ𑲣.⒈𐹭
+≯-ꡋ𑲣.1.𐹭; ; [B1, P1, V6]; xn----ogox061d5i8d.1.xn--lo0d; ; ; # ≯-ꡋ𑲣.1.𐹭
+≯-ꡋ𑲣.1.𐹭; ≯-ꡋ𑲣.1.𐹭; [B1, P1, V6]; xn----ogox061d5i8d.1.xn--lo0d; ; ; # ≯-ꡋ𑲣.1.𐹭
+xn----ogox061d5i8d.1.xn--lo0d; ≯-ꡋ𑲣.1.𐹭; [B1, V6]; xn----ogox061d5i8d.1.xn--lo0d; ; ; # ≯-ꡋ𑲣.1.𐹭
+xn----ogox061d5i8d.xn--tsh0666f; ≯-ꡋ𑲣.⒈𐹭; [B1, V6]; xn----ogox061d5i8d.xn--tsh0666f; ; ; # ≯-ꡋ𑲣.⒈𐹭
+̰.󰜱蚀; ̰.󰜱蚀; [P1, V5, V6]; xn--xta.xn--e91aw9417e; ; ; # ̰.蚀
+̰.󰜱蚀; ; [P1, V5, V6]; xn--xta.xn--e91aw9417e; ; ; # ̰.蚀
+xn--xta.xn--e91aw9417e; ̰.󰜱蚀; [V5, V6]; xn--xta.xn--e91aw9417e; ; ; # ̰.蚀
+יּႸ.𞡼𑇀ß⃗; יּႸ.𞡼𑇀ß⃗; [B2, B3, P1, V6]; xn--kdb1d867b.xn--zca284nhg9nrrxg; ; xn--kdb1d867b.xn--ss-yju5690ken9h; # יּႸ.𞡼𑇀ß⃗
+יּႸ.𞡼𑇀ß⃗; ; [B2, B3, P1, V6]; xn--kdb1d867b.xn--zca284nhg9nrrxg; ; xn--kdb1d867b.xn--ss-yju5690ken9h; # יּႸ.𞡼𑇀ß⃗
+יּⴘ.𞡼𑇀ß⃗; ; [B2, B3]; xn--kdb1d278n.xn--zca284nhg9nrrxg; ; xn--kdb1d278n.xn--ss-yju5690ken9h; # יּⴘ.𞡼𑇀ß⃗
+יּႸ.𞡼𑇀SS⃗; יּႸ.𞡼𑇀ss⃗; [B2, B3, P1, V6]; xn--kdb1d867b.xn--ss-yju5690ken9h; ; ; # יּႸ.𞡼𑇀ss⃗
+יּⴘ.𞡼𑇀ss⃗; ; [B2, B3]; xn--kdb1d278n.xn--ss-yju5690ken9h; ; ; # יּⴘ.𞡼𑇀ss⃗
+xn--kdb1d278n.xn--ss-yju5690ken9h; יּⴘ.𞡼𑇀ss⃗; [B2, B3]; xn--kdb1d278n.xn--ss-yju5690ken9h; ; ; # יּⴘ.𞡼𑇀ss⃗
+xn--kdb1d867b.xn--ss-yju5690ken9h; יּႸ.𞡼𑇀ss⃗; [B2, B3, V6]; xn--kdb1d867b.xn--ss-yju5690ken9h; ; ; # יּႸ.𞡼𑇀ss⃗
+xn--kdb1d278n.xn--zca284nhg9nrrxg; יּⴘ.𞡼𑇀ß⃗; [B2, B3]; xn--kdb1d278n.xn--zca284nhg9nrrxg; ; ; # יּⴘ.𞡼𑇀ß⃗
+xn--kdb1d867b.xn--zca284nhg9nrrxg; יּႸ.𞡼𑇀ß⃗; [B2, B3, V6]; xn--kdb1d867b.xn--zca284nhg9nrrxg; ; ; # יּႸ.𞡼𑇀ß⃗
+יּⴘ.𞡼𑇀ß⃗; יּⴘ.𞡼𑇀ß⃗; [B2, B3]; xn--kdb1d278n.xn--zca284nhg9nrrxg; ; xn--kdb1d278n.xn--ss-yju5690ken9h; # יּⴘ.𞡼𑇀ß⃗
+יּႸ.𞡼𑇀SS⃗; יּႸ.𞡼𑇀ss⃗; [B2, B3, P1, V6]; xn--kdb1d867b.xn--ss-yju5690ken9h; ; ; # יּႸ.𞡼𑇀ss⃗
+יּⴘ.𞡼𑇀ss⃗; יּⴘ.𞡼𑇀ss⃗; [B2, B3]; xn--kdb1d278n.xn--ss-yju5690ken9h; ; ; # יּⴘ.𞡼𑇀ss⃗
+יּႸ.𞡼𑇀ss⃗; ; [B2, B3, P1, V6]; xn--kdb1d867b.xn--ss-yju5690ken9h; ; ; # יּႸ.𞡼𑇀ss⃗
+יּႸ.𞡼𑇀ss⃗; יּႸ.𞡼𑇀ss⃗; [B2, B3, P1, V6]; xn--kdb1d867b.xn--ss-yju5690ken9h; ; ; # יּႸ.𞡼𑇀ss⃗
+ᮣ𐹰򁱓。凬; ᮣ𐹰򁱓.凬; [B1, P1, V5, V6]; xn--rxfz314ilg20c.xn--t9q; ; ; # ᮣ𐹰.凬
+ᮣ𐹰򁱓。凬; ᮣ𐹰򁱓.凬; [B1, P1, V5, V6]; xn--rxfz314ilg20c.xn--t9q; ; ; # ᮣ𐹰.凬
+xn--rxfz314ilg20c.xn--t9q; ᮣ𐹰򁱓.凬; [B1, V5, V6]; xn--rxfz314ilg20c.xn--t9q; ; ; # ᮣ𐹰.凬
+🢟🄈‍ꡎ。྄; 🢟🄈‍ꡎ.྄; [C2, P1, V5, V6]; xn--1ug4874cfd0kbmg.xn--3ed; ; xn--nc9aq743ds0e.xn--3ed; [P1, V5, V6] # 🢟🄈ꡎ.྄
+🢟7,‍ꡎ。྄; 🢟7,‍ꡎ.྄; [C2, P1, V5, V6]; xn--7,-n1t0654eqo3o.xn--3ed; ; xn--7,-gh9hg322i.xn--3ed; [P1, V5, V6] # 🢟7,ꡎ.྄
+xn--7,-gh9hg322i.xn--3ed; 🢟7,ꡎ.྄; [P1, V5, V6]; xn--7,-gh9hg322i.xn--3ed; ; ; # 🢟7,ꡎ.྄
+xn--7,-n1t0654eqo3o.xn--3ed; 🢟7,‍ꡎ.྄; [C2, P1, V5, V6]; xn--7,-n1t0654eqo3o.xn--3ed; ; ; # 🢟7,ꡎ.྄
+xn--nc9aq743ds0e.xn--3ed; 🢟🄈ꡎ.྄; [V5, V6]; xn--nc9aq743ds0e.xn--3ed; ; ; # 🢟🄈ꡎ.྄
+xn--1ug4874cfd0kbmg.xn--3ed; 🢟🄈‍ꡎ.྄; [C2, V5, V6]; xn--1ug4874cfd0kbmg.xn--3ed; ; ; # 🢟🄈ꡎ.྄
+ꡔ。္ᢇ; ꡔ.္ᢇ; [V5]; xn--tc9a.xn--9jd663b; ; ; # ꡔ.္ᢇ
+xn--tc9a.xn--9jd663b; ꡔ.္ᢇ; [V5]; xn--tc9a.xn--9jd663b; ; ; # ꡔ.္ᢇ
+⃫≮.𝨖; ; [P1, V5, V6]; xn--e1g71d.xn--772h; ; ; # ⃫≮.𝨖
+⃫≮.𝨖; ⃫≮.𝨖; [P1, V5, V6]; xn--e1g71d.xn--772h; ; ; # ⃫≮.𝨖
+xn--e1g71d.xn--772h; ⃫≮.𝨖; [V5, V6]; xn--e1g71d.xn--772h; ; ; # ⃫≮.𝨖
+Ⴢ≯褦.ᠪߪႾݧ; Ⴢ≯褦.ᠪߪႾݧ; [B5, B6, P1, V6]; xn--6nd461g478e.xn--rpb5x49td2h; ; ; # Ⴢ≯褦.ᠪߪႾݧ
+Ⴢ≯褦.ᠪߪႾݧ; Ⴢ≯褦.ᠪߪႾݧ; [B5, B6, P1, V6]; xn--6nd461g478e.xn--rpb5x49td2h; ; ; # Ⴢ≯褦.ᠪߪႾݧ
+Ⴢ≯褦.ᠪߪႾݧ; ; [B5, B6, P1, V6]; xn--6nd461g478e.xn--rpb5x49td2h; ; ; # Ⴢ≯褦.ᠪߪႾݧ
+Ⴢ≯褦.ᠪߪႾݧ; Ⴢ≯褦.ᠪߪႾݧ; [B5, B6, P1, V6]; xn--6nd461g478e.xn--rpb5x49td2h; ; ; # Ⴢ≯褦.ᠪߪႾݧ
+ⴢ≯褦.ᠪߪⴞݧ; ⴢ≯褦.ᠪߪⴞݧ; [B5, B6, P1, V6]; xn--hdh433bev8e.xn--rpb5x392bcyt; ; ; # ⴢ≯褦.ᠪߪⴞݧ
+ⴢ≯褦.ᠪߪⴞݧ; ; [B5, B6, P1, V6]; xn--hdh433bev8e.xn--rpb5x392bcyt; ; ; # ⴢ≯褦.ᠪߪⴞݧ
+Ⴢ≯褦.ᠪߪⴞݧ; ; [B5, B6, P1, V6]; xn--6nd461g478e.xn--rpb5x392bcyt; ; ; # Ⴢ≯褦.ᠪߪⴞݧ
+Ⴢ≯褦.ᠪߪⴞݧ; Ⴢ≯褦.ᠪߪⴞݧ; [B5, B6, P1, V6]; xn--6nd461g478e.xn--rpb5x392bcyt; ; ; # Ⴢ≯褦.ᠪߪⴞݧ
+xn--6nd461g478e.xn--rpb5x392bcyt; Ⴢ≯褦.ᠪߪⴞݧ; [B5, B6, V6]; xn--6nd461g478e.xn--rpb5x392bcyt; ; ; # Ⴢ≯褦.ᠪߪⴞݧ
+xn--hdh433bev8e.xn--rpb5x392bcyt; ⴢ≯褦.ᠪߪⴞݧ; [B5, B6, V6]; xn--hdh433bev8e.xn--rpb5x392bcyt; ; ; # ⴢ≯褦.ᠪߪⴞݧ
+xn--6nd461g478e.xn--rpb5x49td2h; Ⴢ≯褦.ᠪߪႾݧ; [B5, B6, V6]; xn--6nd461g478e.xn--rpb5x49td2h; ; ; # Ⴢ≯褦.ᠪߪႾݧ
+ⴢ≯褦.ᠪߪⴞݧ; ⴢ≯褦.ᠪߪⴞݧ; [B5, B6, P1, V6]; xn--hdh433bev8e.xn--rpb5x392bcyt; ; ; # ⴢ≯褦.ᠪߪⴞݧ
+ⴢ≯褦.ᠪߪⴞݧ; ⴢ≯褦.ᠪߪⴞݧ; [B5, B6, P1, V6]; xn--hdh433bev8e.xn--rpb5x392bcyt; ; ; # ⴢ≯褦.ᠪߪⴞݧ
+Ⴢ≯褦.ᠪߪⴞݧ; Ⴢ≯褦.ᠪߪⴞݧ; [B5, B6, P1, V6]; xn--6nd461g478e.xn--rpb5x392bcyt; ; ; # Ⴢ≯褦.ᠪߪⴞݧ
+Ⴢ≯褦.ᠪߪⴞݧ; Ⴢ≯褦.ᠪߪⴞݧ; [B5, B6, P1, V6]; xn--6nd461g478e.xn--rpb5x392bcyt; ; ; # Ⴢ≯褦.ᠪߪⴞݧ
+򊉆󠆒‌꥓。𞤙ٻꡘ; 򊉆‌꥓.𞤻ٻꡘ; [B2, B3, C1, P1, V6]; xn--0ug8815chtz0e.xn--0ib8893fegvj; ; xn--3j9al6189a.xn--0ib8893fegvj; [B2, B3, P1, V6] # ꥓.𞤻ٻꡘ
+򊉆󠆒‌꥓。𞤻ٻꡘ; 򊉆‌꥓.𞤻ٻꡘ; [B2, B3, C1, P1, V6]; xn--0ug8815chtz0e.xn--0ib8893fegvj; ; xn--3j9al6189a.xn--0ib8893fegvj; [B2, B3, P1, V6] # ꥓.𞤻ٻꡘ
+xn--3j9al6189a.xn--0ib8893fegvj; 򊉆꥓.𞤻ٻꡘ; [B2, B3, V6]; xn--3j9al6189a.xn--0ib8893fegvj; ; ; # ꥓.𞤻ٻꡘ
+xn--0ug8815chtz0e.xn--0ib8893fegvj; 򊉆‌꥓.𞤻ٻꡘ; [B2, B3, C1, V6]; xn--0ug8815chtz0e.xn--0ib8893fegvj; ; ; # ꥓.𞤻ٻꡘ
+‌.≯; ; [C1, P1, V6]; xn--0ug.xn--hdh; ; .xn--hdh; [P1, V6, A4_2] # .≯
+‌.≯; ‌.≯; [C1, P1, V6]; xn--0ug.xn--hdh; ; .xn--hdh; [P1, V6, A4_2] # .≯
+.xn--hdh; .≯; [V6, X4_2]; .xn--hdh; [V6, A4_2]; ; # .≯
+xn--0ug.xn--hdh; ‌.≯; [C1, V6]; xn--0ug.xn--hdh; ; ; # .≯
+𰅧񣩠-.꯭-悜; 𰅧񣩠-.꯭-悜; [P1, V3, V5, V6]; xn----7m53aj640l.xn----8f4br83t; ; ; # 𰅧-.꯭-悜
+𰅧񣩠-.꯭-悜; ; [P1, V3, V5, V6]; xn----7m53aj640l.xn----8f4br83t; ; ; # 𰅧-.꯭-悜
+xn----7m53aj640l.xn----8f4br83t; 𰅧񣩠-.꯭-悜; [V3, V5, V6]; xn----7m53aj640l.xn----8f4br83t; ; ; # 𰅧-.꯭-悜
+ᡉ𶓧⬞ᢜ.-‍𞣑‮; ; [C2, P1, V3, V6]; xn--87e0ol04cdl39e.xn----ugn5e3763s; ; xn--87e0ol04cdl39e.xn----qinu247r; [P1, V3, V6] # ᡉ⬞ᢜ.-𞣑
+xn--87e0ol04cdl39e.xn----qinu247r; ᡉ𶓧⬞ᢜ.-𞣑‮; [V3, V6]; xn--87e0ol04cdl39e.xn----qinu247r; ; ; # ᡉ⬞ᢜ.-𞣑
+xn--87e0ol04cdl39e.xn----ugn5e3763s; ᡉ𶓧⬞ᢜ.-‍𞣑‮; [C2, V3, V6]; xn--87e0ol04cdl39e.xn----ugn5e3763s; ; ; # ᡉ⬞ᢜ.-𞣑
+⒐‌衃Ⴝ.ڂႴ; ; [B1, B2, B3, C1, P1, V6]; xn--1nd159ecmd785k.xn--7ib433c; ; xn--1nd362hy16e.xn--7ib433c; [B1, B2, B3, P1, V6] # ⒐衃Ⴝ.ڂႴ
+9.‌衃Ⴝ.ڂႴ; ; [B1, B2, B3, C1, P1, V6]; 9.xn--1nd159e1y2f.xn--7ib433c; ; 9.xn--1nd9032d.xn--7ib433c; [B1, B2, B3, P1, V6] # 9.衃Ⴝ.ڂႴ
+9.‌衃ⴝ.ڂⴔ; ; [B1, B2, B3, C1]; 9.xn--0ug862cbm5e.xn--7ib268q; ; 9.xn--llj1920a.xn--7ib268q; [B1, B2, B3] # 9.衃ⴝ.ڂⴔ
+9.‌衃Ⴝ.ڂⴔ; ; [B1, B2, B3, C1, P1, V6]; 9.xn--1nd159e1y2f.xn--7ib268q; ; 9.xn--1nd9032d.xn--7ib268q; [B1, B2, B3, P1, V6] # 9.衃Ⴝ.ڂⴔ
+9.xn--1nd9032d.xn--7ib268q; 9.衃Ⴝ.ڂⴔ; [B1, B2, B3, V6]; 9.xn--1nd9032d.xn--7ib268q; ; ; # 9.衃Ⴝ.ڂⴔ
+9.xn--1nd159e1y2f.xn--7ib268q; 9.‌衃Ⴝ.ڂⴔ; [B1, B2, B3, C1, V6]; 9.xn--1nd159e1y2f.xn--7ib268q; ; ; # 9.衃Ⴝ.ڂⴔ
+9.xn--llj1920a.xn--7ib268q; 9.衃ⴝ.ڂⴔ; [B1, B2, B3]; 9.xn--llj1920a.xn--7ib268q; ; ; # 9.衃ⴝ.ڂⴔ
+9.xn--0ug862cbm5e.xn--7ib268q; 9.‌衃ⴝ.ڂⴔ; [B1, B2, B3, C1]; 9.xn--0ug862cbm5e.xn--7ib268q; ; ; # 9.衃ⴝ.ڂⴔ
+9.xn--1nd9032d.xn--7ib433c; 9.衃Ⴝ.ڂႴ; [B1, B2, B3, V6]; 9.xn--1nd9032d.xn--7ib433c; ; ; # 9.衃Ⴝ.ڂႴ
+9.xn--1nd159e1y2f.xn--7ib433c; 9.‌衃Ⴝ.ڂႴ; [B1, B2, B3, C1, V6]; 9.xn--1nd159e1y2f.xn--7ib433c; ; ; # 9.衃Ⴝ.ڂႴ
+⒐‌衃ⴝ.ڂⴔ; ; [B1, B2, B3, C1, P1, V6]; xn--0ugx0px1izu2h.xn--7ib268q; ; xn--1shy52abz3f.xn--7ib268q; [B1, B2, B3, P1, V6] # ⒐衃ⴝ.ڂⴔ
+⒐‌衃Ⴝ.ڂⴔ; ; [B1, B2, B3, C1, P1, V6]; xn--1nd159ecmd785k.xn--7ib268q; ; xn--1nd362hy16e.xn--7ib268q; [B1, B2, B3, P1, V6] # ⒐衃Ⴝ.ڂⴔ
+xn--1nd362hy16e.xn--7ib268q; ⒐衃Ⴝ.ڂⴔ; [B1, B2, B3, V6]; xn--1nd362hy16e.xn--7ib268q; ; ; # ⒐衃Ⴝ.ڂⴔ
+xn--1nd159ecmd785k.xn--7ib268q; ⒐‌衃Ⴝ.ڂⴔ; [B1, B2, B3, C1, V6]; xn--1nd159ecmd785k.xn--7ib268q; ; ; # ⒐衃Ⴝ.ڂⴔ
+xn--1shy52abz3f.xn--7ib268q; ⒐衃ⴝ.ڂⴔ; [B1, B2, B3, V6]; xn--1shy52abz3f.xn--7ib268q; ; ; # ⒐衃ⴝ.ڂⴔ
+xn--0ugx0px1izu2h.xn--7ib268q; ⒐‌衃ⴝ.ڂⴔ; [B1, B2, B3, C1, V6]; xn--0ugx0px1izu2h.xn--7ib268q; ; ; # ⒐衃ⴝ.ڂⴔ
+xn--1nd362hy16e.xn--7ib433c; ⒐衃Ⴝ.ڂႴ; [B1, B2, B3, V6]; xn--1nd362hy16e.xn--7ib433c; ; ; # ⒐衃Ⴝ.ڂႴ
+xn--1nd159ecmd785k.xn--7ib433c; ⒐‌衃Ⴝ.ڂႴ; [B1, B2, B3, C1, V6]; xn--1nd159ecmd785k.xn--7ib433c; ; ; # ⒐衃Ⴝ.ڂႴ
+ߡ‌。--⸬; ߡ‌.--⸬; [B1, B3, C1, V3]; xn--8sb884j.xn-----iw2a; ; xn--8sb.xn-----iw2a; [B1, V3] # ߡ.--⸬
+xn--8sb.xn-----iw2a; ߡ.--⸬; [B1, V3]; xn--8sb.xn-----iw2a; ; ; # ߡ.--⸬
+xn--8sb884j.xn-----iw2a; ߡ‌.--⸬; [B1, B3, C1, V3]; xn--8sb884j.xn-----iw2a; ; ; # ߡ.--⸬
+𞥓.ܘ; 𞥓.ܘ; ; xn--of6h.xn--inb; ; ; # 𞥓.ܘ
+𞥓.ܘ; ; ; xn--of6h.xn--inb; ; ; # 𞥓.ܘ
+xn--of6h.xn--inb; 𞥓.ܘ; ; xn--of6h.xn--inb; ; ; # 𞥓.ܘ
+󠄽-.-්; -.-්; [V3]; -.xn----ptf; ; ; # -.-්
+󠄽-.-්; -.-්; [V3]; -.xn----ptf; ; ; # -.-්
+-.xn----ptf; -.-්; [V3]; -.xn----ptf; ; ; # -.-්
+󠇝ݛ-.ᤧ; ݛ-.ᤧ; [B1, B3, B6, V3, V5]; xn----k4c.xn--lff; ; ; # ݛ-.ᤧ
+xn----k4c.xn--lff; ݛ-.ᤧ; [B1, B3, B6, V3, V5]; xn----k4c.xn--lff; ; ; # ݛ-.ᤧ
+𞤴󠆹⦉𐹺.꠆⒌󘤸; 𞤴⦉𐹺.꠆⒌󘤸; [B1, P1, V5, V6]; xn--fuix729epewf.xn--xsh5029b6e77i; ; ; # 𞤴⦉𐹺.꠆⒌
+𞤴󠆹⦉𐹺.꠆5.󘤸; 𞤴⦉𐹺.꠆5.󘤸; [B1, P1, V5, V6]; xn--fuix729epewf.xn--5-w93e.xn--7b83e; ; ; # 𞤴⦉𐹺.꠆5.
+𞤒󠆹⦉𐹺.꠆5.󘤸; 𞤴⦉𐹺.꠆5.󘤸; [B1, P1, V5, V6]; xn--fuix729epewf.xn--5-w93e.xn--7b83e; ; ; # 𞤴⦉𐹺.꠆5.
+xn--fuix729epewf.xn--5-w93e.xn--7b83e; 𞤴⦉𐹺.꠆5.󘤸; [B1, V5, V6]; xn--fuix729epewf.xn--5-w93e.xn--7b83e; ; ; # 𞤴⦉𐹺.꠆5.
+𞤒󠆹⦉𐹺.꠆⒌󘤸; 𞤴⦉𐹺.꠆⒌󘤸; [B1, P1, V5, V6]; xn--fuix729epewf.xn--xsh5029b6e77i; ; ; # 𞤴⦉𐹺.꠆⒌
+xn--fuix729epewf.xn--xsh5029b6e77i; 𞤴⦉𐹺.꠆⒌󘤸; [B1, V5, V6]; xn--fuix729epewf.xn--xsh5029b6e77i; ; ; # 𞤴⦉𐹺.꠆⒌
+󠄸₀。𑖿‌𐦂‍; 0.𑖿‌𐦂‍; [B1, C2, V5]; 0.xn--0ugc8040p9hk; ; 0.xn--mn9cz2s; [B1, V5] # 0.𑖿𐦂
+󠄸0。𑖿‌𐦂‍; 0.𑖿‌𐦂‍; [B1, C2, V5]; 0.xn--0ugc8040p9hk; ; 0.xn--mn9cz2s; [B1, V5] # 0.𑖿𐦂
+0.xn--mn9cz2s; 0.𑖿𐦂; [B1, V5]; 0.xn--mn9cz2s; ; ; # 0.𑖿𐦂
+0.xn--0ugc8040p9hk; 0.𑖿‌𐦂‍; [B1, C2, V5]; 0.xn--0ugc8040p9hk; ; ; # 0.𑖿𐦂
+Ⴚ𐋸󠄄。𝟝ퟶ်; Ⴚ𐋸.5ퟶ်; [P1, V6]; xn--ynd2415j.xn--5-dug9054m; ; ; # Ⴚ𐋸.5ퟶ်
+Ⴚ𐋸󠄄。5ퟶ်; Ⴚ𐋸.5ퟶ်; [P1, V6]; xn--ynd2415j.xn--5-dug9054m; ; ; # Ⴚ𐋸.5ퟶ်
+ⴚ𐋸󠄄。5ퟶ်; ⴚ𐋸.5ퟶ်; ; xn--ilj2659d.xn--5-dug9054m; ; ; # ⴚ𐋸.5ퟶ်
+xn--ilj2659d.xn--5-dug9054m; ⴚ𐋸.5ퟶ်; ; xn--ilj2659d.xn--5-dug9054m; ; ; # ⴚ𐋸.5ퟶ်
+ⴚ𐋸.5ퟶ်; ; ; xn--ilj2659d.xn--5-dug9054m; ; ; # ⴚ𐋸.5ퟶ်
+Ⴚ𐋸.5ퟶ်; ; [P1, V6]; xn--ynd2415j.xn--5-dug9054m; ; ; # Ⴚ𐋸.5ퟶ်
+xn--ynd2415j.xn--5-dug9054m; Ⴚ𐋸.5ퟶ်; [V6]; xn--ynd2415j.xn--5-dug9054m; ; ; # Ⴚ𐋸.5ퟶ်
+ⴚ𐋸󠄄。𝟝ퟶ်; ⴚ𐋸.5ퟶ်; ; xn--ilj2659d.xn--5-dug9054m; ; ; # ⴚ𐋸.5ퟶ်
+‍-ᠹ﹪.ᷡᤢ; ; [C2, P1, V5, V6]; xn----c6j614b1z4v.xn--gff52t; ; xn----c6jx047j.xn--gff52t; [P1, V3, V5, V6] # -ᠹ﹪.ᷡᤢ
+‍-ᠹ%.ᷡᤢ; ; [C2, P1, V5, V6]; xn---%-u4oy48b.xn--gff52t; ; xn---%-u4o.xn--gff52t; [P1, V3, V5, V6] # -ᠹ%.ᷡᤢ
+xn---%-u4o.xn--gff52t; -ᠹ%.ᷡᤢ; [P1, V3, V5, V6]; xn---%-u4o.xn--gff52t; ; ; # -ᠹ%.ᷡᤢ
+xn---%-u4oy48b.xn--gff52t; ‍-ᠹ%.ᷡᤢ; [C2, P1, V5, V6]; xn---%-u4oy48b.xn--gff52t; ; ; # -ᠹ%.ᷡᤢ
+xn----c6jx047j.xn--gff52t; -ᠹ﹪.ᷡᤢ; [V3, V5, V6]; xn----c6jx047j.xn--gff52t; ; ; # -ᠹ﹪.ᷡᤢ
+xn----c6j614b1z4v.xn--gff52t; ‍-ᠹ﹪.ᷡᤢ; [C2, V5, V6]; xn----c6j614b1z4v.xn--gff52t; ; ; # -ᠹ﹪.ᷡᤢ
+≠.ᠿ; ; [P1, V6]; xn--1ch.xn--y7e; ; ; # ≠.ᠿ
+≠.ᠿ; ≠.ᠿ; [P1, V6]; xn--1ch.xn--y7e; ; ; # ≠.ᠿ
+xn--1ch.xn--y7e; ≠.ᠿ; [V6]; xn--1ch.xn--y7e; ; ; # ≠.ᠿ
+ܣ֣。㌪; ܣ֣.ハイツ; ; xn--ucb18e.xn--eck4c5a; ; ; # ܣ֣.ハイツ
+ܣ֣。ハイツ; ܣ֣.ハイツ; ; xn--ucb18e.xn--eck4c5a; ; ; # ܣ֣.ハイツ
+xn--ucb18e.xn--eck4c5a; ܣ֣.ハイツ; ; xn--ucb18e.xn--eck4c5a; ; ; # ܣ֣.ハイツ
+ܣ֣.ハイツ; ; ; xn--ucb18e.xn--eck4c5a; ; ; # ܣ֣.ハイツ
+𞷥󠆀≮.⵿-; 𞷥≮.⵿-; [B1, B3, P1, V3, V5, V6]; xn--gdhx802p.xn----i2s; ; ; # ≮.⵿-
+𞷥󠆀≮.⵿-; 𞷥≮.⵿-; [B1, B3, P1, V3, V5, V6]; xn--gdhx802p.xn----i2s; ; ; # ≮.⵿-
+xn--gdhx802p.xn----i2s; 𞷥≮.⵿-; [B1, B3, V3, V5, V6]; xn--gdhx802p.xn----i2s; ; ; # ≮.⵿-
+₆榎򦖎്。𞤅ۭﱚ󠮨; 6榎򦖎്.𞤧ۭيي󠮨; [B1, B3, P1, V6]; xn--6-kmf4691ejv41j.xn--mhba10ch545mn8v8h; ; ; # 6榎്.𞤧ۭيي
+6榎򦖎്。𞤅ۭيي󠮨; 6榎򦖎്.𞤧ۭيي󠮨; [B1, B3, P1, V6]; xn--6-kmf4691ejv41j.xn--mhba10ch545mn8v8h; ; ; # 6榎്.𞤧ۭيي
+6榎򦖎്。𞤧ۭيي󠮨; 6榎򦖎്.𞤧ۭيي󠮨; [B1, B3, P1, V6]; xn--6-kmf4691ejv41j.xn--mhba10ch545mn8v8h; ; ; # 6榎്.𞤧ۭيي
+xn--6-kmf4691ejv41j.xn--mhba10ch545mn8v8h; 6榎򦖎്.𞤧ۭيي󠮨; [B1, B3, V6]; xn--6-kmf4691ejv41j.xn--mhba10ch545mn8v8h; ; ; # 6榎്.𞤧ۭيي
+₆榎򦖎്。𞤧ۭﱚ󠮨; 6榎򦖎്.𞤧ۭيي󠮨; [B1, B3, P1, V6]; xn--6-kmf4691ejv41j.xn--mhba10ch545mn8v8h; ; ; # 6榎്.𞤧ۭيي
+𣩫.򌑲; 𣩫.򌑲; [P1, V6]; xn--td3j.xn--4628b; ; ; # 𣩫.
+𣩫.򌑲; ; [P1, V6]; xn--td3j.xn--4628b; ; ; # 𣩫.
+xn--td3j.xn--4628b; 𣩫.򌑲; [V6]; xn--td3j.xn--4628b; ; ; # 𣩫.
+‍︒。ڹ‌; ‍︒.ڹ‌; [B1, B3, C1, C2, P1, V6]; xn--1ug2658f.xn--skb080k; ; xn--y86c.xn--skb; [B1, P1, V6] # ︒.ڹ
+xn--y86c.xn--skb; ︒.ڹ; [B1, V6]; xn--y86c.xn--skb; ; ; # ︒.ڹ
+xn--1ug2658f.xn--skb080k; ‍︒.ڹ‌; [B1, B3, C1, C2, V6]; xn--1ug2658f.xn--skb080k; ; ; # ︒.ڹ
+xn--skb; ڹ; ; xn--skb; ; ; # ڹ
+ڹ; ; ; xn--skb; ; ; # ڹ
+𐹦‌𐹶。; 𐹦‌𐹶.; [B1, C1, P1, V6]; xn--0ug4994goba.xn--sxg; ; xn--eo0d6a.xn--sxg; [B1, P1, V6] # 𐹦𐹶.
+xn--eo0d6a.xn--sxg; 𐹦𐹶.; [B1, V6]; xn--eo0d6a.xn--sxg; ; ; # 𐹦𐹶.
+xn--0ug4994goba.xn--sxg; 𐹦‌𐹶.; [B1, C1, V6]; xn--0ug4994goba.xn--sxg; ; ; # 𐹦𐹶.
+్𝨾֩𝟭。-𑜨; ్𝨾֩1.-𑜨; [V3, V5]; xn--1-rfc312cdp45c.xn----nq0j; ; ; # ్𝨾֩1.-𑜨
+్𝨾֩1。-𑜨; ్𝨾֩1.-𑜨; [V3, V5]; xn--1-rfc312cdp45c.xn----nq0j; ; ; # ్𝨾֩1.-𑜨
+xn--1-rfc312cdp45c.xn----nq0j; ్𝨾֩1.-𑜨; [V3, V5]; xn--1-rfc312cdp45c.xn----nq0j; ; ; # ్𝨾֩1.-𑜨
+򣿈。뙏; 򣿈.뙏; [P1, V6]; xn--ph26c.xn--281b; ; ; # .뙏
+򣿈。뙏; 򣿈.뙏; [P1, V6]; xn--ph26c.xn--281b; ; ; # .뙏
+xn--ph26c.xn--281b; 򣿈.뙏; [V6]; xn--ph26c.xn--281b; ; ; # .뙏
+񕨚󠄌󑽀ᡀ.ࢶ; 񕨚󑽀ᡀ.ࢶ; [P1, V6]; xn--z7e98100evc01b.xn--czb; ; ; # ᡀ.ࢶ
+xn--z7e98100evc01b.xn--czb; 񕨚󑽀ᡀ.ࢶ; [V6]; xn--z7e98100evc01b.xn--czb; ; ; # ᡀ.ࢶ
+‍。񅁛; ‍.񅁛; [C2, P1, V6]; xn--1ug.xn--6x4u; ; .xn--6x4u; [P1, V6, A4_2] # .
+‍。񅁛; ‍.񅁛; [C2, P1, V6]; xn--1ug.xn--6x4u; ; .xn--6x4u; [P1, V6, A4_2] # .
+.xn--6x4u; .񅁛; [V6, X4_2]; .xn--6x4u; [V6, A4_2]; ; # .
+xn--1ug.xn--6x4u; ‍.񅁛; [C2, V6]; xn--1ug.xn--6x4u; ; ; # .
+ࡋ皥.-; ࡋ皥.-; [B1, B2, B3, V3]; xn--9vb4167c.-; ; ; # ࡋ皥.-
+ࡋ皥.-; ; [B1, B2, B3, V3]; xn--9vb4167c.-; ; ; # ࡋ皥.-
+xn--9vb4167c.-; ࡋ皥.-; [B1, B2, B3, V3]; xn--9vb4167c.-; ; ; # ࡋ皥.-
+𐣸̕𐮇.⒈ꡦ; 𐣸̕𐮇.⒈ꡦ; [B1, P1, V6]; xn--5sa9915kgvb.xn--tshw539b; ; ; # ̕𐮇.⒈ꡦ
+𐣸̕𐮇.1.ꡦ; ; [B1, P1, V6]; xn--5sa9915kgvb.1.xn--cd9a; ; ; # ̕𐮇.1.ꡦ
+xn--5sa9915kgvb.1.xn--cd9a; 𐣸̕𐮇.1.ꡦ; [B1, V6]; xn--5sa9915kgvb.1.xn--cd9a; ; ; # ̕𐮇.1.ꡦ
+xn--5sa9915kgvb.xn--tshw539b; 𐣸̕𐮇.⒈ꡦ; [B1, V6]; xn--5sa9915kgvb.xn--tshw539b; ; ; # ̕𐮇.⒈ꡦ
+Ⴛ‌֢‍。ᅠā𐹦; Ⴛ‌֢‍.ᅠā𐹦; [B5, B6, C1, C2, P1, V6]; xn--tcb597cdmmfa.xn--yda9741khjj; ; xn--tcb597c.xn--yda9741khjj; [B5, B6, P1, V6] # Ⴛ֢.ā𐹦
+Ⴛ‌֢‍。ᅠā𐹦; Ⴛ‌֢‍.ᅠā𐹦; [B5, B6, C1, C2, P1, V6]; xn--tcb597cdmmfa.xn--yda9741khjj; ; xn--tcb597c.xn--yda9741khjj; [B5, B6, P1, V6] # Ⴛ֢.ā𐹦
+Ⴛ‌֢‍。ᅠā𐹦; Ⴛ‌֢‍.ᅠā𐹦; [B5, B6, C1, C2, P1, V6]; xn--tcb597cdmmfa.xn--yda594fdn5q; ; xn--tcb597c.xn--yda594fdn5q; [B5, B6, P1, V6] # Ⴛ֢.ā𐹦
+Ⴛ‌֢‍。ᅠā𐹦; Ⴛ‌֢‍.ᅠā𐹦; [B5, B6, C1, C2, P1, V6]; xn--tcb597cdmmfa.xn--yda594fdn5q; ; xn--tcb597c.xn--yda594fdn5q; [B5, B6, P1, V6] # Ⴛ֢.ā𐹦
+ⴛ‌֢‍。ᅠā𐹦; ⴛ‌֢‍.ᅠā𐹦; [B5, B6, C1, C2, P1, V6]; xn--tcb736kea974k.xn--yda594fdn5q; ; xn--tcb323r.xn--yda594fdn5q; [B5, B6, P1, V6] # ⴛ֢.ā𐹦
+ⴛ‌֢‍。ᅠā𐹦; ⴛ‌֢‍.ᅠā𐹦; [B5, B6, C1, C2, P1, V6]; xn--tcb736kea974k.xn--yda594fdn5q; ; xn--tcb323r.xn--yda594fdn5q; [B5, B6, P1, V6] # ⴛ֢.ā𐹦
+Ⴛ‌֢‍。ᅠĀ𐹦; Ⴛ‌֢‍.ᅠā𐹦; [B5, B6, C1, C2, P1, V6]; xn--tcb597cdmmfa.xn--yda594fdn5q; ; xn--tcb597c.xn--yda594fdn5q; [B5, B6, P1, V6] # Ⴛ֢.ā𐹦
+Ⴛ‌֢‍。ᅠĀ𐹦; Ⴛ‌֢‍.ᅠā𐹦; [B5, B6, C1, C2, P1, V6]; xn--tcb597cdmmfa.xn--yda594fdn5q; ; xn--tcb597c.xn--yda594fdn5q; [B5, B6, P1, V6] # Ⴛ֢.ā𐹦
+xn--tcb597c.xn--yda594fdn5q; Ⴛ֢.ᅠā𐹦; [B5, B6, V6]; xn--tcb597c.xn--yda594fdn5q; ; ; # Ⴛ֢.ā𐹦
+xn--tcb597cdmmfa.xn--yda594fdn5q; Ⴛ‌֢‍.ᅠā𐹦; [B5, B6, C1, C2, V6]; xn--tcb597cdmmfa.xn--yda594fdn5q; ; ; # Ⴛ֢.ā𐹦
+xn--tcb323r.xn--yda594fdn5q; ⴛ֢.ᅠā𐹦; [B5, B6, V6]; xn--tcb323r.xn--yda594fdn5q; ; ; # ⴛ֢.ā𐹦
+xn--tcb736kea974k.xn--yda594fdn5q; ⴛ‌֢‍.ᅠā𐹦; [B5, B6, C1, C2, V6]; xn--tcb736kea974k.xn--yda594fdn5q; ; ; # ⴛ֢.ā𐹦
+ⴛ‌֢‍。ᅠā𐹦; ⴛ‌֢‍.ᅠā𐹦; [B5, B6, C1, C2, P1, V6]; xn--tcb736kea974k.xn--yda9741khjj; ; xn--tcb323r.xn--yda9741khjj; [B5, B6, P1, V6] # ⴛ֢.ā𐹦
+ⴛ‌֢‍。ᅠā𐹦; ⴛ‌֢‍.ᅠā𐹦; [B5, B6, C1, C2, P1, V6]; xn--tcb736kea974k.xn--yda9741khjj; ; xn--tcb323r.xn--yda9741khjj; [B5, B6, P1, V6] # ⴛ֢.ā𐹦
+Ⴛ‌֢‍。ᅠĀ𐹦; Ⴛ‌֢‍.ᅠā𐹦; [B5, B6, C1, C2, P1, V6]; xn--tcb597cdmmfa.xn--yda9741khjj; ; xn--tcb597c.xn--yda9741khjj; [B5, B6, P1, V6] # Ⴛ֢.ā𐹦
+Ⴛ‌֢‍。ᅠĀ𐹦; Ⴛ‌֢‍.ᅠā𐹦; [B5, B6, C1, C2, P1, V6]; xn--tcb597cdmmfa.xn--yda9741khjj; ; xn--tcb597c.xn--yda9741khjj; [B5, B6, P1, V6] # Ⴛ֢.ā𐹦
+xn--tcb597c.xn--yda9741khjj; Ⴛ֢.ᅠā𐹦; [B5, B6, V6]; xn--tcb597c.xn--yda9741khjj; ; ; # Ⴛ֢.ā𐹦
+xn--tcb597cdmmfa.xn--yda9741khjj; Ⴛ‌֢‍.ᅠā𐹦; [B5, B6, C1, C2, V6]; xn--tcb597cdmmfa.xn--yda9741khjj; ; ; # Ⴛ֢.ā𐹦
+xn--tcb323r.xn--yda9741khjj; ⴛ֢.ᅠā𐹦; [B5, B6, V6]; xn--tcb323r.xn--yda9741khjj; ; ; # ⴛ֢.ā𐹦
+xn--tcb736kea974k.xn--yda9741khjj; ⴛ‌֢‍.ᅠā𐹦; [B5, B6, C1, C2, V6]; xn--tcb736kea974k.xn--yda9741khjj; ; ; # ⴛ֢.ā𐹦
+‌。曳⾑𐋰≯; ‌.曳襾𐋰≯; [C1, P1, V6]; xn--0ug2139f.xn--hdh501y8wvfs5h; ; xn--vn7c.xn--hdh501y8wvfs5h; [P1, V6] # .曳襾𐋰≯
+‌。曳⾑𐋰≯; ‌.曳襾𐋰≯; [C1, P1, V6]; xn--0ug2139f.xn--hdh501y8wvfs5h; ; xn--vn7c.xn--hdh501y8wvfs5h; [P1, V6] # .曳襾𐋰≯
+‌。曳襾𐋰≯; ‌.曳襾𐋰≯; [C1, P1, V6]; xn--0ug2139f.xn--hdh501y8wvfs5h; ; xn--vn7c.xn--hdh501y8wvfs5h; [P1, V6] # .曳襾𐋰≯
+‌。曳襾𐋰≯; ‌.曳襾𐋰≯; [C1, P1, V6]; xn--0ug2139f.xn--hdh501y8wvfs5h; ; xn--vn7c.xn--hdh501y8wvfs5h; [P1, V6] # .曳襾𐋰≯
+xn--vn7c.xn--hdh501y8wvfs5h; .曳襾𐋰≯; [V6]; xn--vn7c.xn--hdh501y8wvfs5h; ; ; # .曳襾𐋰≯
+xn--0ug2139f.xn--hdh501y8wvfs5h; ‌.曳襾𐋰≯; [C1, V6]; xn--0ug2139f.xn--hdh501y8wvfs5h; ; ; # .曳襾𐋰≯
+≯⒈。ß; ≯⒈.ß; [P1, V6]; xn--hdh84f.xn--zca; ; xn--hdh84f.ss; # ≯⒈.ß
+≯⒈。ß; ≯⒈.ß; [P1, V6]; xn--hdh84f.xn--zca; ; xn--hdh84f.ss; # ≯⒈.ß
+≯1.。ß; ≯1..ß; [P1, V6, X4_2]; xn--1-ogo..xn--zca; [P1, V6, A4_2]; xn--1-ogo..ss; # ≯1..ß
+≯1.。ß; ≯1..ß; [P1, V6, X4_2]; xn--1-ogo..xn--zca; [P1, V6, A4_2]; xn--1-ogo..ss; # ≯1..ß
+≯1.。SS; ≯1..ss; [P1, V6, X4_2]; xn--1-ogo..ss; [P1, V6, A4_2]; ; # ≯1..ss
+≯1.。SS; ≯1..ss; [P1, V6, X4_2]; xn--1-ogo..ss; [P1, V6, A4_2]; ; # ≯1..ss
+≯1.。ss; ≯1..ss; [P1, V6, X4_2]; xn--1-ogo..ss; [P1, V6, A4_2]; ; # ≯1..ss
+≯1.。ss; ≯1..ss; [P1, V6, X4_2]; xn--1-ogo..ss; [P1, V6, A4_2]; ; # ≯1..ss
+≯1.。Ss; ≯1..ss; [P1, V6, X4_2]; xn--1-ogo..ss; [P1, V6, A4_2]; ; # ≯1..ss
+≯1.。Ss; ≯1..ss; [P1, V6, X4_2]; xn--1-ogo..ss; [P1, V6, A4_2]; ; # ≯1..ss
+xn--1-ogo..ss; ≯1..ss; [V6, X4_2]; xn--1-ogo..ss; [V6, A4_2]; ; # ≯1..ss
+xn--1-ogo..xn--zca; ≯1..ß; [V6, X4_2]; xn--1-ogo..xn--zca; [V6, A4_2]; ; # ≯1..ß
+≯⒈。SS; ≯⒈.ss; [P1, V6]; xn--hdh84f.ss; ; ; # ≯⒈.ss
+≯⒈。SS; ≯⒈.ss; [P1, V6]; xn--hdh84f.ss; ; ; # ≯⒈.ss
+≯⒈。ss; ≯⒈.ss; [P1, V6]; xn--hdh84f.ss; ; ; # ≯⒈.ss
+≯⒈。ss; ≯⒈.ss; [P1, V6]; xn--hdh84f.ss; ; ; # ≯⒈.ss
+≯⒈。Ss; ≯⒈.ss; [P1, V6]; xn--hdh84f.ss; ; ; # ≯⒈.ss
+≯⒈。Ss; ≯⒈.ss; [P1, V6]; xn--hdh84f.ss; ; ; # ≯⒈.ss
+xn--hdh84f.ss; ≯⒈.ss; [V6]; xn--hdh84f.ss; ; ; # ≯⒈.ss
+xn--hdh84f.xn--zca; ≯⒈.ß; [V6]; xn--hdh84f.xn--zca; ; ; # ≯⒈.ß
+٧‍ﮖ。ߚ-₆Ⴙ; ٧‍ڳ.ߚ-6Ⴙ; [B1, B2, B3, C2, P1, V6]; xn--gib6m343e.xn---6-lve002g; ; xn--gib6m.xn---6-lve002g; [B1, B2, B3, P1, V6] # ٧ڳ.ߚ-6Ⴙ
+٧‍ڳ。ߚ-6Ⴙ; ٧‍ڳ.ߚ-6Ⴙ; [B1, B2, B3, C2, P1, V6]; xn--gib6m343e.xn---6-lve002g; ; xn--gib6m.xn---6-lve002g; [B1, B2, B3, P1, V6] # ٧ڳ.ߚ-6Ⴙ
+٧‍ڳ。ߚ-6ⴙ; ٧‍ڳ.ߚ-6ⴙ; [B1, B2, B3, C2]; xn--gib6m343e.xn---6-lve6529a; ; xn--gib6m.xn---6-lve6529a; [B1, B2, B3] # ٧ڳ.ߚ-6ⴙ
+xn--gib6m.xn---6-lve6529a; ٧ڳ.ߚ-6ⴙ; [B1, B2, B3]; xn--gib6m.xn---6-lve6529a; ; ; # ٧ڳ.ߚ-6ⴙ
+xn--gib6m343e.xn---6-lve6529a; ٧‍ڳ.ߚ-6ⴙ; [B1, B2, B3, C2]; xn--gib6m343e.xn---6-lve6529a; ; ; # ٧ڳ.ߚ-6ⴙ
+xn--gib6m.xn---6-lve002g; ٧ڳ.ߚ-6Ⴙ; [B1, B2, B3, V6]; xn--gib6m.xn---6-lve002g; ; ; # ٧ڳ.ߚ-6Ⴙ
+xn--gib6m343e.xn---6-lve002g; ٧‍ڳ.ߚ-6Ⴙ; [B1, B2, B3, C2, V6]; xn--gib6m343e.xn---6-lve002g; ; ; # ٧ڳ.ߚ-6Ⴙ
+٧‍ﮖ。ߚ-₆ⴙ; ٧‍ڳ.ߚ-6ⴙ; [B1, B2, B3, C2]; xn--gib6m343e.xn---6-lve6529a; ; xn--gib6m.xn---6-lve6529a; [B1, B2, B3] # ٧ڳ.ߚ-6ⴙ
+‌。≠; ‌.≠; [C1, P1, V6]; xn--0ug.xn--1ch; ; .xn--1ch; [P1, V6, A4_2] # .≠
+‌。≠; ‌.≠; [C1, P1, V6]; xn--0ug.xn--1ch; ; .xn--1ch; [P1, V6, A4_2] # .≠
+‌。≠; ‌.≠; [C1, P1, V6]; xn--0ug.xn--1ch; ; .xn--1ch; [P1, V6, A4_2] # .≠
+‌。≠; ‌.≠; [C1, P1, V6]; xn--0ug.xn--1ch; ; .xn--1ch; [P1, V6, A4_2] # .≠
+.xn--1ch; .≠; [V6, X4_2]; .xn--1ch; [V6, A4_2]; ; # .≠
+xn--0ug.xn--1ch; ‌.≠; [C1, V6]; xn--0ug.xn--1ch; ; ; # .≠
+𑖿𝨔.ᡟ𑖿ᭂ‌; ; [C1, V5]; xn--461dw464a.xn--v8e29ldzfo952a; ; xn--461dw464a.xn--v8e29loy65a; [V5] # 𑖿𝨔.ᡟ𑖿ᭂ
+xn--461dw464a.xn--v8e29loy65a; 𑖿𝨔.ᡟ𑖿ᭂ; [V5]; xn--461dw464a.xn--v8e29loy65a; ; ; # 𑖿𝨔.ᡟ𑖿ᭂ
+xn--461dw464a.xn--v8e29ldzfo952a; 𑖿𝨔.ᡟ𑖿ᭂ‌; [C1, V5]; xn--461dw464a.xn--v8e29ldzfo952a; ; ; # 𑖿𝨔.ᡟ𑖿ᭂ
+򔣳‍򑝱.𖬴Ↄ≠-; ; [C2, P1, V3, V5, V6]; xn--1ug15151gkb5a.xn----61n81bt713h; ; xn--6j00chy9a.xn----61n81bt713h; [P1, V3, V5, V6] # .𖬴Ↄ≠-
+򔣳‍򑝱.𖬴Ↄ≠-; 򔣳‍򑝱.𖬴Ↄ≠-; [C2, P1, V3, V5, V6]; xn--1ug15151gkb5a.xn----61n81bt713h; ; xn--6j00chy9a.xn----61n81bt713h; [P1, V3, V5, V6] # .𖬴Ↄ≠-
+򔣳‍򑝱.𖬴ↄ≠-; 򔣳‍򑝱.𖬴ↄ≠-; [C2, P1, V3, V5, V6]; xn--1ug15151gkb5a.xn----81n51bt713h; ; xn--6j00chy9a.xn----81n51bt713h; [P1, V3, V5, V6] # .𖬴ↄ≠-
+򔣳‍򑝱.𖬴ↄ≠-; ; [C2, P1, V3, V5, V6]; xn--1ug15151gkb5a.xn----81n51bt713h; ; xn--6j00chy9a.xn----81n51bt713h; [P1, V3, V5, V6] # .𖬴ↄ≠-
+xn--6j00chy9a.xn----81n51bt713h; 򔣳򑝱.𖬴ↄ≠-; [V3, V5, V6]; xn--6j00chy9a.xn----81n51bt713h; ; ; # .𖬴ↄ≠-
+xn--1ug15151gkb5a.xn----81n51bt713h; 򔣳‍򑝱.𖬴ↄ≠-; [C2, V3, V5, V6]; xn--1ug15151gkb5a.xn----81n51bt713h; ; ; # .𖬴ↄ≠-
+xn--6j00chy9a.xn----61n81bt713h; 򔣳򑝱.𖬴Ↄ≠-; [V3, V5, V6]; xn--6j00chy9a.xn----61n81bt713h; ; ; # .𖬴Ↄ≠-
+xn--1ug15151gkb5a.xn----61n81bt713h; 򔣳‍򑝱.𖬴Ↄ≠-; [C2, V3, V5, V6]; xn--1ug15151gkb5a.xn----61n81bt713h; ; ; # .𖬴Ↄ≠-
+ߢς‍𝟳。蔑򛖢; ߢς‍7.蔑򛖢; [B2, C2, P1, V6]; xn--7-xmb182aez5a.xn--wy1ao4929b; ; xn--7-zmb872a.xn--wy1ao4929b; [B2, P1, V6] # ߢς7.蔑
+ߢς‍7。蔑򛖢; ߢς‍7.蔑򛖢; [B2, C2, P1, V6]; xn--7-xmb182aez5a.xn--wy1ao4929b; ; xn--7-zmb872a.xn--wy1ao4929b; [B2, P1, V6] # ߢς7.蔑
+ߢΣ‍7。蔑򛖢; ߢσ‍7.蔑򛖢; [B2, C2, P1, V6]; xn--7-zmb872aez5a.xn--wy1ao4929b; ; xn--7-zmb872a.xn--wy1ao4929b; [B2, P1, V6] # ߢσ7.蔑
+ߢσ‍7。蔑򛖢; ߢσ‍7.蔑򛖢; [B2, C2, P1, V6]; xn--7-zmb872aez5a.xn--wy1ao4929b; ; xn--7-zmb872a.xn--wy1ao4929b; [B2, P1, V6] # ߢσ7.蔑
+xn--7-zmb872a.xn--wy1ao4929b; ߢσ7.蔑򛖢; [B2, V6]; xn--7-zmb872a.xn--wy1ao4929b; ; ; # ߢσ7.蔑
+xn--7-zmb872aez5a.xn--wy1ao4929b; ߢσ‍7.蔑򛖢; [B2, C2, V6]; xn--7-zmb872aez5a.xn--wy1ao4929b; ; ; # ߢσ7.蔑
+xn--7-xmb182aez5a.xn--wy1ao4929b; ߢς‍7.蔑򛖢; [B2, C2, V6]; xn--7-xmb182aez5a.xn--wy1ao4929b; ; ; # ߢς7.蔑
+ߢΣ‍𝟳。蔑򛖢; ߢσ‍7.蔑򛖢; [B2, C2, P1, V6]; xn--7-zmb872aez5a.xn--wy1ao4929b; ; xn--7-zmb872a.xn--wy1ao4929b; [B2, P1, V6] # ߢσ7.蔑
+ߢσ‍𝟳。蔑򛖢; ߢσ‍7.蔑򛖢; [B2, C2, P1, V6]; xn--7-zmb872aez5a.xn--wy1ao4929b; ; xn--7-zmb872a.xn--wy1ao4929b; [B2, P1, V6] # ߢσ7.蔑
+𐹰.؀; ; [B1, P1, V6]; xn--oo0d.xn--ifb; ; ; # 𐹰.
+xn--oo0d.xn--ifb; 𐹰.؀; [B1, V6]; xn--oo0d.xn--ifb; ; ; # 𐹰.
+-ࢨ.𱠖; ; [B1, P1, V3, V6]; xn----mod.xn--5o9n; ; ; # -ࢨ.
+xn----mod.xn--5o9n; -ࢨ.𱠖; [B1, V3, V6]; xn----mod.xn--5o9n; ; ; # -ࢨ.
+≯𞱸󠇀。誆⒈; ≯𞱸.誆⒈; [B1, P1, V6]; xn--hdh7151p.xn--tsh1248a; ; ; # ≯𞱸.誆⒈
+≯𞱸󠇀。誆⒈; ≯𞱸.誆⒈; [B1, P1, V6]; xn--hdh7151p.xn--tsh1248a; ; ; # ≯𞱸.誆⒈
+≯𞱸󠇀。誆1.; ≯𞱸.誆1.; [B1, P1, V6]; xn--hdh7151p.xn--1-dy1d.; ; ; # ≯𞱸.誆1.
+≯𞱸󠇀。誆1.; ≯𞱸.誆1.; [B1, P1, V6]; xn--hdh7151p.xn--1-dy1d.; ; ; # ≯𞱸.誆1.
+xn--hdh7151p.xn--1-dy1d.; ≯𞱸.誆1.; [B1, V6]; xn--hdh7151p.xn--1-dy1d.; ; ; # ≯𞱸.誆1.
+xn--hdh7151p.xn--tsh1248a; ≯𞱸.誆⒈; [B1, V6]; xn--hdh7151p.xn--tsh1248a; ; ; # ≯𞱸.誆⒈
+ؖ𞥙䐊ِ.︒م↺ڜ; ؖ𞥙䐊ِ.︒م↺ڜ; [B1, P1, V5, V6]; xn--4fb0j490qjg4x.xn--hhb8o948euo5r; ; ; # ؖ𞥙䐊ِ.︒م↺ڜ
+ؖ𞥙䐊ِ.。م↺ڜ; ؖ𞥙䐊ِ..م↺ڜ; [B1, V5, X4_2]; xn--4fb0j490qjg4x..xn--hhb8o948e; [B1, V5, A4_2]; ; # ؖ𞥙䐊ِ..م↺ڜ
+xn--4fb0j490qjg4x..xn--hhb8o948e; ؖ𞥙䐊ِ..م↺ڜ; [B1, V5, X4_2]; xn--4fb0j490qjg4x..xn--hhb8o948e; [B1, V5, A4_2]; ; # ؖ𞥙䐊ِ..م↺ڜ
+xn--4fb0j490qjg4x.xn--hhb8o948euo5r; ؖ𞥙䐊ِ.︒م↺ڜ; [B1, V5, V6]; xn--4fb0j490qjg4x.xn--hhb8o948euo5r; ; ; # ؖ𞥙䐊ِ.︒م↺ڜ
+퀬-?񶳒.‌ૅ󩸤۴; ; [C1, P1, V6]; xn---?-6g4k75207c.xn--hmb76q48y18505a; ; xn---?-6g4k75207c.xn--hmb76q74166b; [P1, V5, V6] # 퀬-?.ૅ۴
+퀬-?񶳒.‌ૅ󩸤۴; 퀬-?񶳒.‌ૅ󩸤۴; [C1, P1, V6]; xn---?-6g4k75207c.xn--hmb76q48y18505a; ; xn---?-6g4k75207c.xn--hmb76q74166b; [P1, V5, V6] # 퀬-?.ૅ۴
+xn---?-6g4k75207c.xn--hmb76q74166b; 퀬-?񶳒.ૅ󩸤۴; [P1, V5, V6]; xn---?-6g4k75207c.xn--hmb76q74166b; ; ; # 퀬-?.ૅ۴
+xn---?-6g4k75207c.xn--hmb76q48y18505a; 퀬-?񶳒.‌ૅ󩸤۴; [C1, P1, V6]; xn---?-6g4k75207c.xn--hmb76q48y18505a; ; ; # 퀬-?.ૅ۴
+퀬-?񶳒.xn--hmb76q74166b; 퀬-?񶳒.ૅ󩸤۴; [P1, V5, V6]; xn---?-6g4k75207c.xn--hmb76q74166b; ; ; # 퀬-?.ૅ۴
+퀬-?񶳒.xn--hmb76q74166b; 퀬-?񶳒.ૅ󩸤۴; [P1, V5, V6]; xn---?-6g4k75207c.xn--hmb76q74166b; ; ; # 퀬-?.ૅ۴
+퀬-?񶳒.XN--HMB76Q74166B; 퀬-?񶳒.ૅ󩸤۴; [P1, V5, V6]; xn---?-6g4k75207c.xn--hmb76q74166b; ; ; # 퀬-?.ૅ۴
+퀬-?񶳒.XN--HMB76Q74166B; 퀬-?񶳒.ૅ󩸤۴; [P1, V5, V6]; xn---?-6g4k75207c.xn--hmb76q74166b; ; ; # 퀬-?.ૅ۴
+퀬-?񶳒.Xn--Hmb76q74166b; 퀬-?񶳒.ૅ󩸤۴; [P1, V5, V6]; xn---?-6g4k75207c.xn--hmb76q74166b; ; ; # 퀬-?.ૅ۴
+퀬-?񶳒.Xn--Hmb76q74166b; 퀬-?񶳒.ૅ󩸤۴; [P1, V5, V6]; xn---?-6g4k75207c.xn--hmb76q74166b; ; ; # 퀬-?.ૅ۴
+퀬-?񶳒.xn--hmb76q48y18505a; 퀬-?񶳒.‌ૅ󩸤۴; [C1, P1, V6]; xn---?-6g4k75207c.xn--hmb76q48y18505a; ; ; # 퀬-?.ૅ۴
+퀬-?񶳒.xn--hmb76q48y18505a; 퀬-?񶳒.‌ૅ󩸤۴; [C1, P1, V6]; xn---?-6g4k75207c.xn--hmb76q48y18505a; ; ; # 퀬-?.ૅ۴
+퀬-?񶳒.XN--HMB76Q48Y18505A; 퀬-?񶳒.‌ૅ󩸤۴; [C1, P1, V6]; xn---?-6g4k75207c.xn--hmb76q48y18505a; ; ; # 퀬-?.ૅ۴
+퀬-?񶳒.XN--HMB76Q48Y18505A; 퀬-?񶳒.‌ૅ󩸤۴; [C1, P1, V6]; xn---?-6g4k75207c.xn--hmb76q48y18505a; ; ; # 퀬-?.ૅ۴
+퀬-?񶳒.Xn--Hmb76q48y18505a; 퀬-?񶳒.‌ૅ󩸤۴; [C1, P1, V6]; xn---?-6g4k75207c.xn--hmb76q48y18505a; ; ; # 퀬-?.ૅ۴
+퀬-?񶳒.Xn--Hmb76q48y18505a; 퀬-?񶳒.‌ૅ󩸤۴; [C1, P1, V6]; xn---?-6g4k75207c.xn--hmb76q48y18505a; ; ; # 퀬-?.ૅ۴
+Ⴌ.𐹾︒𑁿𞾄; ; [B1, P1, V6]; xn--knd.xn--y86c030a9ob6374b; ; ; # Ⴌ.𐹾︒𑁿
+Ⴌ.𐹾。𑁿𞾄; Ⴌ.𐹾.𑁿𞾄; [B1, P1, V5, V6]; xn--knd.xn--2o0d.xn--q30dg029a; ; ; # Ⴌ.𐹾.𑁿
+ⴌ.𐹾。𑁿𞾄; ⴌ.𐹾.𑁿𞾄; [B1, P1, V5, V6]; xn--3kj.xn--2o0d.xn--q30dg029a; ; ; # ⴌ.𐹾.𑁿
+xn--3kj.xn--2o0d.xn--q30dg029a; ⴌ.𐹾.𑁿𞾄; [B1, V5, V6]; xn--3kj.xn--2o0d.xn--q30dg029a; ; ; # ⴌ.𐹾.𑁿
+xn--knd.xn--2o0d.xn--q30dg029a; Ⴌ.𐹾.𑁿𞾄; [B1, V5, V6]; xn--knd.xn--2o0d.xn--q30dg029a; ; ; # Ⴌ.𐹾.𑁿
+ⴌ.𐹾︒𑁿𞾄; ; [B1, P1, V6]; xn--3kj.xn--y86c030a9ob6374b; ; ; # ⴌ.𐹾︒𑁿
+xn--3kj.xn--y86c030a9ob6374b; ⴌ.𐹾︒𑁿𞾄; [B1, V6]; xn--3kj.xn--y86c030a9ob6374b; ; ; # ⴌ.𐹾︒𑁿
+xn--knd.xn--y86c030a9ob6374b; Ⴌ.𐹾︒𑁿𞾄; [B1, V6]; xn--knd.xn--y86c030a9ob6374b; ; ; # Ⴌ.𐹾︒𑁿
+񧞿╏。𞩕󠁾; 񧞿╏.𞩕󠁾; [B3, B6, P1, V6]; xn--iyh90030d.xn--1m6hs0260c; ; ; # ╏.
+xn--iyh90030d.xn--1m6hs0260c; 񧞿╏.𞩕󠁾; [B3, B6, V6]; xn--iyh90030d.xn--1m6hs0260c; ; ; # ╏.
+‍┮󠇐.ఀ్᜴‍; ‍┮.ఀ్᜴‍; [C2, V5]; xn--1ug04r.xn--eoc8m432a40i; ; xn--kxh.xn--eoc8m432a; [V5] # ┮.ఀ్᜴
+‍┮󠇐.ఀ్᜴‍; ‍┮.ఀ్᜴‍; [C2, V5]; xn--1ug04r.xn--eoc8m432a40i; ; xn--kxh.xn--eoc8m432a; [V5] # ┮.ఀ్᜴
+xn--kxh.xn--eoc8m432a; ┮.ఀ్᜴; [V5]; xn--kxh.xn--eoc8m432a; ; ; # ┮.ఀ్᜴
+xn--1ug04r.xn--eoc8m432a40i; ‍┮.ఀ్᜴‍; [C2, V5]; xn--1ug04r.xn--eoc8m432a40i; ; ; # ┮.ఀ్᜴
+򹚪。🄂; 򹚪.🄂; [P1, V6]; xn--n433d.xn--v07h; ; ; # .🄂
+򹚪。1,; 򹚪.1,; [P1, V6]; xn--n433d.1,; ; ; # .1,
+xn--n433d.1,; 򹚪.1,; [P1, V6]; xn--n433d.1,; ; ; # .1,
+xn--n433d.xn--v07h; 򹚪.🄂; [V6]; xn--n433d.xn--v07h; ; ; # .🄂
+𑍨刍.🛦; ; [V5]; xn--rbry728b.xn--y88h; ; ; # 𑍨刍.🛦
+xn--rbry728b.xn--y88h; 𑍨刍.🛦; [V5]; xn--rbry728b.xn--y88h; ; ; # 𑍨刍.🛦
+󠌏3。ᯱ𝟒; 󠌏3.ᯱ4; [P1, V5, V6]; xn--3-ib31m.xn--4-pql; ; ; # 3.ᯱ4
+󠌏3。ᯱ4; 󠌏3.ᯱ4; [P1, V5, V6]; xn--3-ib31m.xn--4-pql; ; ; # 3.ᯱ4
+xn--3-ib31m.xn--4-pql; 󠌏3.ᯱ4; [V5, V6]; xn--3-ib31m.xn--4-pql; ; ; # 3.ᯱ4
+ڇ6Ⴔ辘.ﴢڇ‌; ڇ6Ⴔ辘.صيڇ‌; [B2, B3, C1, P1, V6]; xn--6-gsc039eqq6k.xn--0gb6bxkx18g; ; xn--6-gsc039eqq6k.xn--0gb6bxk; [B2, B3, P1, V6] # ڇ6Ⴔ辘.صيڇ
+ڇ6Ⴔ辘.صيڇ‌; ; [B2, B3, C1, P1, V6]; xn--6-gsc039eqq6k.xn--0gb6bxkx18g; ; xn--6-gsc039eqq6k.xn--0gb6bxk; [B2, B3, P1, V6] # ڇ6Ⴔ辘.صيڇ
+ڇ6ⴔ辘.صيڇ‌; ; [B2, B3, C1]; xn--6-gsc2270akm6f.xn--0gb6bxkx18g; ; xn--6-gsc2270akm6f.xn--0gb6bxk; [B2, B3] # ڇ6ⴔ辘.صيڇ
+xn--6-gsc2270akm6f.xn--0gb6bxk; ڇ6ⴔ辘.صيڇ; [B2, B3]; xn--6-gsc2270akm6f.xn--0gb6bxk; ; ; # ڇ6ⴔ辘.صيڇ
+xn--6-gsc2270akm6f.xn--0gb6bxkx18g; ڇ6ⴔ辘.صيڇ‌; [B2, B3, C1]; xn--6-gsc2270akm6f.xn--0gb6bxkx18g; ; ; # ڇ6ⴔ辘.صيڇ
+xn--6-gsc039eqq6k.xn--0gb6bxk; ڇ6Ⴔ辘.صيڇ; [B2, B3, V6]; xn--6-gsc039eqq6k.xn--0gb6bxk; ; ; # ڇ6Ⴔ辘.صيڇ
+xn--6-gsc039eqq6k.xn--0gb6bxkx18g; ڇ6Ⴔ辘.صيڇ‌; [B2, B3, C1, V6]; xn--6-gsc039eqq6k.xn--0gb6bxkx18g; ; ; # ڇ6Ⴔ辘.صيڇ
+ڇ6ⴔ辘.ﴢڇ‌; ڇ6ⴔ辘.صيڇ‌; [B2, B3, C1]; xn--6-gsc2270akm6f.xn--0gb6bxkx18g; ; xn--6-gsc2270akm6f.xn--0gb6bxk; [B2, B3] # ڇ6ⴔ辘.صيڇ
+󠄍.𐮭𞰬򻫞۹; .𐮭𞰬򻫞۹; [B2, P1, V6, X4_2]; .xn--mmb3954kd0uf1zx7f; [B2, P1, V6, A4_2]; ; # .𐮭۹
+.xn--mmb3954kd0uf1zx7f; .𐮭𞰬򻫞۹; [B2, V6, X4_2]; .xn--mmb3954kd0uf1zx7f; [B2, V6, A4_2]; ; # .𐮭۹
+꡽≯.򻲀򒳄; ꡽≯.򻲀򒳄; [P1, V6]; xn--hdh8193c.xn--5z40cp629b; ; ; # ≯.
+꡽≯.򻲀򒳄; ꡽≯.򻲀򒳄; [P1, V6]; xn--hdh8193c.xn--5z40cp629b; ; ; # ≯.
+꡽≯.򻲀򒳄; ; [P1, V6]; xn--hdh8193c.xn--5z40cp629b; ; ; # ≯.
+꡽≯.򻲀򒳄; ꡽≯.򻲀򒳄; [P1, V6]; xn--hdh8193c.xn--5z40cp629b; ; ; # ≯.
+xn--hdh8193c.xn--5z40cp629b; ꡽≯.򻲀򒳄; [V6]; xn--hdh8193c.xn--5z40cp629b; ; ; # ≯.
+ςოٻ.ςܔ; ; [B5, B6]; xn--3xa80l26n.xn--3xa41o; ; xn--4xa60l26n.xn--4xa21o; # ςოٻ.ςܔ
+ΣᲝٻ.Σܔ; σოٻ.σܔ; [B5, B6]; xn--4xa60l26n.xn--4xa21o; ; ; # σოٻ.σܔ
+σოٻ.σܔ; ; [B5, B6]; xn--4xa60l26n.xn--4xa21o; ; ; # σოٻ.σܔ
+Σოٻ.σܔ; σოٻ.σܔ; [B5, B6]; xn--4xa60l26n.xn--4xa21o; ; ; # σოٻ.σܔ
+xn--4xa60l26n.xn--4xa21o; σოٻ.σܔ; [B5, B6]; xn--4xa60l26n.xn--4xa21o; ; ; # σოٻ.σܔ
+Σოٻ.ςܔ; σოٻ.ςܔ; [B5, B6]; xn--4xa60l26n.xn--3xa41o; ; xn--4xa60l26n.xn--4xa21o; # σოٻ.ςܔ
+σოٻ.ςܔ; ; [B5, B6]; xn--4xa60l26n.xn--3xa41o; ; xn--4xa60l26n.xn--4xa21o; # σოٻ.ςܔ
+xn--4xa60l26n.xn--3xa41o; σოٻ.ςܔ; [B5, B6]; xn--4xa60l26n.xn--3xa41o; ; ; # σოٻ.ςܔ
+xn--3xa80l26n.xn--3xa41o; ςოٻ.ςܔ; [B5, B6]; xn--3xa80l26n.xn--3xa41o; ; ; # ςოٻ.ςܔ
+Σოٻ.Σܔ; σოٻ.σܔ; [B5, B6]; xn--4xa60l26n.xn--4xa21o; ; ; # σოٻ.σܔ
+򄖚݈𠄯ݟ。󠛩; 򄖚݈𠄯ݟ.󠛩; [B1, B5, B6, P1, V6]; xn--vob0c4369twfv8b.xn--kl46e; ; ; # ݈𠄯ݟ.
+򄖚݈𠄯ݟ。󠛩; 򄖚݈𠄯ݟ.󠛩; [B1, B5, B6, P1, V6]; xn--vob0c4369twfv8b.xn--kl46e; ; ; # ݈𠄯ݟ.
+xn--vob0c4369twfv8b.xn--kl46e; 򄖚݈𠄯ݟ.󠛩; [B1, B5, B6, V6]; xn--vob0c4369twfv8b.xn--kl46e; ; ; # ݈𠄯ݟ.
+󠳛.‍䤫≠Ⴞ; 󠳛.‍䤫≠Ⴞ; [C2, P1, V6]; xn--1t56e.xn--2nd159e9vb743e; ; xn--1t56e.xn--2nd141ghl2a; [P1, V6] # .䤫≠Ⴞ
+󠳛.‍䤫≠Ⴞ; 󠳛.‍䤫≠Ⴞ; [C2, P1, V6]; xn--1t56e.xn--2nd159e9vb743e; ; xn--1t56e.xn--2nd141ghl2a; [P1, V6] # .䤫≠Ⴞ
+󠳛.‍䤫≠Ⴞ; ; [C2, P1, V6]; xn--1t56e.xn--2nd159e9vb743e; ; xn--1t56e.xn--2nd141ghl2a; [P1, V6] # .䤫≠Ⴞ
+󠳛.‍䤫≠Ⴞ; 󠳛.‍䤫≠Ⴞ; [C2, P1, V6]; xn--1t56e.xn--2nd159e9vb743e; ; xn--1t56e.xn--2nd141ghl2a; [P1, V6] # .䤫≠Ⴞ
+󠳛.‍䤫≠ⴞ; 󠳛.‍䤫≠ⴞ; [C2, P1, V6]; xn--1t56e.xn--1ug73gzzpwi3a; ; xn--1t56e.xn--1ch153bqvw; [P1, V6] # .䤫≠ⴞ
+󠳛.‍䤫≠ⴞ; ; [C2, P1, V6]; xn--1t56e.xn--1ug73gzzpwi3a; ; xn--1t56e.xn--1ch153bqvw; [P1, V6] # .䤫≠ⴞ
+xn--1t56e.xn--1ch153bqvw; 󠳛.䤫≠ⴞ; [V6]; xn--1t56e.xn--1ch153bqvw; ; ; # .䤫≠ⴞ
+xn--1t56e.xn--1ug73gzzpwi3a; 󠳛.‍䤫≠ⴞ; [C2, V6]; xn--1t56e.xn--1ug73gzzpwi3a; ; ; # .䤫≠ⴞ
+xn--1t56e.xn--2nd141ghl2a; 󠳛.䤫≠Ⴞ; [V6]; xn--1t56e.xn--2nd141ghl2a; ; ; # .䤫≠Ⴞ
+xn--1t56e.xn--2nd159e9vb743e; 󠳛.‍䤫≠Ⴞ; [C2, V6]; xn--1t56e.xn--2nd159e9vb743e; ; ; # .䤫≠Ⴞ
+󠳛.‍䤫≠ⴞ; 󠳛.‍䤫≠ⴞ; [C2, P1, V6]; xn--1t56e.xn--1ug73gzzpwi3a; ; xn--1t56e.xn--1ch153bqvw; [P1, V6] # .䤫≠ⴞ
+󠳛.‍䤫≠ⴞ; 󠳛.‍䤫≠ⴞ; [C2, P1, V6]; xn--1t56e.xn--1ug73gzzpwi3a; ; xn--1t56e.xn--1ch153bqvw; [P1, V6] # .䤫≠ⴞ
+𐽘𑈵.𐹣🕥; 𐽘𑈵.𐹣🕥; [B1, B2, B3]; xn--bv0d02c.xn--bo0dq650b; ; ; # 𐽘𑈵.𐹣🕥
+𐽘𑈵.𐹣🕥; ; [B1, B2, B3]; xn--bv0d02c.xn--bo0dq650b; ; ; # 𐽘𑈵.𐹣🕥
+xn--bv0d02c.xn--bo0dq650b; 𐽘𑈵.𐹣🕥; [B1, B2, B3]; xn--bv0d02c.xn--bo0dq650b; ; ; # 𐽘𑈵.𐹣🕥
+⒊⒈𑁄。9; ⒊⒈𑁄.9; [P1, V6]; xn--tshd3512p.9; ; ; # ⒊⒈𑁄.9
+3.1.𑁄。9; 3.1.𑁄.9; [V5]; 3.1.xn--110d.9; ; ; # 3.1.𑁄.9
+3.1.xn--110d.9; 3.1.𑁄.9; [V5]; 3.1.xn--110d.9; ; ; # 3.1.𑁄.9
+xn--tshd3512p.9; ⒊⒈𑁄.9; [V6]; xn--tshd3512p.9; ; ; # ⒊⒈𑁄.9
+-‌ⷱ≮.𐹱򭏴4₉; -‌ⷱ≮.𐹱򭏴49; [B1, C1, P1, V3, V6]; xn----sgn20i14s.xn--49-ki3om2611f; ; xn----ngo823c.xn--49-ki3om2611f; [B1, P1, V3, V6] # -ⷱ≮.𐹱49
+-‌ⷱ≮.𐹱򭏴4₉; -‌ⷱ≮.𐹱򭏴49; [B1, C1, P1, V3, V6]; xn----sgn20i14s.xn--49-ki3om2611f; ; xn----ngo823c.xn--49-ki3om2611f; [B1, P1, V3, V6] # -ⷱ≮.𐹱49
+-‌ⷱ≮.𐹱򭏴49; ; [B1, C1, P1, V3, V6]; xn----sgn20i14s.xn--49-ki3om2611f; ; xn----ngo823c.xn--49-ki3om2611f; [B1, P1, V3, V6] # -ⷱ≮.𐹱49
+-‌ⷱ≮.𐹱򭏴49; -‌ⷱ≮.𐹱򭏴49; [B1, C1, P1, V3, V6]; xn----sgn20i14s.xn--49-ki3om2611f; ; xn----ngo823c.xn--49-ki3om2611f; [B1, P1, V3, V6] # -ⷱ≮.𐹱49
+xn----ngo823c.xn--49-ki3om2611f; -ⷱ≮.𐹱򭏴49; [B1, V3, V6]; xn----ngo823c.xn--49-ki3om2611f; ; ; # -ⷱ≮.𐹱49
+xn----sgn20i14s.xn--49-ki3om2611f; -‌ⷱ≮.𐹱򭏴49; [B1, C1, V3, V6]; xn----sgn20i14s.xn--49-ki3om2611f; ; ; # -ⷱ≮.𐹱49
+-≯딾。ࡇ; -≯딾.ࡇ; [B1, P1, V3, V6]; xn----pgow547d.xn--5vb; ; ; # -≯딾.ࡇ
+-≯딾。ࡇ; -≯딾.ࡇ; [B1, P1, V3, V6]; xn----pgow547d.xn--5vb; ; ; # -≯딾.ࡇ
+-≯딾。ࡇ; -≯딾.ࡇ; [B1, P1, V3, V6]; xn----pgow547d.xn--5vb; ; ; # -≯딾.ࡇ
+-≯딾。ࡇ; -≯딾.ࡇ; [B1, P1, V3, V6]; xn----pgow547d.xn--5vb; ; ; # -≯딾.ࡇ
+xn----pgow547d.xn--5vb; -≯딾.ࡇ; [B1, V3, V6]; xn----pgow547d.xn--5vb; ; ; # -≯딾.ࡇ
+𑙢⒈𐹠-。󠗐‌; 𑙢⒈𐹠-.󠗐‌; [B1, C1, P1, V3, V6]; xn----dcpy090hiyg.xn--0ug23321l; ; xn----dcpy090hiyg.xn--jd46e; [B1, P1, V3, V6] # 𑙢⒈𐹠-.
+𑙢1.𐹠-。󠗐‌; 𑙢1.𐹠-.󠗐‌; [B1, C1, P1, V3, V6]; xn--1-bf0j.xn----516i.xn--0ug23321l; ; xn--1-bf0j.xn----516i.xn--jd46e; [B1, P1, V3, V6] # 𑙢1.𐹠-.
+xn--1-bf0j.xn----516i.xn--jd46e; 𑙢1.𐹠-.󠗐; [B1, V3, V6]; xn--1-bf0j.xn----516i.xn--jd46e; ; ; # 𑙢1.𐹠-.
+xn--1-bf0j.xn----516i.xn--0ug23321l; 𑙢1.𐹠-.󠗐‌; [B1, C1, V3, V6]; xn--1-bf0j.xn----516i.xn--0ug23321l; ; ; # 𑙢1.𐹠-.
+xn----dcpy090hiyg.xn--jd46e; 𑙢⒈𐹠-.󠗐; [B1, V3, V6]; xn----dcpy090hiyg.xn--jd46e; ; ; # 𑙢⒈𐹠-.
+xn----dcpy090hiyg.xn--0ug23321l; 𑙢⒈𐹠-.󠗐‌; [B1, C1, V3, V6]; xn----dcpy090hiyg.xn--0ug23321l; ; ; # 𑙢⒈𐹠-.
+͊.𐨎; ͊.𐨎; [V5]; xn--oua.xn--mr9c; ; ; # ͊.𐨎
+͊.𐨎; ; [V5]; xn--oua.xn--mr9c; ; ; # ͊.𐨎
+xn--oua.xn--mr9c; ͊.𐨎; [V5]; xn--oua.xn--mr9c; ; ; # ͊.𐨎
+훉≮。ิ; 훉≮.ิ; [P1, V5, V6]; xn--gdh2512e.xn--i4c; ; ; # 훉≮.ิ
+훉≮。ิ; 훉≮.ิ; [P1, V5, V6]; xn--gdh2512e.xn--i4c; ; ; # 훉≮.ิ
+훉≮。ิ; 훉≮.ิ; [P1, V5, V6]; xn--gdh2512e.xn--i4c; ; ; # 훉≮.ิ
+훉≮。ิ; 훉≮.ิ; [P1, V5, V6]; xn--gdh2512e.xn--i4c; ; ; # 훉≮.ิ
+xn--gdh2512e.xn--i4c; 훉≮.ิ; [V5, V6]; xn--gdh2512e.xn--i4c; ; ; # 훉≮.ิ
+ⷷ򞣉🃘.𴈇𝟸ٙ𞤯; ⷷ򞣉🃘.𴈇2ٙ𞤯; [B1, B5, B6, P1, V5, V6]; xn--trj8045le6s9b.xn--2-upc23918acjsj; ; ; # ⷷ🃘.2ٙ𞤯
+ⷷ򞣉🃘.𴈇2ٙ𞤯; ; [B1, B5, B6, P1, V5, V6]; xn--trj8045le6s9b.xn--2-upc23918acjsj; ; ; # ⷷ🃘.2ٙ𞤯
+ⷷ򞣉🃘.𴈇2ٙ𞤍; ⷷ򞣉🃘.𴈇2ٙ𞤯; [B1, B5, B6, P1, V5, V6]; xn--trj8045le6s9b.xn--2-upc23918acjsj; ; ; # ⷷ🃘.2ٙ𞤯
+xn--trj8045le6s9b.xn--2-upc23918acjsj; ⷷ򞣉🃘.𴈇2ٙ𞤯; [B1, B5, B6, V5, V6]; xn--trj8045le6s9b.xn--2-upc23918acjsj; ; ; # ⷷ🃘.2ٙ𞤯
+ⷷ򞣉🃘.𴈇𝟸ٙ𞤍; ⷷ򞣉🃘.𴈇2ٙ𞤯; [B1, B5, B6, P1, V5, V6]; xn--trj8045le6s9b.xn--2-upc23918acjsj; ; ; # ⷷ🃘.2ٙ𞤯
+󗇩ßᢞ‌。٠𞷻ﳔ-; 󗇩ßᢞ‌.٠𞷻نخ-; [B1, B6, C1, P1, V3, V6]; xn--zca272jbif10059a.xn----dnc5e1er384z; ; xn--ss-jepz4596r.xn----dnc5e1er384z; [B1, P1, V3, V6] # ßᢞ.٠نخ-
+󗇩ßᢞ‌。٠𞷻نخ-; 󗇩ßᢞ‌.٠𞷻نخ-; [B1, B6, C1, P1, V3, V6]; xn--zca272jbif10059a.xn----dnc5e1er384z; ; xn--ss-jepz4596r.xn----dnc5e1er384z; [B1, P1, V3, V6] # ßᢞ.٠نخ-
+󗇩SSᢞ‌。٠𞷻نخ-; 󗇩ssᢞ‌.٠𞷻نخ-; [B1, B6, C1, P1, V3, V6]; xn--ss-jep006bqt765b.xn----dnc5e1er384z; ; xn--ss-jepz4596r.xn----dnc5e1er384z; [B1, P1, V3, V6] # ssᢞ.٠نخ-
+󗇩ssᢞ‌。٠𞷻نخ-; 󗇩ssᢞ‌.٠𞷻نخ-; [B1, B6, C1, P1, V3, V6]; xn--ss-jep006bqt765b.xn----dnc5e1er384z; ; xn--ss-jepz4596r.xn----dnc5e1er384z; [B1, P1, V3, V6] # ssᢞ.٠نخ-
+󗇩Ssᢞ‌。٠𞷻نخ-; 󗇩ssᢞ‌.٠𞷻نخ-; [B1, B6, C1, P1, V3, V6]; xn--ss-jep006bqt765b.xn----dnc5e1er384z; ; xn--ss-jepz4596r.xn----dnc5e1er384z; [B1, P1, V3, V6] # ssᢞ.٠نخ-
+xn--ss-jepz4596r.xn----dnc5e1er384z; 󗇩ssᢞ.٠𞷻نخ-; [B1, V3, V6]; xn--ss-jepz4596r.xn----dnc5e1er384z; ; ; # ssᢞ.٠نخ-
+xn--ss-jep006bqt765b.xn----dnc5e1er384z; 󗇩ssᢞ‌.٠𞷻نخ-; [B1, B6, C1, V3, V6]; xn--ss-jep006bqt765b.xn----dnc5e1er384z; ; ; # ssᢞ.٠نخ-
+xn--zca272jbif10059a.xn----dnc5e1er384z; 󗇩ßᢞ‌.٠𞷻نخ-; [B1, B6, C1, V3, V6]; xn--zca272jbif10059a.xn----dnc5e1er384z; ; ; # ßᢞ.٠نخ-
+󗇩SSᢞ‌。٠𞷻ﳔ-; 󗇩ssᢞ‌.٠𞷻نخ-; [B1, B6, C1, P1, V3, V6]; xn--ss-jep006bqt765b.xn----dnc5e1er384z; ; xn--ss-jepz4596r.xn----dnc5e1er384z; [B1, P1, V3, V6] # ssᢞ.٠نخ-
+󗇩ssᢞ‌。٠𞷻ﳔ-; 󗇩ssᢞ‌.٠𞷻نخ-; [B1, B6, C1, P1, V3, V6]; xn--ss-jep006bqt765b.xn----dnc5e1er384z; ; xn--ss-jepz4596r.xn----dnc5e1er384z; [B1, P1, V3, V6] # ssᢞ.٠نخ-
+󗇩Ssᢞ‌。٠𞷻ﳔ-; 󗇩ssᢞ‌.٠𞷻نخ-; [B1, B6, C1, P1, V3, V6]; xn--ss-jep006bqt765b.xn----dnc5e1er384z; ; xn--ss-jepz4596r.xn----dnc5e1er384z; [B1, P1, V3, V6] # ssᢞ.٠نخ-
+ꡆ。Ↄྵ놮-; ꡆ.Ↄྵ놮-; [P1, V3, V6]; xn--fc9a.xn----qmg787k869k; ; ; # ꡆ.Ↄྵ놮-
+ꡆ。Ↄྵ놮-; ꡆ.Ↄྵ놮-; [P1, V3, V6]; xn--fc9a.xn----qmg787k869k; ; ; # ꡆ.Ↄྵ놮-
+ꡆ。ↄྵ놮-; ꡆ.ↄྵ놮-; [V3]; xn--fc9a.xn----qmg097k469k; ; ; # ꡆ.ↄྵ놮-
+ꡆ。ↄྵ놮-; ꡆ.ↄྵ놮-; [V3]; xn--fc9a.xn----qmg097k469k; ; ; # ꡆ.ↄྵ놮-
+xn--fc9a.xn----qmg097k469k; ꡆ.ↄྵ놮-; [V3]; xn--fc9a.xn----qmg097k469k; ; ; # ꡆ.ↄྵ놮-
+xn--fc9a.xn----qmg787k869k; ꡆ.Ↄྵ놮-; [V3, V6]; xn--fc9a.xn----qmg787k869k; ; ; # ꡆ.Ↄྵ놮-
+ﶭ‍.񥰌ک; لمي‍.񥰌ک; [B3, B5, B6, C2, P1, V6]; xn--ghbcp494x.xn--ckb36214f; ; xn--ghbcp.xn--ckb36214f; [B5, B6, P1, V6] # لمي.ک
+لمي‍.񥰌ک; ; [B3, B5, B6, C2, P1, V6]; xn--ghbcp494x.xn--ckb36214f; ; xn--ghbcp.xn--ckb36214f; [B5, B6, P1, V6] # لمي.ک
+xn--ghbcp.xn--ckb36214f; لمي.񥰌ک; [B5, B6, V6]; xn--ghbcp.xn--ckb36214f; ; ; # لمي.ک
+xn--ghbcp494x.xn--ckb36214f; لمي‍.񥰌ک; [B3, B5, B6, C2, V6]; xn--ghbcp494x.xn--ckb36214f; ; ; # لمي.ک
+Ⴜᰯ𐳒≯。۠ᜲྺ; Ⴜᰯ𐳒≯.۠ᜲྺ; [B1, B3, B5, B6, P1, V5, V6]; xn--0nd679cf3eq67y.xn--wlb646b4ng; ; ; # Ⴜᰯ𐳒≯.۠ᜲྺ
+Ⴜᰯ𐳒≯。۠ᜲྺ; Ⴜᰯ𐳒≯.۠ᜲྺ; [B1, B3, B5, B6, P1, V5, V6]; xn--0nd679cf3eq67y.xn--wlb646b4ng; ; ; # Ⴜᰯ𐳒≯.۠ᜲྺ
+ⴜᰯ𐳒≯。۠ᜲྺ; ⴜᰯ𐳒≯.۠ᜲྺ; [B1, B3, B5, B6, P1, V5, V6]; xn--r1f68xh1jgv7u.xn--wlb646b4ng; ; ; # ⴜᰯ𐳒≯.۠ᜲྺ
+ⴜᰯ𐳒≯。۠ᜲྺ; ⴜᰯ𐳒≯.۠ᜲྺ; [B1, B3, B5, B6, P1, V5, V6]; xn--r1f68xh1jgv7u.xn--wlb646b4ng; ; ; # ⴜᰯ𐳒≯.۠ᜲྺ
+Ⴜᰯ𐲒≯。۠ᜲྺ; Ⴜᰯ𐳒≯.۠ᜲྺ; [B1, B3, B5, B6, P1, V5, V6]; xn--0nd679cf3eq67y.xn--wlb646b4ng; ; ; # Ⴜᰯ𐳒≯.۠ᜲྺ
+Ⴜᰯ𐲒≯。۠ᜲྺ; Ⴜᰯ𐳒≯.۠ᜲྺ; [B1, B3, B5, B6, P1, V5, V6]; xn--0nd679cf3eq67y.xn--wlb646b4ng; ; ; # Ⴜᰯ𐳒≯.۠ᜲྺ
+xn--0nd679cf3eq67y.xn--wlb646b4ng; Ⴜᰯ𐳒≯.۠ᜲྺ; [B1, B3, B5, B6, V5, V6]; xn--0nd679cf3eq67y.xn--wlb646b4ng; ; ; # Ⴜᰯ𐳒≯.۠ᜲྺ
+xn--r1f68xh1jgv7u.xn--wlb646b4ng; ⴜᰯ𐳒≯.۠ᜲྺ; [B1, B3, B5, B6, V5, V6]; xn--r1f68xh1jgv7u.xn--wlb646b4ng; ; ; # ⴜᰯ𐳒≯.۠ᜲྺ
+𐋵。ﳬ; 𐋵.كم; [B1]; xn--p97c.xn--fhbe; ; ; # 𐋵.كم
+𐋵。كم; 𐋵.كم; [B1]; xn--p97c.xn--fhbe; ; ; # 𐋵.كم
+xn--p97c.xn--fhbe; 𐋵.كم; [B1]; xn--p97c.xn--fhbe; ; ; # 𐋵.كم
+𐋵.كم; ; [B1]; xn--p97c.xn--fhbe; ; ; # 𐋵.كم
+≮𝅶.񱲁ꫬ⹈󰥭; ≮𝅶.񱲁ꫬ⹈󰥭; [P1, V6]; xn--gdh0880o.xn--4tjx101bsg00ds9pyc; ; ; # ≮.ꫬ⹈
+≮𝅶.񱲁ꫬ⹈󰥭; ≮𝅶.񱲁ꫬ⹈󰥭; [P1, V6]; xn--gdh0880o.xn--4tjx101bsg00ds9pyc; ; ; # ≮.ꫬ⹈
+≮𝅶.񱲁ꫬ⹈󰥭; ; [P1, V6]; xn--gdh0880o.xn--4tjx101bsg00ds9pyc; ; ; # ≮.ꫬ⹈
+≮𝅶.񱲁ꫬ⹈󰥭; ≮𝅶.񱲁ꫬ⹈󰥭; [P1, V6]; xn--gdh0880o.xn--4tjx101bsg00ds9pyc; ; ; # ≮.ꫬ⹈
+xn--gdh0880o.xn--4tjx101bsg00ds9pyc; ≮𝅶.񱲁ꫬ⹈󰥭; [V6]; xn--gdh0880o.xn--4tjx101bsg00ds9pyc; ; ; # ≮.ꫬ⹈
+ⷰ͘ᢕ.͡𐹷󠴍; ⷰ͘ᢕ.͡𐹷󠴍; [B1, P1, V5, V6]; xn--2ua889htsp.xn--cva2687k2tv0g; ; ; # ⷰ͘ᢕ.͡𐹷
+ⷰ͘ᢕ.͡𐹷󠴍; ; [B1, P1, V5, V6]; xn--2ua889htsp.xn--cva2687k2tv0g; ; ; # ⷰ͘ᢕ.͡𐹷
+xn--2ua889htsp.xn--cva2687k2tv0g; ⷰ͘ᢕ.͡𐹷󠴍; [B1, V5, V6]; xn--2ua889htsp.xn--cva2687k2tv0g; ; ; # ⷰ͘ᢕ.͡𐹷
+ﵹᡐ‌ڭ.𑋪ׇ; غممᡐ‌ڭ.𑋪ׇ; [B1, B2, B3, B6, V5]; xn--5gbwa03bg24eptk.xn--vdb1198k; ; xn--5gbwa03bg24e.xn--vdb1198k; # غممᡐڭ.𑋪ׇ
+غممᡐ‌ڭ.𑋪ׇ; ; [B1, B2, B3, B6, V5]; xn--5gbwa03bg24eptk.xn--vdb1198k; ; xn--5gbwa03bg24e.xn--vdb1198k; # غممᡐڭ.𑋪ׇ
+xn--5gbwa03bg24e.xn--vdb1198k; غممᡐڭ.𑋪ׇ; [B1, B2, B3, B6, V5]; xn--5gbwa03bg24e.xn--vdb1198k; ; ; # غممᡐڭ.𑋪ׇ
+xn--5gbwa03bg24eptk.xn--vdb1198k; غممᡐ‌ڭ.𑋪ׇ; [B1, B2, B3, B6, V5]; xn--5gbwa03bg24eptk.xn--vdb1198k; ; ; # غممᡐڭ.𑋪ׇ
+𑑂。‍󥞀🞕򥁔; 𑑂.‍󥞀🞕򥁔; [C2, P1, V5, V6]; xn--8v1d.xn--1ug1386plvx1cd8vya; ; xn--8v1d.xn--ye9h41035a2qqs; [P1, V5, V6] # 𑑂.🞕
+𑑂。‍󥞀🞕򥁔; 𑑂.‍󥞀🞕򥁔; [C2, P1, V5, V6]; xn--8v1d.xn--1ug1386plvx1cd8vya; ; xn--8v1d.xn--ye9h41035a2qqs; [P1, V5, V6] # 𑑂.🞕
+xn--8v1d.xn--ye9h41035a2qqs; 𑑂.󥞀🞕򥁔; [V5, V6]; xn--8v1d.xn--ye9h41035a2qqs; ; ; # 𑑂.🞕
+xn--8v1d.xn--1ug1386plvx1cd8vya; 𑑂.‍󥞀🞕򥁔; [C2, V5, V6]; xn--8v1d.xn--1ug1386plvx1cd8vya; ; ; # 𑑂.🞕
+-ש。⒚; -ש.⒚; [B1, P1, V3, V6]; xn----gjc.xn--cth; ; ; # -ש.⒚
+-ש。19.; -ש.19.; [B1, V3]; xn----gjc.19.; ; ; # -ש.19.
+xn----gjc.19.; -ש.19.; [B1, V3]; xn----gjc.19.; ; ; # -ש.19.
+xn----gjc.xn--cth; -ש.⒚; [B1, V3, V6]; xn----gjc.xn--cth; ; ; # -ש.⒚
+􊾻ࡅ‌。ᢎ‍; 􊾻ࡅ‌.ᢎ‍; [B5, B6, C1, C2, P1, V6]; xn--3vb882jz4411a.xn--79e259a; ; xn--3vb50049s.xn--79e; [B5, B6, P1, V6] # ࡅ.ᢎ
+􊾻ࡅ‌。ᢎ‍; 􊾻ࡅ‌.ᢎ‍; [B5, B6, C1, C2, P1, V6]; xn--3vb882jz4411a.xn--79e259a; ; xn--3vb50049s.xn--79e; [B5, B6, P1, V6] # ࡅ.ᢎ
+xn--3vb50049s.xn--79e; 􊾻ࡅ.ᢎ; [B5, B6, V6]; xn--3vb50049s.xn--79e; ; ; # ࡅ.ᢎ
+xn--3vb882jz4411a.xn--79e259a; 􊾻ࡅ‌.ᢎ‍; [B5, B6, C1, C2, V6]; xn--3vb882jz4411a.xn--79e259a; ; ; # ࡅ.ᢎ
+ßুᷭ。ؠ8₅; ßুᷭ.ؠ85; ; xn--zca266bwrr.xn--85-psd; ; xn--ss-e2f077r.xn--85-psd; # ßুᷭ.ؠ85
+ßুᷭ。ؠ85; ßুᷭ.ؠ85; ; xn--zca266bwrr.xn--85-psd; ; xn--ss-e2f077r.xn--85-psd; # ßুᷭ.ؠ85
+SSুᷭ。ؠ85; ssুᷭ.ؠ85; ; xn--ss-e2f077r.xn--85-psd; ; ; # ssুᷭ.ؠ85
+ssুᷭ。ؠ85; ssুᷭ.ؠ85; ; xn--ss-e2f077r.xn--85-psd; ; ; # ssুᷭ.ؠ85
+Ssুᷭ。ؠ85; ssুᷭ.ؠ85; ; xn--ss-e2f077r.xn--85-psd; ; ; # ssুᷭ.ؠ85
+xn--ss-e2f077r.xn--85-psd; ssুᷭ.ؠ85; ; xn--ss-e2f077r.xn--85-psd; ; ; # ssুᷭ.ؠ85
+ssুᷭ.ؠ85; ; ; xn--ss-e2f077r.xn--85-psd; ; ; # ssুᷭ.ؠ85
+SSুᷭ.ؠ85; ssুᷭ.ؠ85; ; xn--ss-e2f077r.xn--85-psd; ; ; # ssুᷭ.ؠ85
+Ssুᷭ.ؠ85; ssুᷭ.ؠ85; ; xn--ss-e2f077r.xn--85-psd; ; ; # ssুᷭ.ؠ85
+xn--zca266bwrr.xn--85-psd; ßুᷭ.ؠ85; ; xn--zca266bwrr.xn--85-psd; ; ; # ßুᷭ.ؠ85
+ßুᷭ.ؠ85; ; ; xn--zca266bwrr.xn--85-psd; ; xn--ss-e2f077r.xn--85-psd; # ßুᷭ.ؠ85
+SSুᷭ。ؠ8₅; ssুᷭ.ؠ85; ; xn--ss-e2f077r.xn--85-psd; ; ; # ssুᷭ.ؠ85
+ssুᷭ。ؠ8₅; ssুᷭ.ؠ85; ; xn--ss-e2f077r.xn--85-psd; ; ; # ssুᷭ.ؠ85
+Ssুᷭ。ؠ8₅; ssুᷭ.ؠ85; ; xn--ss-e2f077r.xn--85-psd; ; ; # ssুᷭ.ؠ85
+્҄魅𝟣.₃𐹥ß; ્҄魅1.3𐹥ß; [B1, V5]; xn--1-0xb049b102o.xn--3-qfa7018r; ; xn--1-0xb049b102o.xn--3ss-nv9t; # ્҄魅1.3𐹥ß
+્҄魅1.3𐹥ß; ; [B1, V5]; xn--1-0xb049b102o.xn--3-qfa7018r; ; xn--1-0xb049b102o.xn--3ss-nv9t; # ્҄魅1.3𐹥ß
+્҄魅1.3𐹥SS; ્҄魅1.3𐹥ss; [B1, V5]; xn--1-0xb049b102o.xn--3ss-nv9t; ; ; # ્҄魅1.3𐹥ss
+્҄魅1.3𐹥ss; ; [B1, V5]; xn--1-0xb049b102o.xn--3ss-nv9t; ; ; # ્҄魅1.3𐹥ss
+્҄魅1.3𐹥Ss; ્҄魅1.3𐹥ss; [B1, V5]; xn--1-0xb049b102o.xn--3ss-nv9t; ; ; # ્҄魅1.3𐹥ss
+xn--1-0xb049b102o.xn--3ss-nv9t; ્҄魅1.3𐹥ss; [B1, V5]; xn--1-0xb049b102o.xn--3ss-nv9t; ; ; # ્҄魅1.3𐹥ss
+xn--1-0xb049b102o.xn--3-qfa7018r; ્҄魅1.3𐹥ß; [B1, V5]; xn--1-0xb049b102o.xn--3-qfa7018r; ; ; # ્҄魅1.3𐹥ß
+્҄魅𝟣.₃𐹥SS; ્҄魅1.3𐹥ss; [B1, V5]; xn--1-0xb049b102o.xn--3ss-nv9t; ; ; # ્҄魅1.3𐹥ss
+્҄魅𝟣.₃𐹥ss; ્҄魅1.3𐹥ss; [B1, V5]; xn--1-0xb049b102o.xn--3ss-nv9t; ; ; # ્҄魅1.3𐹥ss
+્҄魅𝟣.₃𐹥Ss; ્҄魅1.3𐹥ss; [B1, V5]; xn--1-0xb049b102o.xn--3ss-nv9t; ; ; # ્҄魅1.3𐹥ss
+ܫ。𑓂⒈𑜫󠿻; ܫ.𑓂⒈𑜫󠿻; [B1, P1, V5, V6]; xn--1nb.xn--tsh7798f6rbrt828c; ; ; # ܫ.𑓂⒈𑜫
+ܫ。𑓂1.𑜫󠿻; ܫ.𑓂1.𑜫󠿻; [B1, P1, V5, V6]; xn--1nb.xn--1-jq9i.xn--ji2dg9877c; ; ; # ܫ.𑓂1.𑜫
+xn--1nb.xn--1-jq9i.xn--ji2dg9877c; ܫ.𑓂1.𑜫󠿻; [B1, V5, V6]; xn--1nb.xn--1-jq9i.xn--ji2dg9877c; ; ; # ܫ.𑓂1.𑜫
+xn--1nb.xn--tsh7798f6rbrt828c; ܫ.𑓂⒈𑜫󠿻; [B1, V5, V6]; xn--1nb.xn--tsh7798f6rbrt828c; ; ; # ܫ.𑓂⒈𑜫
+︍છ。嵨; છ.嵨; ; xn--6dc.xn--tot; ; ; # છ.嵨
+xn--6dc.xn--tot; છ.嵨; ; xn--6dc.xn--tot; ; ; # છ.嵨
+છ.嵨; ; ; xn--6dc.xn--tot; ; ; # છ.嵨
+Ⴔ≠Ⴀ.𐹥𐹰; ; [B1, P1, V6]; xn--7md3b171g.xn--do0dwa; ; ; # Ⴔ≠Ⴀ.𐹥𐹰
+Ⴔ≠Ⴀ.𐹥𐹰; Ⴔ≠Ⴀ.𐹥𐹰; [B1, P1, V6]; xn--7md3b171g.xn--do0dwa; ; ; # Ⴔ≠Ⴀ.𐹥𐹰
+ⴔ≠ⴀ.𐹥𐹰; ⴔ≠ⴀ.𐹥𐹰; [B1, P1, V6]; xn--1ch603bxb.xn--do0dwa; ; ; # ⴔ≠ⴀ.𐹥𐹰
+ⴔ≠ⴀ.𐹥𐹰; ; [B1, P1, V6]; xn--1ch603bxb.xn--do0dwa; ; ; # ⴔ≠ⴀ.𐹥𐹰
+xn--1ch603bxb.xn--do0dwa; ⴔ≠ⴀ.𐹥𐹰; [B1, V6]; xn--1ch603bxb.xn--do0dwa; ; ; # ⴔ≠ⴀ.𐹥𐹰
+xn--7md3b171g.xn--do0dwa; Ⴔ≠Ⴀ.𐹥𐹰; [B1, V6]; xn--7md3b171g.xn--do0dwa; ; ; # Ⴔ≠Ⴀ.𐹥𐹰
+-‌⒙𐫥。𝨵; -‌⒙𐫥.𝨵; [C1, P1, V3, V5, V6]; xn----sgn18r3191a.xn--382h; ; xn----ddps939g.xn--382h; [P1, V3, V5, V6] # -⒙𐫥.𝨵
+-‌18.𐫥。𝨵; -‌18.𐫥.𝨵; [C1, V3, V5]; xn---18-9m0a.xn--rx9c.xn--382h; ; -18.xn--rx9c.xn--382h; [V3, V5] # -18.𐫥.𝨵
+-18.xn--rx9c.xn--382h; -18.𐫥.𝨵; [V3, V5]; -18.xn--rx9c.xn--382h; ; ; # -18.𐫥.𝨵
+xn---18-9m0a.xn--rx9c.xn--382h; -‌18.𐫥.𝨵; [C1, V3, V5]; xn---18-9m0a.xn--rx9c.xn--382h; ; ; # -18.𐫥.𝨵
+xn----ddps939g.xn--382h; -⒙𐫥.𝨵; [V3, V5, V6]; xn----ddps939g.xn--382h; ; ; # -⒙𐫥.𝨵
+xn----sgn18r3191a.xn--382h; -‌⒙𐫥.𝨵; [C1, V3, V5, V6]; xn----sgn18r3191a.xn--382h; ; ; # -⒙𐫥.𝨵
+︒.ʌᠣ-𐹽; ; [B1, B5, B6, P1, V6]; xn--y86c.xn----73a596nuh9t; ; ; # ︒.ʌᠣ-𐹽
+。.ʌᠣ-𐹽; ..ʌᠣ-𐹽; [B5, B6, X4_2]; ..xn----73a596nuh9t; [B5, B6, A4_2]; ; # ..ʌᠣ-𐹽
+。.Ʌᠣ-𐹽; ..ʌᠣ-𐹽; [B5, B6, X4_2]; ..xn----73a596nuh9t; [B5, B6, A4_2]; ; # ..ʌᠣ-𐹽
+..xn----73a596nuh9t; ..ʌᠣ-𐹽; [B5, B6, X4_2]; ..xn----73a596nuh9t; [B5, B6, A4_2]; ; # ..ʌᠣ-𐹽
+︒.Ʌᠣ-𐹽; ︒.ʌᠣ-𐹽; [B1, B5, B6, P1, V6]; xn--y86c.xn----73a596nuh9t; ; ; # ︒.ʌᠣ-𐹽
+xn--y86c.xn----73a596nuh9t; ︒.ʌᠣ-𐹽; [B1, B5, B6, V6]; xn--y86c.xn----73a596nuh9t; ; ; # ︒.ʌᠣ-𐹽
+︅︒。𦀾᳠; ︒.𦀾᳠; [P1, V6]; xn--y86c.xn--t6f5138v; ; ; # ︒.𦀾᳠
+︅。。𦀾᳠; ..𦀾᳠; [X4_2]; ..xn--t6f5138v; [A4_2]; ; # ..𦀾᳠
+..xn--t6f5138v; ..𦀾᳠; [X4_2]; ..xn--t6f5138v; [A4_2]; ; # ..𦀾᳠
+xn--y86c.xn--t6f5138v; ︒.𦀾᳠; [V6]; xn--y86c.xn--t6f5138v; ; ; # ︒.𦀾᳠
+xn--t6f5138v; 𦀾᳠; ; xn--t6f5138v; ; ; # 𦀾᳠
+𦀾᳠; ; ; xn--t6f5138v; ; ; # 𦀾᳠
+𞮑ß􏞞。ᡁ; 𞮑ß􏞞.ᡁ; [B2, B3, P1, V6]; xn--zca9432wb989f.xn--07e; ; xn--ss-o412ac6305g.xn--07e; # ß.ᡁ
+𞮑SS􏞞。ᡁ; 𞮑ss􏞞.ᡁ; [B2, B3, P1, V6]; xn--ss-o412ac6305g.xn--07e; ; ; # ss.ᡁ
+𞮑ss􏞞。ᡁ; 𞮑ss􏞞.ᡁ; [B2, B3, P1, V6]; xn--ss-o412ac6305g.xn--07e; ; ; # ss.ᡁ
+𞮑Ss􏞞。ᡁ; 𞮑ss􏞞.ᡁ; [B2, B3, P1, V6]; xn--ss-o412ac6305g.xn--07e; ; ; # ss.ᡁ
+xn--ss-o412ac6305g.xn--07e; 𞮑ss􏞞.ᡁ; [B2, B3, V6]; xn--ss-o412ac6305g.xn--07e; ; ; # ss.ᡁ
+xn--zca9432wb989f.xn--07e; 𞮑ß􏞞.ᡁ; [B2, B3, V6]; xn--zca9432wb989f.xn--07e; ; ; # ß.ᡁ
+꥓‍ج٬。𱆎󻡟‌󠅆; ꥓‍ج٬.𱆎󻡟‌; [B5, B6, C1, P1, V5, V6]; xn--rgb2k500fhq9j.xn--0ug78870a5sp9d; ; xn--rgb2k6711c.xn--ec8nj3948b; [B5, B6, P1, V5, V6] # ꥓ج٬.𱆎
+xn--rgb2k6711c.xn--ec8nj3948b; ꥓ج٬.𱆎󻡟; [B5, B6, V5, V6]; xn--rgb2k6711c.xn--ec8nj3948b; ; ; # ꥓ج٬.𱆎
+xn--rgb2k500fhq9j.xn--0ug78870a5sp9d; ꥓‍ج٬.𱆎󻡟‌; [B5, B6, C1, V5, V6]; xn--rgb2k500fhq9j.xn--0ug78870a5sp9d; ; ; # ꥓ج٬.𱆎
+󠕏.-ß‌≠; 󠕏.-ß‌≠; [C1, P1, V3, V6]; xn--u836e.xn----qfa750ve7b; ; xn--u836e.xn---ss-gl2a; [P1, V3, V6] # .-ß≠
+󠕏.-ß‌≠; 󠕏.-ß‌≠; [C1, P1, V3, V6]; xn--u836e.xn----qfa750ve7b; ; xn--u836e.xn---ss-gl2a; [P1, V3, V6] # .-ß≠
+󠕏.-ß‌≠; ; [C1, P1, V3, V6]; xn--u836e.xn----qfa750ve7b; ; xn--u836e.xn---ss-gl2a; [P1, V3, V6] # .-ß≠
+󠕏.-ß‌≠; 󠕏.-ß‌≠; [C1, P1, V3, V6]; xn--u836e.xn----qfa750ve7b; ; xn--u836e.xn---ss-gl2a; [P1, V3, V6] # .-ß≠
+󠕏.-SS‌≠; 󠕏.-ss‌≠; [C1, P1, V3, V6]; xn--u836e.xn---ss-cn0at5l; ; xn--u836e.xn---ss-gl2a; [P1, V3, V6] # .-ss≠
+󠕏.-SS‌≠; 󠕏.-ss‌≠; [C1, P1, V3, V6]; xn--u836e.xn---ss-cn0at5l; ; xn--u836e.xn---ss-gl2a; [P1, V3, V6] # .-ss≠
+󠕏.-ss‌≠; ; [C1, P1, V3, V6]; xn--u836e.xn---ss-cn0at5l; ; xn--u836e.xn---ss-gl2a; [P1, V3, V6] # .-ss≠
+󠕏.-ss‌≠; 󠕏.-ss‌≠; [C1, P1, V3, V6]; xn--u836e.xn---ss-cn0at5l; ; xn--u836e.xn---ss-gl2a; [P1, V3, V6] # .-ss≠
+󠕏.-Ss‌≠; 󠕏.-ss‌≠; [C1, P1, V3, V6]; xn--u836e.xn---ss-cn0at5l; ; xn--u836e.xn---ss-gl2a; [P1, V3, V6] # .-ss≠
+󠕏.-Ss‌≠; 󠕏.-ss‌≠; [C1, P1, V3, V6]; xn--u836e.xn---ss-cn0at5l; ; xn--u836e.xn---ss-gl2a; [P1, V3, V6] # .-ss≠
+xn--u836e.xn---ss-gl2a; 󠕏.-ss≠; [V3, V6]; xn--u836e.xn---ss-gl2a; ; ; # .-ss≠
+xn--u836e.xn---ss-cn0at5l; 󠕏.-ss‌≠; [C1, V3, V6]; xn--u836e.xn---ss-cn0at5l; ; ; # .-ss≠
+xn--u836e.xn----qfa750ve7b; 󠕏.-ß‌≠; [C1, V3, V6]; xn--u836e.xn----qfa750ve7b; ; ; # .-ß≠
+󠕏.-SS‌≠; 󠕏.-ss‌≠; [C1, P1, V3, V6]; xn--u836e.xn---ss-cn0at5l; ; xn--u836e.xn---ss-gl2a; [P1, V3, V6] # .-ss≠
+󠕏.-SS‌≠; 󠕏.-ss‌≠; [C1, P1, V3, V6]; xn--u836e.xn---ss-cn0at5l; ; xn--u836e.xn---ss-gl2a; [P1, V3, V6] # .-ss≠
+󠕏.-ss‌≠; 󠕏.-ss‌≠; [C1, P1, V3, V6]; xn--u836e.xn---ss-cn0at5l; ; xn--u836e.xn---ss-gl2a; [P1, V3, V6] # .-ss≠
+󠕏.-ss‌≠; 󠕏.-ss‌≠; [C1, P1, V3, V6]; xn--u836e.xn---ss-cn0at5l; ; xn--u836e.xn---ss-gl2a; [P1, V3, V6] # .-ss≠
+󠕏.-Ss‌≠; 󠕏.-ss‌≠; [C1, P1, V3, V6]; xn--u836e.xn---ss-cn0at5l; ; xn--u836e.xn---ss-gl2a; [P1, V3, V6] # .-ss≠
+󠕏.-Ss‌≠; 󠕏.-ss‌≠; [C1, P1, V3, V6]; xn--u836e.xn---ss-cn0at5l; ; xn--u836e.xn---ss-gl2a; [P1, V3, V6] # .-ss≠
+ᡙ‌。≯𐋲≠; ᡙ‌.≯𐋲≠; [C1, P1, V6]; xn--p8e650b.xn--1ch3a7084l; ; xn--p8e.xn--1ch3a7084l; [P1, V6] # ᡙ.≯𐋲≠
+ᡙ‌。≯𐋲≠; ᡙ‌.≯𐋲≠; [C1, P1, V6]; xn--p8e650b.xn--1ch3a7084l; ; xn--p8e.xn--1ch3a7084l; [P1, V6] # ᡙ.≯𐋲≠
+ᡙ‌。≯𐋲≠; ᡙ‌.≯𐋲≠; [C1, P1, V6]; xn--p8e650b.xn--1ch3a7084l; ; xn--p8e.xn--1ch3a7084l; [P1, V6] # ᡙ.≯𐋲≠
+ᡙ‌。≯𐋲≠; ᡙ‌.≯𐋲≠; [C1, P1, V6]; xn--p8e650b.xn--1ch3a7084l; ; xn--p8e.xn--1ch3a7084l; [P1, V6] # ᡙ.≯𐋲≠
+xn--p8e.xn--1ch3a7084l; ᡙ.≯𐋲≠; [V6]; xn--p8e.xn--1ch3a7084l; ; ; # ᡙ.≯𐋲≠
+xn--p8e650b.xn--1ch3a7084l; ᡙ‌.≯𐋲≠; [C1, V6]; xn--p8e650b.xn--1ch3a7084l; ; ; # ᡙ.≯𐋲≠
+𐹧𞲄󠁭񆼩。͎🄀; 𐹧𞲄󠁭񆼩.͎🄀; [B1, P1, V5, V6]; xn--fo0dw409aq58qrn69d.xn--sua6883w; ; ; # 𐹧𞲄.͎🄀
+𐹧𞲄󠁭񆼩。͎0.; 𐹧𞲄󠁭񆼩.͎0.; [B1, P1, V5, V6]; xn--fo0dw409aq58qrn69d.xn--0-bgb.; ; ; # 𐹧𞲄.͎0.
+xn--fo0dw409aq58qrn69d.xn--0-bgb.; 𐹧𞲄󠁭񆼩.͎0.; [B1, V5, V6]; xn--fo0dw409aq58qrn69d.xn--0-bgb.; ; ; # 𐹧𞲄.͎0.
+xn--fo0dw409aq58qrn69d.xn--sua6883w; 𐹧𞲄󠁭񆼩.͎🄀; [B1, V5, V6]; xn--fo0dw409aq58qrn69d.xn--sua6883w; ; ; # 𐹧𞲄.͎🄀
+Ⴄ.‍ܡ󻣋ς; Ⴄ.‍ܡ󻣋ς; [B1, C2, P1, V6]; xn--cnd.xn--3xa93o3t5ajq467a; ; xn--cnd.xn--4xa73ob5892c; [B2, B3, P1, V6] # Ⴄ.ܡς
+Ⴄ.‍ܡ󻣋ς; ; [B1, C2, P1, V6]; xn--cnd.xn--3xa93o3t5ajq467a; ; xn--cnd.xn--4xa73ob5892c; [B2, B3, P1, V6] # Ⴄ.ܡς
+ⴄ.‍ܡ󻣋ς; ; [B1, C2, P1, V6]; xn--vkj.xn--3xa93o3t5ajq467a; ; xn--vkj.xn--4xa73ob5892c; [B2, B3, P1, V6] # ⴄ.ܡς
+Ⴄ.‍ܡ󻣋Σ; Ⴄ.‍ܡ󻣋σ; [B1, C2, P1, V6]; xn--cnd.xn--4xa73o3t5ajq467a; ; xn--cnd.xn--4xa73ob5892c; [B2, B3, P1, V6] # Ⴄ.ܡσ
+ⴄ.‍ܡ󻣋σ; ; [B1, C2, P1, V6]; xn--vkj.xn--4xa73o3t5ajq467a; ; xn--vkj.xn--4xa73ob5892c; [B2, B3, P1, V6] # ⴄ.ܡσ
+xn--vkj.xn--4xa73ob5892c; ⴄ.ܡ󻣋σ; [B2, B3, V6]; xn--vkj.xn--4xa73ob5892c; ; ; # ⴄ.ܡσ
+xn--vkj.xn--4xa73o3t5ajq467a; ⴄ.‍ܡ󻣋σ; [B1, C2, V6]; xn--vkj.xn--4xa73o3t5ajq467a; ; ; # ⴄ.ܡσ
+xn--cnd.xn--4xa73ob5892c; Ⴄ.ܡ󻣋σ; [B2, B3, V6]; xn--cnd.xn--4xa73ob5892c; ; ; # Ⴄ.ܡσ
+xn--cnd.xn--4xa73o3t5ajq467a; Ⴄ.‍ܡ󻣋σ; [B1, C2, V6]; xn--cnd.xn--4xa73o3t5ajq467a; ; ; # Ⴄ.ܡσ
+xn--vkj.xn--3xa93o3t5ajq467a; ⴄ.‍ܡ󻣋ς; [B1, C2, V6]; xn--vkj.xn--3xa93o3t5ajq467a; ; ; # ⴄ.ܡς
+xn--cnd.xn--3xa93o3t5ajq467a; Ⴄ.‍ܡ󻣋ς; [B1, C2, V6]; xn--cnd.xn--3xa93o3t5ajq467a; ; ; # Ⴄ.ܡς
+ⴄ.‍ܡ󻣋ς; ⴄ.‍ܡ󻣋ς; [B1, C2, P1, V6]; xn--vkj.xn--3xa93o3t5ajq467a; ; xn--vkj.xn--4xa73ob5892c; [B2, B3, P1, V6] # ⴄ.ܡς
+Ⴄ.‍ܡ󻣋Σ; Ⴄ.‍ܡ󻣋σ; [B1, C2, P1, V6]; xn--cnd.xn--4xa73o3t5ajq467a; ; xn--cnd.xn--4xa73ob5892c; [B2, B3, P1, V6] # Ⴄ.ܡσ
+ⴄ.‍ܡ󻣋σ; ⴄ.‍ܡ󻣋σ; [B1, C2, P1, V6]; xn--vkj.xn--4xa73o3t5ajq467a; ; xn--vkj.xn--4xa73ob5892c; [B2, B3, P1, V6] # ⴄ.ܡσ
+򮵛ؓ.Ⴕ; ; [P1, V6]; xn--1fb94204l.xn--tnd; ; ; # ؓ.Ⴕ
+򮵛ؓ.ⴕ; ; [P1, V6]; xn--1fb94204l.xn--dlj; ; ; # ؓ.ⴕ
+xn--1fb94204l.xn--dlj; 򮵛ؓ.ⴕ; [V6]; xn--1fb94204l.xn--dlj; ; ; # ؓ.ⴕ
+xn--1fb94204l.xn--tnd; 򮵛ؓ.Ⴕ; [V6]; xn--1fb94204l.xn--tnd; ; ; # ؓ.Ⴕ
+≯ᷳ𞤥。‌꣄󠪉‍; ≯ᷳ𞤥.‌꣄󠪉‍; [B1, C1, C2, P1, V6]; xn--ofg13qyr21c.xn--0ugc0116hix29k; ; xn--ofg13qyr21c.xn--0f9au6706d; [B1, P1, V5, V6] # ≯ᷳ𞤥.꣄
+≯ᷳ𞤥。‌꣄󠪉‍; ≯ᷳ𞤥.‌꣄󠪉‍; [B1, C1, C2, P1, V6]; xn--ofg13qyr21c.xn--0ugc0116hix29k; ; xn--ofg13qyr21c.xn--0f9au6706d; [B1, P1, V5, V6] # ≯ᷳ𞤥.꣄
+≯ᷳ𞤃。‌꣄󠪉‍; ≯ᷳ𞤥.‌꣄󠪉‍; [B1, C1, C2, P1, V6]; xn--ofg13qyr21c.xn--0ugc0116hix29k; ; xn--ofg13qyr21c.xn--0f9au6706d; [B1, P1, V5, V6] # ≯ᷳ𞤥.꣄
+≯ᷳ𞤃。‌꣄󠪉‍; ≯ᷳ𞤥.‌꣄󠪉‍; [B1, C1, C2, P1, V6]; xn--ofg13qyr21c.xn--0ugc0116hix29k; ; xn--ofg13qyr21c.xn--0f9au6706d; [B1, P1, V5, V6] # ≯ᷳ𞤥.꣄
+xn--ofg13qyr21c.xn--0f9au6706d; ≯ᷳ𞤥.꣄󠪉; [B1, V5, V6]; xn--ofg13qyr21c.xn--0f9au6706d; ; ; # ≯ᷳ𞤥.꣄
+xn--ofg13qyr21c.xn--0ugc0116hix29k; ≯ᷳ𞤥.‌꣄󠪉‍; [B1, C1, C2, V6]; xn--ofg13qyr21c.xn--0ugc0116hix29k; ; ; # ≯ᷳ𞤥.꣄
+‌󠄷。򒑁; ‌.򒑁; [C1, P1, V6]; xn--0ug.xn--w720c; ; .xn--w720c; [P1, V6, A4_2] # .
+‌󠄷。򒑁; ‌.򒑁; [C1, P1, V6]; xn--0ug.xn--w720c; ; .xn--w720c; [P1, V6, A4_2] # .
+.xn--w720c; .򒑁; [V6, X4_2]; .xn--w720c; [V6, A4_2]; ; # .
+xn--0ug.xn--w720c; ‌.򒑁; [C1, V6]; xn--0ug.xn--w720c; ; ; # .
+⒈ූ焅.󗡙‍ꡟ; ; [C2, P1, V6]; xn--t1c337io97c.xn--1ugz184c9lw7i; ; xn--t1c337io97c.xn--4c9a21133d; [P1, V6] # ⒈ූ焅.ꡟ
+1.ූ焅.󗡙‍ꡟ; ; [C2, P1, V5, V6]; 1.xn--t1c6981c.xn--1ugz184c9lw7i; ; 1.xn--t1c6981c.xn--4c9a21133d; [P1, V5, V6] # 1.ූ焅.ꡟ
+1.xn--t1c6981c.xn--4c9a21133d; 1.ූ焅.󗡙ꡟ; [V5, V6]; 1.xn--t1c6981c.xn--4c9a21133d; ; ; # 1.ූ焅.ꡟ
+1.xn--t1c6981c.xn--1ugz184c9lw7i; 1.ූ焅.󗡙‍ꡟ; [C2, V5, V6]; 1.xn--t1c6981c.xn--1ugz184c9lw7i; ; ; # 1.ූ焅.ꡟ
+xn--t1c337io97c.xn--4c9a21133d; ⒈ූ焅.󗡙ꡟ; [V6]; xn--t1c337io97c.xn--4c9a21133d; ; ; # ⒈ූ焅.ꡟ
+xn--t1c337io97c.xn--1ugz184c9lw7i; ⒈ූ焅.󗡙‍ꡟ; [C2, V6]; xn--t1c337io97c.xn--1ugz184c9lw7i; ; ; # ⒈ූ焅.ꡟ
+᷍ς≮.ς𝪦𞤕0; ᷍ς≮.ς𝪦𞤷0; [B1, B5, P1, V5, V6]; xn--3xa744kvid.xn--0-xmb85727aggma; ; xn--4xa544kvid.xn--0-zmb55727aggma; # ᷍ς≮.ς𝪦𞤷0
+᷍ς≮.ς𝪦𞤕0; ᷍ς≮.ς𝪦𞤷0; [B1, B5, P1, V5, V6]; xn--3xa744kvid.xn--0-xmb85727aggma; ; xn--4xa544kvid.xn--0-zmb55727aggma; # ᷍ς≮.ς𝪦𞤷0
+᷍ς≮.ς𝪦𞤷0; ᷍ς≮.ς𝪦𞤷0; [B1, B5, P1, V5, V6]; xn--3xa744kvid.xn--0-xmb85727aggma; ; xn--4xa544kvid.xn--0-zmb55727aggma; # ᷍ς≮.ς𝪦𞤷0
+᷍ς≮.ς𝪦𞤷0; ; [B1, B5, P1, V5, V6]; xn--3xa744kvid.xn--0-xmb85727aggma; ; xn--4xa544kvid.xn--0-zmb55727aggma; # ᷍ς≮.ς𝪦𞤷0
+᷍Σ≮.Σ𝪦𞤕0; ᷍σ≮.σ𝪦𞤷0; [B1, B5, P1, V5, V6]; xn--4xa544kvid.xn--0-zmb55727aggma; ; ; # ᷍σ≮.σ𝪦𞤷0
+᷍Σ≮.Σ𝪦𞤕0; ᷍σ≮.σ𝪦𞤷0; [B1, B5, P1, V5, V6]; xn--4xa544kvid.xn--0-zmb55727aggma; ; ; # ᷍σ≮.σ𝪦𞤷0
+᷍σ≮.σ𝪦𞤷0; ᷍σ≮.σ𝪦𞤷0; [B1, B5, P1, V5, V6]; xn--4xa544kvid.xn--0-zmb55727aggma; ; ; # ᷍σ≮.σ𝪦𞤷0
+᷍σ≮.σ𝪦𞤷0; ; [B1, B5, P1, V5, V6]; xn--4xa544kvid.xn--0-zmb55727aggma; ; ; # ᷍σ≮.σ𝪦𞤷0
+᷍Σ≮.Σ𝪦𞤷0; ᷍σ≮.σ𝪦𞤷0; [B1, B5, P1, V5, V6]; xn--4xa544kvid.xn--0-zmb55727aggma; ; ; # ᷍σ≮.σ𝪦𞤷0
+᷍Σ≮.Σ𝪦𞤷0; ᷍σ≮.σ𝪦𞤷0; [B1, B5, P1, V5, V6]; xn--4xa544kvid.xn--0-zmb55727aggma; ; ; # ᷍σ≮.σ𝪦𞤷0
+xn--4xa544kvid.xn--0-zmb55727aggma; ᷍σ≮.σ𝪦𞤷0; [B1, B5, V5, V6]; xn--4xa544kvid.xn--0-zmb55727aggma; ; ; # ᷍σ≮.σ𝪦𞤷0
+xn--3xa744kvid.xn--0-xmb85727aggma; ᷍ς≮.ς𝪦𞤷0; [B1, B5, V5, V6]; xn--3xa744kvid.xn--0-xmb85727aggma; ; ; # ᷍ς≮.ς𝪦𞤷0
+᷍σ≮.σ𝪦𞤕0; ᷍σ≮.σ𝪦𞤷0; [B1, B5, P1, V5, V6]; xn--4xa544kvid.xn--0-zmb55727aggma; ; ; # ᷍σ≮.σ𝪦𞤷0
+᷍σ≮.σ𝪦𞤕0; ᷍σ≮.σ𝪦𞤷0; [B1, B5, P1, V5, V6]; xn--4xa544kvid.xn--0-zmb55727aggma; ; ; # ᷍σ≮.σ𝪦𞤷0
+򢦾ßֹ𐫙.֭ࢡ; ; [B1, B5, B6, P1, V5, V6]; xn--zca89v339zj118e.xn--4cb62m; ; xn--ss-xjd6058xlz50g.xn--4cb62m; # ßֹ𐫙.֭ࢡ
+򢦾SSֹ𐫙.֭ࢡ; 򢦾ssֹ𐫙.֭ࢡ; [B1, B5, B6, P1, V5, V6]; xn--ss-xjd6058xlz50g.xn--4cb62m; ; ; # ssֹ𐫙.֭ࢡ
+򢦾ssֹ𐫙.֭ࢡ; ; [B1, B5, B6, P1, V5, V6]; xn--ss-xjd6058xlz50g.xn--4cb62m; ; ; # ssֹ𐫙.֭ࢡ
+򢦾Ssֹ𐫙.֭ࢡ; 򢦾ssֹ𐫙.֭ࢡ; [B1, B5, B6, P1, V5, V6]; xn--ss-xjd6058xlz50g.xn--4cb62m; ; ; # ssֹ𐫙.֭ࢡ
+xn--ss-xjd6058xlz50g.xn--4cb62m; 򢦾ssֹ𐫙.֭ࢡ; [B1, B5, B6, V5, V6]; xn--ss-xjd6058xlz50g.xn--4cb62m; ; ; # ssֹ𐫙.֭ࢡ
+xn--zca89v339zj118e.xn--4cb62m; 򢦾ßֹ𐫙.֭ࢡ; [B1, B5, B6, V5, V6]; xn--zca89v339zj118e.xn--4cb62m; ; ; # ßֹ𐫙.֭ࢡ
+-𞣄。⒈; -𞣄.⒈; [B1, P1, V3, V6]; xn----xc8r.xn--tsh; ; ; # -𞣄.⒈
+-𞣄。1.; -𞣄.1.; [B1, V3]; xn----xc8r.1.; ; ; # -𞣄.1.
+xn----xc8r.1.; -𞣄.1.; [B1, V3]; xn----xc8r.1.; ; ; # -𞣄.1.
+xn----xc8r.xn--tsh; -𞣄.⒈; [B1, V3, V6]; xn----xc8r.xn--tsh; ; ; # -𞣄.⒈
+񈠢𐫖𝟡。ؾ𑘿; 񈠢𐫖9.ؾ𑘿; [B5, P1, V6]; xn--9-el5iv442t.xn--9gb0830l; ; ; # 𐫖9.ؾ𑘿
+񈠢𐫖9。ؾ𑘿; 񈠢𐫖9.ؾ𑘿; [B5, P1, V6]; xn--9-el5iv442t.xn--9gb0830l; ; ; # 𐫖9.ؾ𑘿
+xn--9-el5iv442t.xn--9gb0830l; 񈠢𐫖9.ؾ𑘿; [B5, V6]; xn--9-el5iv442t.xn--9gb0830l; ; ; # 𐫖9.ؾ𑘿
+٨ﲌ٨ᩝ.‍; ٨نم٨ᩝ.‍; [B1, C2]; xn--hhbb5hc956w.xn--1ug; ; xn--hhbb5hc956w.; [B1] # ٨نم٨ᩝ.
+٨نم٨ᩝ.‍; ; [B1, C2]; xn--hhbb5hc956w.xn--1ug; ; xn--hhbb5hc956w.; [B1] # ٨نم٨ᩝ.
+xn--hhbb5hc956w.; ٨نم٨ᩝ.; [B1]; xn--hhbb5hc956w.; ; ; # ٨نم٨ᩝ.
+xn--hhbb5hc956w.xn--1ug; ٨نم٨ᩝ.‍; [B1, C2]; xn--hhbb5hc956w.xn--1ug; ; ; # ٨نم٨ᩝ.
+𝟘.Ⴇ󀳑ﵐ񫃱; 0.Ⴇ󀳑تجم񫃱; [B1, B5, P1, V6]; 0.xn--pgbe9e344c2725svff8b; ; ; # 0.Ⴇتجم
+0.Ⴇ󀳑تجم񫃱; ; [B1, B5, P1, V6]; 0.xn--pgbe9e344c2725svff8b; ; ; # 0.Ⴇتجم
+0.ⴇ󀳑تجم񫃱; ; [B1, B5, P1, V6]; 0.xn--pgbe9ez79qd207lvff8b; ; ; # 0.ⴇتجم
+0.xn--pgbe9ez79qd207lvff8b; 0.ⴇ󀳑تجم񫃱; [B1, B5, V6]; 0.xn--pgbe9ez79qd207lvff8b; ; ; # 0.ⴇتجم
+0.xn--pgbe9e344c2725svff8b; 0.Ⴇ󀳑تجم񫃱; [B1, B5, V6]; 0.xn--pgbe9e344c2725svff8b; ; ; # 0.Ⴇتجم
+𝟘.ⴇ󀳑ﵐ񫃱; 0.ⴇ󀳑تجم񫃱; [B1, B5, P1, V6]; 0.xn--pgbe9ez79qd207lvff8b; ; ; # 0.ⴇتجم
+𑇀▍.⁞ᠰ; ; [V5]; xn--9zh3057f.xn--j7e103b; ; ; # 𑇀▍.⁞ᠰ
+xn--9zh3057f.xn--j7e103b; 𑇀▍.⁞ᠰ; [V5]; xn--9zh3057f.xn--j7e103b; ; ; # 𑇀▍.⁞ᠰ
+‍-ٺ.򏯩; ; [B1, C2, P1, V6]; xn----qrc357q.xn--ts49b; ; xn----qrc.xn--ts49b; [B1, P1, V3, V6] # -ٺ.
+xn----qrc.xn--ts49b; -ٺ.򏯩; [B1, V3, V6]; xn----qrc.xn--ts49b; ; ; # -ٺ.
+xn----qrc357q.xn--ts49b; ‍-ٺ.򏯩; [B1, C2, V6]; xn----qrc357q.xn--ts49b; ; ; # -ٺ.
+ᠢ𐮂𐫘寐。‌≯✳; ᠢ𐮂𐫘寐.‌≯✳; [B1, B5, C1, P1, V6]; xn--46e6675axzzhota.xn--0ug06gu8f; ; xn--46e6675axzzhota.xn--hdh99p; [B1, B5, P1, V6] # ᠢ𐮂𐫘寐.≯✳
+ᠢ𐮂𐫘寐。‌≯✳; ᠢ𐮂𐫘寐.‌≯✳; [B1, B5, C1, P1, V6]; xn--46e6675axzzhota.xn--0ug06gu8f; ; xn--46e6675axzzhota.xn--hdh99p; [B1, B5, P1, V6] # ᠢ𐮂𐫘寐.≯✳
+ᠢ𐮂𐫘寐。‌≯✳; ᠢ𐮂𐫘寐.‌≯✳; [B1, B5, C1, P1, V6]; xn--46e6675axzzhota.xn--0ug06gu8f; ; xn--46e6675axzzhota.xn--hdh99p; [B1, B5, P1, V6] # ᠢ𐮂𐫘寐.≯✳
+ᠢ𐮂𐫘寐。‌≯✳; ᠢ𐮂𐫘寐.‌≯✳; [B1, B5, C1, P1, V6]; xn--46e6675axzzhota.xn--0ug06gu8f; ; xn--46e6675axzzhota.xn--hdh99p; [B1, B5, P1, V6] # ᠢ𐮂𐫘寐.≯✳
+xn--46e6675axzzhota.xn--hdh99p; ᠢ𐮂𐫘寐.≯✳; [B1, B5, V6]; xn--46e6675axzzhota.xn--hdh99p; ; ; # ᠢ𐮂𐫘寐.≯✳
+xn--46e6675axzzhota.xn--0ug06gu8f; ᠢ𐮂𐫘寐.‌≯✳; [B1, B5, C1, V6]; xn--46e6675axzzhota.xn--0ug06gu8f; ; ; # ᠢ𐮂𐫘寐.≯✳
+‍。󸲜ႺႴ𞨇; ‍.󸲜ႺႴ𞨇; [B1, B5, B6, C2, P1, V6]; xn--1ug.xn--sndl01647an3h1h; ; .xn--sndl01647an3h1h; [B5, B6, P1, V6, A4_2] # .ႺႴ
+‍。󸲜ႺႴ𞨇; ‍.󸲜ႺႴ𞨇; [B1, B5, B6, C2, P1, V6]; xn--1ug.xn--sndl01647an3h1h; ; .xn--sndl01647an3h1h; [B5, B6, P1, V6, A4_2] # .ႺႴ
+‍。󸲜ⴚⴔ𞨇; ‍.󸲜ⴚⴔ𞨇; [B1, B5, B6, C2, P1, V6]; xn--1ug.xn--cljl81825an3r4h; ; .xn--cljl81825an3r4h; [B5, B6, P1, V6, A4_2] # .ⴚⴔ
+‍。󸲜Ⴚⴔ𞨇; ‍.󸲜Ⴚⴔ𞨇; [B1, B5, B6, C2, P1, V6]; xn--1ug.xn--ynd036lq981an3r4h; ; .xn--ynd036lq981an3r4h; [B5, B6, P1, V6, A4_2] # .Ⴚⴔ
+.xn--ynd036lq981an3r4h; .󸲜Ⴚⴔ𞨇; [B5, B6, V6, X4_2]; .xn--ynd036lq981an3r4h; [B5, B6, V6, A4_2]; ; # .Ⴚⴔ
+xn--1ug.xn--ynd036lq981an3r4h; ‍.󸲜Ⴚⴔ𞨇; [B1, B5, B6, C2, V6]; xn--1ug.xn--ynd036lq981an3r4h; ; ; # .Ⴚⴔ
+.xn--cljl81825an3r4h; .󸲜ⴚⴔ𞨇; [B5, B6, V6, X4_2]; .xn--cljl81825an3r4h; [B5, B6, V6, A4_2]; ; # .ⴚⴔ
+xn--1ug.xn--cljl81825an3r4h; ‍.󸲜ⴚⴔ𞨇; [B1, B5, B6, C2, V6]; xn--1ug.xn--cljl81825an3r4h; ; ; # .ⴚⴔ
+.xn--sndl01647an3h1h; .󸲜ႺႴ𞨇; [B5, B6, V6, X4_2]; .xn--sndl01647an3h1h; [B5, B6, V6, A4_2]; ; # .ႺႴ
+xn--1ug.xn--sndl01647an3h1h; ‍.󸲜ႺႴ𞨇; [B1, B5, B6, C2, V6]; xn--1ug.xn--sndl01647an3h1h; ; ; # .ႺႴ
+‍。󸲜ⴚⴔ𞨇; ‍.󸲜ⴚⴔ𞨇; [B1, B5, B6, C2, P1, V6]; xn--1ug.xn--cljl81825an3r4h; ; .xn--cljl81825an3r4h; [B5, B6, P1, V6, A4_2] # .ⴚⴔ
+‍。󸲜Ⴚⴔ𞨇; ‍.󸲜Ⴚⴔ𞨇; [B1, B5, B6, C2, P1, V6]; xn--1ug.xn--ynd036lq981an3r4h; ; .xn--ynd036lq981an3r4h; [B5, B6, P1, V6, A4_2] # .Ⴚⴔ
+-3.‍ヌᢕ; ; [C2, V3]; -3.xn--fbf739aq5o; ; -3.xn--fbf115j; [V3] # -3.ヌᢕ
+-3.xn--fbf115j; -3.ヌᢕ; [V3]; -3.xn--fbf115j; ; ; # -3.ヌᢕ
+-3.xn--fbf739aq5o; -3.‍ヌᢕ; [C2, V3]; -3.xn--fbf739aq5o; ; ; # -3.ヌᢕ
+🂃٦ß‍。󠠂򭰍𞩒-; 🂃٦ß‍.󠠂򭰍𞩒-; [B1, C2, P1, V3, V6]; xn--zca34z68yzu83b.xn----nz8rh7531csznt; ; xn--ss-pyd98921c.xn----nz8rh7531csznt; [B1, P1, V3, V6] # 🂃٦ß.-
+🂃٦SS‍。󠠂򭰍𞩒-; 🂃٦ss‍.󠠂򭰍𞩒-; [B1, C2, P1, V3, V6]; xn--ss-pyd483x5k99b.xn----nz8rh7531csznt; ; xn--ss-pyd98921c.xn----nz8rh7531csznt; [B1, P1, V3, V6] # 🂃٦ss.-
+🂃٦ss‍。󠠂򭰍𞩒-; 🂃٦ss‍.󠠂򭰍𞩒-; [B1, C2, P1, V3, V6]; xn--ss-pyd483x5k99b.xn----nz8rh7531csznt; ; xn--ss-pyd98921c.xn----nz8rh7531csznt; [B1, P1, V3, V6] # 🂃٦ss.-
+xn--ss-pyd98921c.xn----nz8rh7531csznt; 🂃٦ss.󠠂򭰍𞩒-; [B1, V3, V6]; xn--ss-pyd98921c.xn----nz8rh7531csznt; ; ; # 🂃٦ss.-
+xn--ss-pyd483x5k99b.xn----nz8rh7531csznt; 🂃٦ss‍.󠠂򭰍𞩒-; [B1, C2, V3, V6]; xn--ss-pyd483x5k99b.xn----nz8rh7531csznt; ; ; # 🂃٦ss.-
+xn--zca34z68yzu83b.xn----nz8rh7531csznt; 🂃٦ß‍.󠠂򭰍𞩒-; [B1, C2, V3, V6]; xn--zca34z68yzu83b.xn----nz8rh7531csznt; ; ; # 🂃٦ß.-
+🂃٦Ss‍。󠠂򭰍𞩒-; 🂃٦ss‍.󠠂򭰍𞩒-; [B1, C2, P1, V3, V6]; xn--ss-pyd483x5k99b.xn----nz8rh7531csznt; ; xn--ss-pyd98921c.xn----nz8rh7531csznt; [B1, P1, V3, V6] # 🂃٦ss.-
+ꇟ-𐾺ڟ。򰀺‌; ꇟ-𐾺ڟ.򰀺‌; [B5, B6, C1, P1, V6]; xn----utc4430jd3zd.xn--0ugx6670i; ; xn----utc4430jd3zd.xn--bp20d; [B5, B6, P1, V6] # ꇟ-𐾺ڟ.
+xn----utc4430jd3zd.xn--bp20d; ꇟ-𐾺ڟ.򰀺; [B5, B6, V6]; xn----utc4430jd3zd.xn--bp20d; ; ; # ꇟ-𐾺ڟ.
+xn----utc4430jd3zd.xn--0ugx6670i; ꇟ-𐾺ڟ.򰀺‌; [B5, B6, C1, V6]; xn----utc4430jd3zd.xn--0ugx6670i; ; ; # ꇟ-𐾺ڟ.
+٥.҄𐨗𝩋𴤃; ; [B1, P1, V5, V6]; xn--eib.xn--n3a0405kus8eft5l; ; ; # ٥.҄𐨗𝩋
+xn--eib.xn--n3a0405kus8eft5l; ٥.҄𐨗𝩋𴤃; [B1, V5, V6]; xn--eib.xn--n3a0405kus8eft5l; ; ; # ٥.҄𐨗𝩋
+-.񱼓ى𐨿; ; [B1, B5, B6, P1, V3, V6]; -.xn--lhb4124khbq4b; ; ; # -.ى𐨿
+-.xn--lhb4124khbq4b; -.񱼓ى𐨿; [B1, B5, B6, V3, V6]; -.xn--lhb4124khbq4b; ; ; # -.ى𐨿
+󾬨ς.𞶙녫ß; ; [B2, B3, P1, V6]; xn--3xa96659r.xn--zca5051g4h4i; ; xn--4xa76659r.xn--ss-d64i8755h; # ς.녫ß
+󾬨ς.𞶙녫ß; 󾬨ς.𞶙녫ß; [B2, B3, P1, V6]; xn--3xa96659r.xn--zca5051g4h4i; ; xn--4xa76659r.xn--ss-d64i8755h; # ς.녫ß
+󾬨Σ.𞶙녫SS; 󾬨σ.𞶙녫ss; [B2, B3, P1, V6]; xn--4xa76659r.xn--ss-d64i8755h; ; ; # σ.녫ss
+󾬨Σ.𞶙녫SS; 󾬨σ.𞶙녫ss; [B2, B3, P1, V6]; xn--4xa76659r.xn--ss-d64i8755h; ; ; # σ.녫ss
+󾬨σ.𞶙녫ss; ; [B2, B3, P1, V6]; xn--4xa76659r.xn--ss-d64i8755h; ; ; # σ.녫ss
+󾬨σ.𞶙녫ss; 󾬨σ.𞶙녫ss; [B2, B3, P1, V6]; xn--4xa76659r.xn--ss-d64i8755h; ; ; # σ.녫ss
+󾬨Σ.𞶙녫ss; 󾬨σ.𞶙녫ss; [B2, B3, P1, V6]; xn--4xa76659r.xn--ss-d64i8755h; ; ; # σ.녫ss
+󾬨Σ.𞶙녫ss; 󾬨σ.𞶙녫ss; [B2, B3, P1, V6]; xn--4xa76659r.xn--ss-d64i8755h; ; ; # σ.녫ss
+󾬨Σ.𞶙녫Ss; 󾬨σ.𞶙녫ss; [B2, B3, P1, V6]; xn--4xa76659r.xn--ss-d64i8755h; ; ; # σ.녫ss
+󾬨Σ.𞶙녫Ss; 󾬨σ.𞶙녫ss; [B2, B3, P1, V6]; xn--4xa76659r.xn--ss-d64i8755h; ; ; # σ.녫ss
+xn--4xa76659r.xn--ss-d64i8755h; 󾬨σ.𞶙녫ss; [B2, B3, V6]; xn--4xa76659r.xn--ss-d64i8755h; ; ; # σ.녫ss
+󾬨Σ.𞶙녫ß; 󾬨σ.𞶙녫ß; [B2, B3, P1, V6]; xn--4xa76659r.xn--zca5051g4h4i; ; xn--4xa76659r.xn--ss-d64i8755h; # σ.녫ß
+󾬨Σ.𞶙녫ß; 󾬨σ.𞶙녫ß; [B2, B3, P1, V6]; xn--4xa76659r.xn--zca5051g4h4i; ; xn--4xa76659r.xn--ss-d64i8755h; # σ.녫ß
+󾬨σ.𞶙녫ß; ; [B2, B3, P1, V6]; xn--4xa76659r.xn--zca5051g4h4i; ; xn--4xa76659r.xn--ss-d64i8755h; # σ.녫ß
+󾬨σ.𞶙녫ß; 󾬨σ.𞶙녫ß; [B2, B3, P1, V6]; xn--4xa76659r.xn--zca5051g4h4i; ; xn--4xa76659r.xn--ss-d64i8755h; # σ.녫ß
+xn--4xa76659r.xn--zca5051g4h4i; 󾬨σ.𞶙녫ß; [B2, B3, V6]; xn--4xa76659r.xn--zca5051g4h4i; ; ; # σ.녫ß
+xn--3xa96659r.xn--zca5051g4h4i; 󾬨ς.𞶙녫ß; [B2, B3, V6]; xn--3xa96659r.xn--zca5051g4h4i; ; ; # ς.녫ß
+Ⅎ្‍。≠‍‌; Ⅎ្‍.≠‍‌; [C1, C2, P1, V6]; xn--u4e823bcza.xn--0ugb89o; ; xn--u4e319b.xn--1ch; [P1, V6] # Ⅎ្.≠
+Ⅎ្‍。≠‍‌; Ⅎ្‍.≠‍‌; [C1, C2, P1, V6]; xn--u4e823bcza.xn--0ugb89o; ; xn--u4e319b.xn--1ch; [P1, V6] # Ⅎ្.≠
+Ⅎ្‍。≠‍‌; Ⅎ្‍.≠‍‌; [C1, C2, P1, V6]; xn--u4e823bcza.xn--0ugb89o; ; xn--u4e319b.xn--1ch; [P1, V6] # Ⅎ្.≠
+Ⅎ្‍。≠‍‌; Ⅎ្‍.≠‍‌; [C1, C2, P1, V6]; xn--u4e823bcza.xn--0ugb89o; ; xn--u4e319b.xn--1ch; [P1, V6] # Ⅎ្.≠
+ⅎ្‍。≠‍‌; ⅎ្‍.≠‍‌; [C1, C2, P1, V6]; xn--u4e823bq1a.xn--0ugb89o; ; xn--u4e969b.xn--1ch; [P1, V6] # ⅎ្.≠
+ⅎ្‍。≠‍‌; ⅎ្‍.≠‍‌; [C1, C2, P1, V6]; xn--u4e823bq1a.xn--0ugb89o; ; xn--u4e969b.xn--1ch; [P1, V6] # ⅎ្.≠
+xn--u4e969b.xn--1ch; ⅎ្.≠; [V6]; xn--u4e969b.xn--1ch; ; ; # ⅎ្.≠
+xn--u4e823bq1a.xn--0ugb89o; ⅎ្‍.≠‍‌; [C1, C2, V6]; xn--u4e823bq1a.xn--0ugb89o; ; ; # ⅎ្.≠
+xn--u4e319b.xn--1ch; Ⅎ្.≠; [V6]; xn--u4e319b.xn--1ch; ; ; # Ⅎ្.≠
+xn--u4e823bcza.xn--0ugb89o; Ⅎ្‍.≠‍‌; [C1, C2, V6]; xn--u4e823bcza.xn--0ugb89o; ; ; # Ⅎ្.≠
+ⅎ្‍。≠‍‌; ⅎ្‍.≠‍‌; [C1, C2, P1, V6]; xn--u4e823bq1a.xn--0ugb89o; ; xn--u4e969b.xn--1ch; [P1, V6] # ⅎ្.≠
+ⅎ្‍。≠‍‌; ⅎ្‍.≠‍‌; [C1, C2, P1, V6]; xn--u4e823bq1a.xn--0ugb89o; ; xn--u4e969b.xn--1ch; [P1, V6] # ⅎ្.≠
+𐋺꫶꥓󧦉.‌᜔ڏ; 𐋺꫶꥓󧦉.‌᜔ڏ; [B1, C1, P1, V6]; xn--3j9a14ak27osbz2o.xn--ljb175f1wg; ; xn--3j9a14ak27osbz2o.xn--ljb175f; [B1, P1, V5, V6] # 𐋺꫶꥓.᜔ڏ
+𐋺꫶꥓󧦉.‌᜔ڏ; ; [B1, C1, P1, V6]; xn--3j9a14ak27osbz2o.xn--ljb175f1wg; ; xn--3j9a14ak27osbz2o.xn--ljb175f; [B1, P1, V5, V6] # 𐋺꫶꥓.᜔ڏ
+xn--3j9a14ak27osbz2o.xn--ljb175f; 𐋺꫶꥓󧦉.᜔ڏ; [B1, V5, V6]; xn--3j9a14ak27osbz2o.xn--ljb175f; ; ; # 𐋺꫶꥓.᜔ڏ
+xn--3j9a14ak27osbz2o.xn--ljb175f1wg; 𐋺꫶꥓󧦉.‌᜔ڏ; [B1, C1, V6]; xn--3j9a14ak27osbz2o.xn--ljb175f1wg; ; ; # 𐋺꫶꥓.᜔ڏ
+񺔯ྨ.≯; 񺔯ྨ.≯; [P1, V6]; xn--4fd57150h.xn--hdh; ; ; # ྨ.≯
+񺔯ྨ.≯; 񺔯ྨ.≯; [P1, V6]; xn--4fd57150h.xn--hdh; ; ; # ྨ.≯
+񺔯ྨ.≯; ; [P1, V6]; xn--4fd57150h.xn--hdh; ; ; # ྨ.≯
+񺔯ྨ.≯; 񺔯ྨ.≯; [P1, V6]; xn--4fd57150h.xn--hdh; ; ; # ྨ.≯
+xn--4fd57150h.xn--hdh; 񺔯ྨ.≯; [V6]; xn--4fd57150h.xn--hdh; ; ; # ྨ.≯
+‍𞡄Ⴓ.𐇽; ‍𞡄Ⴓ.𐇽; [B1, B3, B6, C2, P1, V5, V6]; xn--rnd379ex885a.xn--m27c; ; xn--rnd5552v.xn--m27c; [B1, B2, B3, B6, P1, V5, V6] # 𞡄Ⴓ.𐇽
+‍𞡄Ⴓ.𐇽; ; [B1, B3, B6, C2, P1, V5, V6]; xn--rnd379ex885a.xn--m27c; ; xn--rnd5552v.xn--m27c; [B1, B2, B3, B6, P1, V5, V6] # 𞡄Ⴓ.𐇽
+‍𞡄ⴓ.𐇽; ; [B1, B3, B6, C2, V5]; xn--1ugz52c4i16a.xn--m27c; ; xn--blj7492l.xn--m27c; [B1, B2, B3, B6, V5] # 𞡄ⴓ.𐇽
+xn--blj7492l.xn--m27c; 𞡄ⴓ.𐇽; [B1, B2, B3, B6, V5]; xn--blj7492l.xn--m27c; ; ; # 𞡄ⴓ.𐇽
+xn--1ugz52c4i16a.xn--m27c; ‍𞡄ⴓ.𐇽; [B1, B3, B6, C2, V5]; xn--1ugz52c4i16a.xn--m27c; ; ; # 𞡄ⴓ.𐇽
+xn--rnd5552v.xn--m27c; 𞡄Ⴓ.𐇽; [B1, B2, B3, B6, V5, V6]; xn--rnd5552v.xn--m27c; ; ; # 𞡄Ⴓ.𐇽
+xn--rnd379ex885a.xn--m27c; ‍𞡄Ⴓ.𐇽; [B1, B3, B6, C2, V5, V6]; xn--rnd379ex885a.xn--m27c; ; ; # 𞡄Ⴓ.𐇽
+‍𞡄ⴓ.𐇽; ‍𞡄ⴓ.𐇽; [B1, B3, B6, C2, V5]; xn--1ugz52c4i16a.xn--m27c; ; xn--blj7492l.xn--m27c; [B1, B2, B3, B6, V5] # 𞡄ⴓ.𐇽
+𐪒ß꣪.ᡤ; 𐪒ß꣪.ᡤ; [B2, B3]; xn--zca2517f2hvc.xn--08e; ; xn--ss-tu9hw933a.xn--08e; # 𐪒ß꣪.ᡤ
+𐪒ß꣪.ᡤ; ; [B2, B3]; xn--zca2517f2hvc.xn--08e; ; xn--ss-tu9hw933a.xn--08e; # 𐪒ß꣪.ᡤ
+𐪒SS꣪.ᡤ; 𐪒ss꣪.ᡤ; [B2, B3]; xn--ss-tu9hw933a.xn--08e; ; ; # 𐪒ss꣪.ᡤ
+𐪒ss꣪.ᡤ; ; [B2, B3]; xn--ss-tu9hw933a.xn--08e; ; ; # 𐪒ss꣪.ᡤ
+xn--ss-tu9hw933a.xn--08e; 𐪒ss꣪.ᡤ; [B2, B3]; xn--ss-tu9hw933a.xn--08e; ; ; # 𐪒ss꣪.ᡤ
+xn--zca2517f2hvc.xn--08e; 𐪒ß꣪.ᡤ; [B2, B3]; xn--zca2517f2hvc.xn--08e; ; ; # 𐪒ß꣪.ᡤ
+𐪒SS꣪.ᡤ; 𐪒ss꣪.ᡤ; [B2, B3]; xn--ss-tu9hw933a.xn--08e; ; ; # 𐪒ss꣪.ᡤ
+𐪒ss꣪.ᡤ; 𐪒ss꣪.ᡤ; [B2, B3]; xn--ss-tu9hw933a.xn--08e; ; ; # 𐪒ss꣪.ᡤ
+𐪒Ss꣪.ᡤ; 𐪒ss꣪.ᡤ; [B2, B3]; xn--ss-tu9hw933a.xn--08e; ; ; # 𐪒ss꣪.ᡤ
+𐪒Ss꣪.ᡤ; 𐪒ss꣪.ᡤ; [B2, B3]; xn--ss-tu9hw933a.xn--08e; ; ; # 𐪒ss꣪.ᡤ
+𐨿󠆌鸮𑚶.ς; 𐨿鸮𑚶.ς; [V5]; xn--l76a726rt2h.xn--3xa; ; xn--l76a726rt2h.xn--4xa; # 𐨿鸮𑚶.ς
+𐨿󠆌鸮𑚶.Σ; 𐨿鸮𑚶.σ; [V5]; xn--l76a726rt2h.xn--4xa; ; ; # 𐨿鸮𑚶.σ
+𐨿󠆌鸮𑚶.σ; 𐨿鸮𑚶.σ; [V5]; xn--l76a726rt2h.xn--4xa; ; ; # 𐨿鸮𑚶.σ
+xn--l76a726rt2h.xn--4xa; 𐨿鸮𑚶.σ; [V5]; xn--l76a726rt2h.xn--4xa; ; ; # 𐨿鸮𑚶.σ
+xn--l76a726rt2h.xn--3xa; 𐨿鸮𑚶.ς; [V5]; xn--l76a726rt2h.xn--3xa; ; ; # 𐨿鸮𑚶.ς
+⒗𞤬。-𑚶; ⒗𞤬.-𑚶; [B1, P1, V3, V6]; xn--8shw466n.xn----4j0j; ; ; # ⒗𞤬.-𑚶
+16.𞤬。-𑚶; 16.𞤬.-𑚶; [B1, V3]; 16.xn--ke6h.xn----4j0j; ; ; # 16.𞤬.-𑚶
+16.𞤊。-𑚶; 16.𞤬.-𑚶; [B1, V3]; 16.xn--ke6h.xn----4j0j; ; ; # 16.𞤬.-𑚶
+16.xn--ke6h.xn----4j0j; 16.𞤬.-𑚶; [B1, V3]; 16.xn--ke6h.xn----4j0j; ; ; # 16.𞤬.-𑚶
+⒗𞤊。-𑚶; ⒗𞤬.-𑚶; [B1, P1, V3, V6]; xn--8shw466n.xn----4j0j; ; ; # ⒗𞤬.-𑚶
+xn--8shw466n.xn----4j0j; ⒗𞤬.-𑚶; [B1, V3, V6]; xn--8shw466n.xn----4j0j; ; ; # ⒗𞤬.-𑚶
+ࢳ𞤿⾫。𐹣ڏ⒈; ࢳ𞤿隹.𐹣ڏ⒈; [B1, B2, B3, P1, V6]; xn--8yb0383efiwk.xn--ljb064mol4n; ; ; # ࢳ𞤿隹.𐹣ڏ⒈
+ࢳ𞤿隹。𐹣ڏ1.; ࢳ𞤿隹.𐹣ڏ1.; [B1, B2, B3]; xn--8yb0383efiwk.xn--1-wsc3373r.; ; ; # ࢳ𞤿隹.𐹣ڏ1.
+ࢳ𞤝隹。𐹣ڏ1.; ࢳ𞤿隹.𐹣ڏ1.; [B1, B2, B3]; xn--8yb0383efiwk.xn--1-wsc3373r.; ; ; # ࢳ𞤿隹.𐹣ڏ1.
+xn--8yb0383efiwk.xn--1-wsc3373r.; ࢳ𞤿隹.𐹣ڏ1.; [B1, B2, B3]; xn--8yb0383efiwk.xn--1-wsc3373r.; ; ; # ࢳ𞤿隹.𐹣ڏ1.
+ࢳ𞤝⾫。𐹣ڏ⒈; ࢳ𞤿隹.𐹣ڏ⒈; [B1, B2, B3, P1, V6]; xn--8yb0383efiwk.xn--ljb064mol4n; ; ; # ࢳ𞤿隹.𐹣ڏ⒈
+xn--8yb0383efiwk.xn--ljb064mol4n; ࢳ𞤿隹.𐹣ڏ⒈; [B1, B2, B3, V6]; xn--8yb0383efiwk.xn--ljb064mol4n; ; ; # ࢳ𞤿隹.𐹣ڏ⒈
+␳𚎛𝟧١.ᡢ8ི؀; ␳𚎛5١.ᡢ8ི؀; [B5, B6, P1, V6]; xn--5-bqc410un435a.xn--8-rkc763epjj; ; ; # 5١.ᡢ8ི
+␳𚎛5١.ᡢ8ི؀; ; [B5, B6, P1, V6]; xn--5-bqc410un435a.xn--8-rkc763epjj; ; ; # 5١.ᡢ8ི
+xn--5-bqc410un435a.xn--8-rkc763epjj; ␳𚎛5١.ᡢ8ི؀; [B5, B6, V6]; xn--5-bqc410un435a.xn--8-rkc763epjj; ; ; # 5١.ᡢ8ི
+𐹠.🄀⒒-󨰈; ; [B1, P1, V6]; xn--7n0d.xn----xcp9757q1s13g; ; ; # 𐹠.🄀⒒-
+𐹠.0.11.-󨰈; ; [B1, P1, V3, V6]; xn--7n0d.0.11.xn----8j07m; ; ; # 𐹠.0.11.-
+xn--7n0d.0.11.xn----8j07m; 𐹠.0.11.-󨰈; [B1, V3, V6]; xn--7n0d.0.11.xn----8j07m; ; ; # 𐹠.0.11.-
+xn--7n0d.xn----xcp9757q1s13g; 𐹠.🄀⒒-󨰈; [B1, V6]; xn--7n0d.xn----xcp9757q1s13g; ; ; # 𐹠.🄀⒒-
+ς-。‌𝟭-; ς-.‌1-; [C1, V3]; xn----xmb.xn--1--i1t; ; xn----zmb.1-; [V3] # ς-.1-
+ς-。‌1-; ς-.‌1-; [C1, V3]; xn----xmb.xn--1--i1t; ; xn----zmb.1-; [V3] # ς-.1-
+Σ-。‌1-; σ-.‌1-; [C1, V3]; xn----zmb.xn--1--i1t; ; xn----zmb.1-; [V3] # σ-.1-
+σ-。‌1-; σ-.‌1-; [C1, V3]; xn----zmb.xn--1--i1t; ; xn----zmb.1-; [V3] # σ-.1-
+xn----zmb.1-; σ-.1-; [V3]; xn----zmb.1-; ; ; # σ-.1-
+xn----zmb.xn--1--i1t; σ-.‌1-; [C1, V3]; xn----zmb.xn--1--i1t; ; ; # σ-.1-
+xn----xmb.xn--1--i1t; ς-.‌1-; [C1, V3]; xn----xmb.xn--1--i1t; ; ; # ς-.1-
+Σ-。‌𝟭-; σ-.‌1-; [C1, V3]; xn----zmb.xn--1--i1t; ; xn----zmb.1-; [V3] # σ-.1-
+σ-。‌𝟭-; σ-.‌1-; [C1, V3]; xn----zmb.xn--1--i1t; ; xn----zmb.1-; [V3] # σ-.1-
+᜴-ೢ.󠄩Ⴄ; ᜴-ೢ.Ⴄ; [P1, V5, V6]; xn----ggf830f.xn--cnd; ; ; # ᜴-ೢ.Ⴄ
+᜴-ೢ.󠄩Ⴄ; ᜴-ೢ.Ⴄ; [P1, V5, V6]; xn----ggf830f.xn--cnd; ; ; # ᜴-ೢ.Ⴄ
+᜴-ೢ.󠄩ⴄ; ᜴-ೢ.ⴄ; [V5]; xn----ggf830f.xn--vkj; ; ; # ᜴-ೢ.ⴄ
+xn----ggf830f.xn--vkj; ᜴-ೢ.ⴄ; [V5]; xn----ggf830f.xn--vkj; ; ; # ᜴-ೢ.ⴄ
+xn----ggf830f.xn--cnd; ᜴-ೢ.Ⴄ; [V5, V6]; xn----ggf830f.xn--cnd; ; ; # ᜴-ೢ.Ⴄ
+᜴-ೢ.󠄩ⴄ; ᜴-ೢ.ⴄ; [V5]; xn----ggf830f.xn--vkj; ; ; # ᜴-ೢ.ⴄ
+򭈗♋ڻ𐦥。॔⒈; 򭈗♋ڻ𐦥.॔⒈; [B1, B5, B6, P1, V5, V6]; xn--ukb372n129m3rs7f.xn--u3b240l; ; ; # ♋ڻ𐦥.॔⒈
+򭈗♋ڻ𐦥。॔1.; 򭈗♋ڻ𐦥.॔1.; [B1, B5, B6, P1, V5, V6]; xn--ukb372n129m3rs7f.xn--1-fyd.; ; ; # ♋ڻ𐦥.॔1.
+xn--ukb372n129m3rs7f.xn--1-fyd.; 򭈗♋ڻ𐦥.॔1.; [B1, B5, B6, V5, V6]; xn--ukb372n129m3rs7f.xn--1-fyd.; ; ; # ♋ڻ𐦥.॔1.
+xn--ukb372n129m3rs7f.xn--u3b240l; 򭈗♋ڻ𐦥.॔⒈; [B1, B5, B6, V5, V6]; xn--ukb372n129m3rs7f.xn--u3b240l; ; ; # ♋ڻ𐦥.॔⒈
+֤.ہ᪳‌; ֤.ہ᪳‌; [B1, B3, B6, C1, V5]; xn--vcb.xn--0kb623hm1d; ; xn--vcb.xn--0kb623h; [B1, B3, B6, V5] # ֤.ہ᪳
+֤.ہ᪳‌; ; [B1, B3, B6, C1, V5]; xn--vcb.xn--0kb623hm1d; ; xn--vcb.xn--0kb623h; [B1, B3, B6, V5] # ֤.ہ᪳
+xn--vcb.xn--0kb623h; ֤.ہ᪳; [B1, B3, B6, V5]; xn--vcb.xn--0kb623h; ; ; # ֤.ہ᪳
+xn--vcb.xn--0kb623hm1d; ֤.ہ᪳‌; [B1, B3, B6, C1, V5]; xn--vcb.xn--0kb623hm1d; ; ; # ֤.ہ᪳
+񢭏ࡆ≮્.𞦊; 񢭏ࡆ≮્.𞦊; [B5, B6, P1, V6]; xn--4vb80kq29ayo62l.xn--8g6h; ; ; # ࡆ≮્.
+񢭏ࡆ≮્.𞦊; 񢭏ࡆ≮્.𞦊; [B5, B6, P1, V6]; xn--4vb80kq29ayo62l.xn--8g6h; ; ; # ࡆ≮્.
+񢭏ࡆ≮્.𞦊; ; [B5, B6, P1, V6]; xn--4vb80kq29ayo62l.xn--8g6h; ; ; # ࡆ≮્.
+񢭏ࡆ≮્.𞦊; 񢭏ࡆ≮્.𞦊; [B5, B6, P1, V6]; xn--4vb80kq29ayo62l.xn--8g6h; ; ; # ࡆ≮્.
+xn--4vb80kq29ayo62l.xn--8g6h; 񢭏ࡆ≮્.𞦊; [B5, B6, V6]; xn--4vb80kq29ayo62l.xn--8g6h; ; ; # ࡆ≮્.
+‍。𞀘⒈ꡍ擉; ‍.𞀘⒈ꡍ擉; [C2, P1, V5, V6]; xn--1ug.xn--tsh026uql4bew9p; ; .xn--tsh026uql4bew9p; [P1, V5, V6, A4_2] # .𞀘⒈ꡍ擉
+‍。𞀘1.ꡍ擉; ‍.𞀘1.ꡍ擉; [C2, V5]; xn--1ug.xn--1-1p4r.xn--s7uv61m; ; .xn--1-1p4r.xn--s7uv61m; [V5, A4_2] # .𞀘1.ꡍ擉
+.xn--1-1p4r.xn--s7uv61m; .𞀘1.ꡍ擉; [V5, X4_2]; .xn--1-1p4r.xn--s7uv61m; [V5, A4_2]; ; # .𞀘1.ꡍ擉
+xn--1ug.xn--1-1p4r.xn--s7uv61m; ‍.𞀘1.ꡍ擉; [C2, V5]; xn--1ug.xn--1-1p4r.xn--s7uv61m; ; ; # .𞀘1.ꡍ擉
+.xn--tsh026uql4bew9p; .𞀘⒈ꡍ擉; [V5, V6, X4_2]; .xn--tsh026uql4bew9p; [V5, V6, A4_2]; ; # .𞀘⒈ꡍ擉
+xn--1ug.xn--tsh026uql4bew9p; ‍.𞀘⒈ꡍ擉; [C2, V5, V6]; xn--1ug.xn--tsh026uql4bew9p; ; ; # .𞀘⒈ꡍ擉
+₈ߋ.ﭤ≠; 8ߋ.ٿ≠; [B1, B3, P1, V6]; xn--8-zbd.xn--4ib883l; ; ; # 8ߋ.ٿ≠
+₈ߋ.ﭤ≠; 8ߋ.ٿ≠; [B1, B3, P1, V6]; xn--8-zbd.xn--4ib883l; ; ; # 8ߋ.ٿ≠
+8ߋ.ٿ≠; ; [B1, B3, P1, V6]; xn--8-zbd.xn--4ib883l; ; ; # 8ߋ.ٿ≠
+8ߋ.ٿ≠; 8ߋ.ٿ≠; [B1, B3, P1, V6]; xn--8-zbd.xn--4ib883l; ; ; # 8ߋ.ٿ≠
+xn--8-zbd.xn--4ib883l; 8ߋ.ٿ≠; [B1, B3, V6]; xn--8-zbd.xn--4ib883l; ; ; # 8ߋ.ٿ≠
+ᢡߞ򹐣.⒒ق𑍦; ; [B1, B5, P1, V6]; xn--5sb596fi873t.xn--ehb336mvy7n; ; ; # ᢡߞ.⒒ق𑍦
+ᢡߞ򹐣.11.ق𑍦; ; [B1, B5, P1, V6]; xn--5sb596fi873t.11.xn--ehb4198k; ; ; # ᢡߞ.11.ق𑍦
+xn--5sb596fi873t.11.xn--ehb4198k; ᢡߞ򹐣.11.ق𑍦; [B1, B5, V6]; xn--5sb596fi873t.11.xn--ehb4198k; ; ; # ᢡߞ.11.ق𑍦
+xn--5sb596fi873t.xn--ehb336mvy7n; ᢡߞ򹐣.⒒ق𑍦; [B1, B5, V6]; xn--5sb596fi873t.xn--ehb336mvy7n; ; ; # ᢡߞ.⒒ق𑍦
+่-𐹺𝟜.ͣۡ⒏; ่-𐹺4.ͣۡ⒏; [B1, P1, V5, V6]; xn---4-owiz479s.xn--eva20pjv9a; ; ; # ่-𐹺4.ͣۡ⒏
+่-𐹺4.ͣۡ8.; ; [B1, V5]; xn---4-owiz479s.xn--8-ihb69x.; ; ; # ่-𐹺4.ͣۡ8.
+xn---4-owiz479s.xn--8-ihb69x.; ่-𐹺4.ͣۡ8.; [B1, V5]; xn---4-owiz479s.xn--8-ihb69x.; ; ; # ่-𐹺4.ͣۡ8.
+xn---4-owiz479s.xn--eva20pjv9a; ่-𐹺4.ͣۡ⒏; [B1, V5, V6]; xn---4-owiz479s.xn--eva20pjv9a; ; ; # ่-𐹺4.ͣۡ⒏
+⫐。Ⴠ-󃐢; ⫐.Ⴠ-󃐢; [P1, V6]; xn--r3i.xn----z1g58579u; ; ; # ⫐.Ⴠ-
+⫐。Ⴠ-󃐢; ⫐.Ⴠ-󃐢; [P1, V6]; xn--r3i.xn----z1g58579u; ; ; # ⫐.Ⴠ-
+⫐。ⴠ-󃐢; ⫐.ⴠ-󃐢; [P1, V6]; xn--r3i.xn----2wst7439i; ; ; # ⫐.ⴠ-
+xn--r3i.xn----2wst7439i; ⫐.ⴠ-󃐢; [V6]; xn--r3i.xn----2wst7439i; ; ; # ⫐.ⴠ-
+xn--r3i.xn----z1g58579u; ⫐.Ⴠ-󃐢; [V6]; xn--r3i.xn----z1g58579u; ; ; # ⫐.Ⴠ-
+⫐。ⴠ-󃐢; ⫐.ⴠ-󃐢; [P1, V6]; xn--r3i.xn----2wst7439i; ; ; # ⫐.ⴠ-
+𑑂◊.⦟∠; 𑑂◊.⦟∠; [V5]; xn--01h3338f.xn--79g270a; ; ; # 𑑂◊.⦟∠
+𑑂◊.⦟∠; ; [V5]; xn--01h3338f.xn--79g270a; ; ; # 𑑂◊.⦟∠
+xn--01h3338f.xn--79g270a; 𑑂◊.⦟∠; [V5]; xn--01h3338f.xn--79g270a; ; ; # 𑑂◊.⦟∠
+𿌰-٢。󋸛ꡂ; 𿌰-٢.󋸛ꡂ; [B5, B6, P1, V6]; xn----dqc20828e.xn--bc9an2879c; ; ; # -٢.ꡂ
+xn----dqc20828e.xn--bc9an2879c; 𿌰-٢.󋸛ꡂ; [B5, B6, V6]; xn----dqc20828e.xn--bc9an2879c; ; ; # -٢.ꡂ
+ٸ。󠏬݁𞪭𐹪; يٴ.󠏬݁𞪭𐹪; [B1, P1, V6]; xn--mhb8f.xn--oob2585kfdsfsbo7h; ; ; # يٴ.݁𐹪
+يٴ。󠏬݁𞪭𐹪; يٴ.󠏬݁𞪭𐹪; [B1, P1, V6]; xn--mhb8f.xn--oob2585kfdsfsbo7h; ; ; # يٴ.݁𐹪
+xn--mhb8f.xn--oob2585kfdsfsbo7h; يٴ.󠏬݁𞪭𐹪; [B1, V6]; xn--mhb8f.xn--oob2585kfdsfsbo7h; ; ; # يٴ.݁𐹪
+𐫆ꌄ。‍ᣬ; 𐫆ꌄ.‍ᣬ; [B1, B2, B3, C2]; xn--y77ao18q.xn--wdf367a; ; xn--y77ao18q.xn--wdf; [B2, B3] # 𐫆ꌄ.ᣬ
+𐫆ꌄ。‍ᣬ; 𐫆ꌄ.‍ᣬ; [B1, B2, B3, C2]; xn--y77ao18q.xn--wdf367a; ; xn--y77ao18q.xn--wdf; [B2, B3] # 𐫆ꌄ.ᣬ
+xn--y77ao18q.xn--wdf; 𐫆ꌄ.ᣬ; [B2, B3]; xn--y77ao18q.xn--wdf; ; ; # 𐫆ꌄ.ᣬ
+xn--y77ao18q.xn--wdf367a; 𐫆ꌄ.‍ᣬ; [B1, B2, B3, C2]; xn--y77ao18q.xn--wdf367a; ; ; # 𐫆ꌄ.ᣬ
+₀٢。󅪞≯-; 0٢.󅪞≯-; [B1, B6, P1, V3, V6]; xn--0-dqc.xn----ogov3342l; ; ; # 0٢.≯-
+₀٢。󅪞≯-; 0٢.󅪞≯-; [B1, B6, P1, V3, V6]; xn--0-dqc.xn----ogov3342l; ; ; # 0٢.≯-
+0٢。󅪞≯-; 0٢.󅪞≯-; [B1, B6, P1, V3, V6]; xn--0-dqc.xn----ogov3342l; ; ; # 0٢.≯-
+0٢。󅪞≯-; 0٢.󅪞≯-; [B1, B6, P1, V3, V6]; xn--0-dqc.xn----ogov3342l; ; ; # 0٢.≯-
+xn--0-dqc.xn----ogov3342l; 0٢.󅪞≯-; [B1, B6, V3, V6]; xn--0-dqc.xn----ogov3342l; ; ; # 0٢.≯-
+̜𐹫-𞯃.𐋤ࡅ; ; [B1, P1, V5, V6]; xn----gdb7046r692g.xn--3vb1349j; ; ; # ̜𐹫-.𐋤ࡅ
+xn----gdb7046r692g.xn--3vb1349j; ̜𐹫-𞯃.𐋤ࡅ; [B1, V5, V6]; xn----gdb7046r692g.xn--3vb1349j; ; ; # ̜𐹫-.𐋤ࡅ
+≠。𝩑𐹩Ⴡ֔; ≠.𝩑𐹩Ⴡ֔; [B1, P1, V5, V6]; xn--1ch.xn--fcb538c649rypog; ; ; # ≠.𝩑𐹩Ⴡ֔
+≠。𝩑𐹩Ⴡ֔; ≠.𝩑𐹩Ⴡ֔; [B1, P1, V5, V6]; xn--1ch.xn--fcb538c649rypog; ; ; # ≠.𝩑𐹩Ⴡ֔
+≠。𝩑𐹩Ⴡ֔; ≠.𝩑𐹩Ⴡ֔; [B1, P1, V5, V6]; xn--1ch.xn--fcb538c649rypog; ; ; # ≠.𝩑𐹩Ⴡ֔
+≠。𝩑𐹩Ⴡ֔; ≠.𝩑𐹩Ⴡ֔; [B1, P1, V5, V6]; xn--1ch.xn--fcb538c649rypog; ; ; # ≠.𝩑𐹩Ⴡ֔
+≠。𝩑𐹩ⴡ֔; ≠.𝩑𐹩ⴡ֔; [B1, P1, V5, V6]; xn--1ch.xn--fcb363rk03mypug; ; ; # ≠.𝩑𐹩ⴡ֔
+≠。𝩑𐹩ⴡ֔; ≠.𝩑𐹩ⴡ֔; [B1, P1, V5, V6]; xn--1ch.xn--fcb363rk03mypug; ; ; # ≠.𝩑𐹩ⴡ֔
+xn--1ch.xn--fcb363rk03mypug; ≠.𝩑𐹩ⴡ֔; [B1, V5, V6]; xn--1ch.xn--fcb363rk03mypug; ; ; # ≠.𝩑𐹩ⴡ֔
+xn--1ch.xn--fcb538c649rypog; ≠.𝩑𐹩Ⴡ֔; [B1, V5, V6]; xn--1ch.xn--fcb538c649rypog; ; ; # ≠.𝩑𐹩Ⴡ֔
+≠。𝩑𐹩ⴡ֔; ≠.𝩑𐹩ⴡ֔; [B1, P1, V5, V6]; xn--1ch.xn--fcb363rk03mypug; ; ; # ≠.𝩑𐹩ⴡ֔
+≠。𝩑𐹩ⴡ֔; ≠.𝩑𐹩ⴡ֔; [B1, P1, V5, V6]; xn--1ch.xn--fcb363rk03mypug; ; ; # ≠.𝩑𐹩ⴡ֔
+𖫳≠.Ⴀ𐮀; ; [B1, B5, B6, P1, V5, V6]; xn--1ch9250k.xn--7md2659j; ; ; # 𖫳≠.Ⴀ𐮀
+𖫳≠.Ⴀ𐮀; 𖫳≠.Ⴀ𐮀; [B1, B5, B6, P1, V5, V6]; xn--1ch9250k.xn--7md2659j; ; ; # 𖫳≠.Ⴀ𐮀
+𖫳≠.ⴀ𐮀; 𖫳≠.ⴀ𐮀; [B1, B5, B6, P1, V5, V6]; xn--1ch9250k.xn--rkj6232e; ; ; # 𖫳≠.ⴀ𐮀
+𖫳≠.ⴀ𐮀; ; [B1, B5, B6, P1, V5, V6]; xn--1ch9250k.xn--rkj6232e; ; ; # 𖫳≠.ⴀ𐮀
+xn--1ch9250k.xn--rkj6232e; 𖫳≠.ⴀ𐮀; [B1, B5, B6, V5, V6]; xn--1ch9250k.xn--rkj6232e; ; ; # 𖫳≠.ⴀ𐮀
+xn--1ch9250k.xn--7md2659j; 𖫳≠.Ⴀ𐮀; [B1, B5, B6, V5, V6]; xn--1ch9250k.xn--7md2659j; ; ; # 𖫳≠.Ⴀ𐮀
+󠅾ܶܦ.ᢚ閪࣢𝩟; ܶܦ.ᢚ閪࣢𝩟; [B1, B5, B6, P1, V5, V6]; xn--wnb5a.xn--l0b161fis8gbp5m; ; ; # ܶܦ.ᢚ閪𝩟
+󠅾ܶܦ.ᢚ閪࣢𝩟; ܶܦ.ᢚ閪࣢𝩟; [B1, B5, B6, P1, V5, V6]; xn--wnb5a.xn--l0b161fis8gbp5m; ; ; # ܶܦ.ᢚ閪𝩟
+xn--wnb5a.xn--l0b161fis8gbp5m; ܶܦ.ᢚ閪࣢𝩟; [B1, B5, B6, V5, V6]; xn--wnb5a.xn--l0b161fis8gbp5m; ; ; # ܶܦ.ᢚ閪𝩟
+‍󠇜ۋ꣩。⃝ྰ-ᛟ; ‍ۋ꣩.⃝ྰ-ᛟ; [B1, C2, V5]; xn--blb540ke10h.xn----gmg236cj6k; ; xn--blb8114f.xn----gmg236cj6k; [B1, V5] # ۋ꣩.⃝ྰ-ᛟ
+‍󠇜ۋ꣩。⃝ྰ-ᛟ; ‍ۋ꣩.⃝ྰ-ᛟ; [B1, C2, V5]; xn--blb540ke10h.xn----gmg236cj6k; ; xn--blb8114f.xn----gmg236cj6k; [B1, V5] # ۋ꣩.⃝ྰ-ᛟ
+xn--blb8114f.xn----gmg236cj6k; ۋ꣩.⃝ྰ-ᛟ; [B1, V5]; xn--blb8114f.xn----gmg236cj6k; ; ; # ۋ꣩.⃝ྰ-ᛟ
+xn--blb540ke10h.xn----gmg236cj6k; ‍ۋ꣩.⃝ྰ-ᛟ; [B1, C2, V5]; xn--blb540ke10h.xn----gmg236cj6k; ; ; # ۋ꣩.⃝ྰ-ᛟ
+헁󘖙ฺ󚍚。ں𝟜; 헁󘖙ฺ󚍚.ں4; [P1, V6]; xn--o4c1723h8g85gt4ya.xn--4-dvc; ; ; # 헁ฺ.ں4
+헁󘖙ฺ󚍚。ں𝟜; 헁󘖙ฺ󚍚.ں4; [P1, V6]; xn--o4c1723h8g85gt4ya.xn--4-dvc; ; ; # 헁ฺ.ں4
+헁󘖙ฺ󚍚。ں4; 헁󘖙ฺ󚍚.ں4; [P1, V6]; xn--o4c1723h8g85gt4ya.xn--4-dvc; ; ; # 헁ฺ.ں4
+헁󘖙ฺ󚍚。ں4; 헁󘖙ฺ󚍚.ں4; [P1, V6]; xn--o4c1723h8g85gt4ya.xn--4-dvc; ; ; # 헁ฺ.ں4
+xn--o4c1723h8g85gt4ya.xn--4-dvc; 헁󘖙ฺ󚍚.ں4; [V6]; xn--o4c1723h8g85gt4ya.xn--4-dvc; ; ; # 헁ฺ.ں4
+𐹭。󃱂‌Ⴞ; 𐹭.󃱂‌Ⴞ; [B1, C1, P1, V6]; xn--lo0d.xn--2nd949eqw95u; ; xn--lo0d.xn--2nd75260n; [B1, P1, V6] # 𐹭.Ⴞ
+𐹭。󃱂‌Ⴞ; 𐹭.󃱂‌Ⴞ; [B1, C1, P1, V6]; xn--lo0d.xn--2nd949eqw95u; ; xn--lo0d.xn--2nd75260n; [B1, P1, V6] # 𐹭.Ⴞ
+𐹭。󃱂‌ⴞ; 𐹭.󃱂‌ⴞ; [B1, C1, P1, V6]; xn--lo0d.xn--0ugx72cwi33v; ; xn--lo0d.xn--mljx1099g; [B1, P1, V6] # 𐹭.ⴞ
+xn--lo0d.xn--mljx1099g; 𐹭.󃱂ⴞ; [B1, V6]; xn--lo0d.xn--mljx1099g; ; ; # 𐹭.ⴞ
+xn--lo0d.xn--0ugx72cwi33v; 𐹭.󃱂‌ⴞ; [B1, C1, V6]; xn--lo0d.xn--0ugx72cwi33v; ; ; # 𐹭.ⴞ
+xn--lo0d.xn--2nd75260n; 𐹭.󃱂Ⴞ; [B1, V6]; xn--lo0d.xn--2nd75260n; ; ; # 𐹭.Ⴞ
+xn--lo0d.xn--2nd949eqw95u; 𐹭.󃱂‌Ⴞ; [B1, C1, V6]; xn--lo0d.xn--2nd949eqw95u; ; ; # 𐹭.Ⴞ
+𐹭。󃱂‌ⴞ; 𐹭.󃱂‌ⴞ; [B1, C1, P1, V6]; xn--lo0d.xn--0ugx72cwi33v; ; xn--lo0d.xn--mljx1099g; [B1, P1, V6] # 𐹭.ⴞ
+꥓.̽𑂽馋; ; [P1, V5, V6]; xn--3j9a.xn--bua0708eqzrd; ; ; # ꥓.̽馋
+xn--3j9a.xn--bua0708eqzrd; ꥓.̽𑂽馋; [V5, V6]; xn--3j9a.xn--bua0708eqzrd; ; ; # ꥓.̽馋
+󈫝򪛸‍。䜖; 󈫝򪛸‍.䜖; [C2, P1, V6]; xn--1ug30527h9mxi.xn--k0o; ; xn--g138cxw05a.xn--k0o; [P1, V6] # .䜖
+󈫝򪛸‍。䜖; 󈫝򪛸‍.䜖; [C2, P1, V6]; xn--1ug30527h9mxi.xn--k0o; ; xn--g138cxw05a.xn--k0o; [P1, V6] # .䜖
+xn--g138cxw05a.xn--k0o; 󈫝򪛸.䜖; [V6]; xn--g138cxw05a.xn--k0o; ; ; # .䜖
+xn--1ug30527h9mxi.xn--k0o; 󈫝򪛸‍.䜖; [C2, V6]; xn--1ug30527h9mxi.xn--k0o; ; ; # .䜖
+ᡯ⚉姶🄉.۷‍🎪‍; ᡯ⚉姶🄉.۷‍🎪‍; [C2, P1, V6]; xn--c9e433epi4b3j20a.xn--kmb859ja94998b; ; xn--c9e433epi4b3j20a.xn--kmb6733w; [P1, V6] # ᡯ⚉姶🄉.۷🎪
+ᡯ⚉姶8,.۷‍🎪‍; ; [C2, P1, V6]; xn--8,-g9oy26fzu4d.xn--kmb859ja94998b; ; xn--8,-g9oy26fzu4d.xn--kmb6733w; [P1, V6] # ᡯ⚉姶8,.۷🎪
+xn--8,-g9oy26fzu4d.xn--kmb6733w; ᡯ⚉姶8,.۷🎪; [P1, V6]; xn--8,-g9oy26fzu4d.xn--kmb6733w; ; ; # ᡯ⚉姶8,.۷🎪
+xn--8,-g9oy26fzu4d.xn--kmb859ja94998b; ᡯ⚉姶8,.۷‍🎪‍; [C2, P1, V6]; xn--8,-g9oy26fzu4d.xn--kmb859ja94998b; ; ; # ᡯ⚉姶8,.۷🎪
+xn--c9e433epi4b3j20a.xn--kmb6733w; ᡯ⚉姶🄉.۷🎪; [V6]; xn--c9e433epi4b3j20a.xn--kmb6733w; ; ; # ᡯ⚉姶🄉.۷🎪
+xn--c9e433epi4b3j20a.xn--kmb859ja94998b; ᡯ⚉姶🄉.۷‍🎪‍; [C2, V6]; xn--c9e433epi4b3j20a.xn--kmb859ja94998b; ; ; # ᡯ⚉姶🄉.۷🎪
+𞽀.𐹸🚖ฺ; ; [B1, P1, V6]; xn--0n7h.xn--o4c9032klszf; ; ; # .𐹸🚖ฺ
+xn--0n7h.xn--o4c9032klszf; 𞽀.𐹸🚖ฺ; [B1, V6]; xn--0n7h.xn--o4c9032klszf; ; ; # .𐹸🚖ฺ
+Ⴔᠵ。𐹧݇۹; Ⴔᠵ.𐹧݇۹; [B1, P1, V6]; xn--snd659a.xn--mmb9ml895e; ; ; # Ⴔᠵ.𐹧݇۹
+Ⴔᠵ。𐹧݇۹; Ⴔᠵ.𐹧݇۹; [B1, P1, V6]; xn--snd659a.xn--mmb9ml895e; ; ; # Ⴔᠵ.𐹧݇۹
+ⴔᠵ。𐹧݇۹; ⴔᠵ.𐹧݇۹; [B1]; xn--o7e997h.xn--mmb9ml895e; ; ; # ⴔᠵ.𐹧݇۹
+xn--o7e997h.xn--mmb9ml895e; ⴔᠵ.𐹧݇۹; [B1]; xn--o7e997h.xn--mmb9ml895e; ; ; # ⴔᠵ.𐹧݇۹
+xn--snd659a.xn--mmb9ml895e; Ⴔᠵ.𐹧݇۹; [B1, V6]; xn--snd659a.xn--mmb9ml895e; ; ; # Ⴔᠵ.𐹧݇۹
+ⴔᠵ。𐹧݇۹; ⴔᠵ.𐹧݇۹; [B1]; xn--o7e997h.xn--mmb9ml895e; ; ; # ⴔᠵ.𐹧݇۹
+፟ᡈ‌.︒-𖾐-; ፟ᡈ‌.︒-𖾐-; [C1, P1, V3, V5, V6]; xn--b7d82wo4h.xn-----c82nz547a; ; xn--b7d82w.xn-----c82nz547a; [P1, V3, V5, V6] # ፟ᡈ.︒-𖾐-
+፟ᡈ‌.。-𖾐-; ፟ᡈ‌..-𖾐-; [C1, V3, V5, X4_2]; xn--b7d82wo4h..xn-----pe4u; [C1, V3, V5, A4_2]; xn--b7d82w..xn-----pe4u; [V3, V5, A4_2] # ፟ᡈ..-𖾐-
+xn--b7d82w..xn-----pe4u; ፟ᡈ..-𖾐-; [V3, V5, X4_2]; xn--b7d82w..xn-----pe4u; [V3, V5, A4_2]; ; # ፟ᡈ..-𖾐-
+xn--b7d82wo4h..xn-----pe4u; ፟ᡈ‌..-𖾐-; [C1, V3, V5, X4_2]; xn--b7d82wo4h..xn-----pe4u; [C1, V3, V5, A4_2]; ; # ፟ᡈ..-𖾐-
+xn--b7d82w.xn-----c82nz547a; ፟ᡈ.︒-𖾐-; [V3, V5, V6]; xn--b7d82w.xn-----c82nz547a; ; ; # ፟ᡈ.︒-𖾐-
+xn--b7d82wo4h.xn-----c82nz547a; ፟ᡈ‌.︒-𖾐-; [C1, V3, V5, V6]; xn--b7d82wo4h.xn-----c82nz547a; ; ; # ፟ᡈ.︒-𖾐-
+⒈؁⒖‌.ᷰߛ; ; [B1, C1, P1, V5, V6]; xn--jfb844kmfdwb.xn--2sb914i; ; xn--jfb347mib.xn--2sb914i; [B1, P1, V5, V6] # ⒈⒖.ᷰߛ
+1.؁15.‌.ᷰߛ; ; [B1, C1, P1, V5, V6]; 1.xn--15-1pd.xn--0ug.xn--2sb914i; ; 1.xn--15-1pd..xn--2sb914i; [B1, P1, V5, V6, A4_2] # 1.15..ᷰߛ
+1.xn--15-1pd..xn--2sb914i; 1.؁15..ᷰߛ; [B1, V5, V6, X4_2]; 1.xn--15-1pd..xn--2sb914i; [B1, V5, V6, A4_2]; ; # 1.15..ᷰߛ
+1.xn--15-1pd.xn--0ug.xn--2sb914i; 1.؁15.‌.ᷰߛ; [B1, C1, V5, V6]; 1.xn--15-1pd.xn--0ug.xn--2sb914i; ; ; # 1.15..ᷰߛ
+xn--jfb347mib.xn--2sb914i; ⒈؁⒖.ᷰߛ; [B1, V5, V6]; xn--jfb347mib.xn--2sb914i; ; ; # ⒈⒖.ᷰߛ
+xn--jfb844kmfdwb.xn--2sb914i; ⒈؁⒖‌.ᷰߛ; [B1, C1, V5, V6]; xn--jfb844kmfdwb.xn--2sb914i; ; ; # ⒈⒖.ᷰߛ
+𝩜。-୍Ⴋ; 𝩜.-୍Ⴋ; [P1, V3, V5, V6]; xn--792h.xn----bse632b; ; ; # 𝩜.-୍Ⴋ
+𝩜。-୍ⴋ; 𝩜.-୍ⴋ; [V3, V5]; xn--792h.xn----bse820x; ; ; # 𝩜.-୍ⴋ
+xn--792h.xn----bse820x; 𝩜.-୍ⴋ; [V3, V5]; xn--792h.xn----bse820x; ; ; # 𝩜.-୍ⴋ
+xn--792h.xn----bse632b; 𝩜.-୍Ⴋ; [V3, V5, V6]; xn--792h.xn----bse632b; ; ; # 𝩜.-୍Ⴋ
+ßჀ.ؠ刯Ⴝ; ; [B2, B3, P1, V6]; xn--zca442f.xn--fgb845cb66c; ; xn--ss-wgk.xn--fgb845cb66c; # ßჀ.ؠ刯Ⴝ
+ßⴠ.ؠ刯ⴝ; ; [B2, B3]; xn--zca277t.xn--fgb670rovy; ; xn--ss-j81a.xn--fgb670rovy; # ßⴠ.ؠ刯ⴝ
+SSჀ.ؠ刯Ⴝ; ssჀ.ؠ刯Ⴝ; [B2, B3, P1, V6]; xn--ss-wgk.xn--fgb845cb66c; ; ; # ssჀ.ؠ刯Ⴝ
+ssⴠ.ؠ刯ⴝ; ; [B2, B3]; xn--ss-j81a.xn--fgb670rovy; ; ; # ssⴠ.ؠ刯ⴝ
+Ssⴠ.ؠ刯Ⴝ; ssⴠ.ؠ刯Ⴝ; [B2, B3, P1, V6]; xn--ss-j81a.xn--fgb845cb66c; ; ; # ssⴠ.ؠ刯Ⴝ
+xn--ss-j81a.xn--fgb845cb66c; ssⴠ.ؠ刯Ⴝ; [B2, B3, V6]; xn--ss-j81a.xn--fgb845cb66c; ; ; # ssⴠ.ؠ刯Ⴝ
+xn--ss-j81a.xn--fgb670rovy; ssⴠ.ؠ刯ⴝ; [B2, B3]; xn--ss-j81a.xn--fgb670rovy; ; ; # ssⴠ.ؠ刯ⴝ
+xn--ss-wgk.xn--fgb845cb66c; ssჀ.ؠ刯Ⴝ; [B2, B3, V6]; xn--ss-wgk.xn--fgb845cb66c; ; ; # ssჀ.ؠ刯Ⴝ
+xn--zca277t.xn--fgb670rovy; ßⴠ.ؠ刯ⴝ; [B2, B3]; xn--zca277t.xn--fgb670rovy; ; ; # ßⴠ.ؠ刯ⴝ
+xn--zca442f.xn--fgb845cb66c; ßჀ.ؠ刯Ⴝ; [B2, B3, V6]; xn--zca442f.xn--fgb845cb66c; ; ; # ßჀ.ؠ刯Ⴝ
+᮪ႣℲ。ᠳ툻ٳ; ᮪ႣℲ.ᠳ툻ٳ; [B5, B6, P1, V5, V6]; xn--bnd957cone.xn--sib102gc69k; ; ; # ᮪ႣℲ.ᠳ툻ٳ
+᮪ႣℲ。ᠳ툻ٳ; ᮪ႣℲ.ᠳ툻ٳ; [B5, B6, P1, V5, V6]; xn--bnd957cone.xn--sib102gc69k; ; ; # ᮪ႣℲ.ᠳ툻ٳ
+᮪ႣℲ。ᠳ툻ٳ; ᮪ႣℲ.ᠳ툻ٳ; [B5, B6, P1, V5, V6]; xn--bnd957cone.xn--sib102gc69k; ; ; # ᮪ႣℲ.ᠳ툻ٳ
+᮪ႣℲ。ᠳ툻ٳ; ᮪ႣℲ.ᠳ툻ٳ; [B5, B6, P1, V5, V6]; xn--bnd957cone.xn--sib102gc69k; ; ; # ᮪ႣℲ.ᠳ툻ٳ
+᮪ⴃⅎ。ᠳ툻ٳ; ᮪ⴃⅎ.ᠳ툻ٳ; [B5, B6, V5]; xn--yxf24x4ol.xn--sib102gc69k; ; ; # ᮪ⴃⅎ.ᠳ툻ٳ
+᮪ⴃⅎ。ᠳ툻ٳ; ᮪ⴃⅎ.ᠳ툻ٳ; [B5, B6, V5]; xn--yxf24x4ol.xn--sib102gc69k; ; ; # ᮪ⴃⅎ.ᠳ툻ٳ
+᮪Ⴃⅎ。ᠳ툻ٳ; ᮪Ⴃⅎ.ᠳ툻ٳ; [B5, B6, P1, V5, V6]; xn--bnd957c2pe.xn--sib102gc69k; ; ; # ᮪Ⴃⅎ.ᠳ툻ٳ
+᮪Ⴃⅎ。ᠳ툻ٳ; ᮪Ⴃⅎ.ᠳ툻ٳ; [B5, B6, P1, V5, V6]; xn--bnd957c2pe.xn--sib102gc69k; ; ; # ᮪Ⴃⅎ.ᠳ툻ٳ
+xn--bnd957c2pe.xn--sib102gc69k; ᮪Ⴃⅎ.ᠳ툻ٳ; [B5, B6, V5, V6]; xn--bnd957c2pe.xn--sib102gc69k; ; ; # ᮪Ⴃⅎ.ᠳ툻ٳ
+xn--yxf24x4ol.xn--sib102gc69k; ᮪ⴃⅎ.ᠳ툻ٳ; [B5, B6, V5]; xn--yxf24x4ol.xn--sib102gc69k; ; ; # ᮪ⴃⅎ.ᠳ툻ٳ
+xn--bnd957cone.xn--sib102gc69k; ᮪ႣℲ.ᠳ툻ٳ; [B5, B6, V5, V6]; xn--bnd957cone.xn--sib102gc69k; ; ; # ᮪ႣℲ.ᠳ툻ٳ
+᮪ⴃⅎ。ᠳ툻ٳ; ᮪ⴃⅎ.ᠳ툻ٳ; [B5, B6, V5]; xn--yxf24x4ol.xn--sib102gc69k; ; ; # ᮪ⴃⅎ.ᠳ툻ٳ
+᮪ⴃⅎ。ᠳ툻ٳ; ᮪ⴃⅎ.ᠳ툻ٳ; [B5, B6, V5]; xn--yxf24x4ol.xn--sib102gc69k; ; ; # ᮪ⴃⅎ.ᠳ툻ٳ
+᮪Ⴃⅎ。ᠳ툻ٳ; ᮪Ⴃⅎ.ᠳ툻ٳ; [B5, B6, P1, V5, V6]; xn--bnd957c2pe.xn--sib102gc69k; ; ; # ᮪Ⴃⅎ.ᠳ툻ٳ
+᮪Ⴃⅎ。ᠳ툻ٳ; ᮪Ⴃⅎ.ᠳ툻ٳ; [B5, B6, P1, V5, V6]; xn--bnd957c2pe.xn--sib102gc69k; ; ; # ᮪Ⴃⅎ.ᠳ툻ٳ
+۬.ࢢ𐹫ټ; ; [B1, B3, B6, V5]; xn--8lb.xn--1ib31ily45b; ; ; # ۬.ࢢ𐹫ټ
+xn--8lb.xn--1ib31ily45b; ۬.ࢢ𐹫ټ; [B1, B3, B6, V5]; xn--8lb.xn--1ib31ily45b; ; ; # ۬.ࢢ𐹫ټ
+ڶ۟。₇꠆; ڶ۟.7꠆; [B1]; xn--pkb6f.xn--7-x93e; ; ; # ڶ۟.7꠆
+ڶ۟。7꠆; ڶ۟.7꠆; [B1]; xn--pkb6f.xn--7-x93e; ; ; # ڶ۟.7꠆
+xn--pkb6f.xn--7-x93e; ڶ۟.7꠆; [B1]; xn--pkb6f.xn--7-x93e; ; ; # ڶ۟.7꠆
+ڶ۟.7꠆; ; [B1]; xn--pkb6f.xn--7-x93e; ; ; # ڶ۟.7꠆
+Ⴣ𐹻.‌𝪣≮󠩉; ; [B1, B5, B6, C1, P1, V6]; xn--7nd8101k.xn--0ugy6gn120eb103g; ; xn--7nd8101k.xn--gdh4944ob3x3e; [B1, B5, B6, P1, V5, V6] # Ⴣ𐹻.𝪣≮
+Ⴣ𐹻.‌𝪣≮󠩉; Ⴣ𐹻.‌𝪣≮󠩉; [B1, B5, B6, C1, P1, V6]; xn--7nd8101k.xn--0ugy6gn120eb103g; ; xn--7nd8101k.xn--gdh4944ob3x3e; [B1, B5, B6, P1, V5, V6] # Ⴣ𐹻.𝪣≮
+ⴣ𐹻.‌𝪣≮󠩉; ⴣ𐹻.‌𝪣≮󠩉; [B1, B5, B6, C1, P1, V6]; xn--rlj6323e.xn--0ugy6gn120eb103g; ; xn--rlj6323e.xn--gdh4944ob3x3e; [B1, B5, B6, P1, V5, V6] # ⴣ𐹻.𝪣≮
+ⴣ𐹻.‌𝪣≮󠩉; ; [B1, B5, B6, C1, P1, V6]; xn--rlj6323e.xn--0ugy6gn120eb103g; ; xn--rlj6323e.xn--gdh4944ob3x3e; [B1, B5, B6, P1, V5, V6] # ⴣ𐹻.𝪣≮
+xn--rlj6323e.xn--gdh4944ob3x3e; ⴣ𐹻.𝪣≮󠩉; [B1, B5, B6, V5, V6]; xn--rlj6323e.xn--gdh4944ob3x3e; ; ; # ⴣ𐹻.𝪣≮
+xn--rlj6323e.xn--0ugy6gn120eb103g; ⴣ𐹻.‌𝪣≮󠩉; [B1, B5, B6, C1, V6]; xn--rlj6323e.xn--0ugy6gn120eb103g; ; ; # ⴣ𐹻.𝪣≮
+xn--7nd8101k.xn--gdh4944ob3x3e; Ⴣ𐹻.𝪣≮󠩉; [B1, B5, B6, V5, V6]; xn--7nd8101k.xn--gdh4944ob3x3e; ; ; # Ⴣ𐹻.𝪣≮
+xn--7nd8101k.xn--0ugy6gn120eb103g; Ⴣ𐹻.‌𝪣≮󠩉; [B1, B5, B6, C1, V6]; xn--7nd8101k.xn--0ugy6gn120eb103g; ; ; # Ⴣ𐹻.𝪣≮
+𝟵隁⯮.᠍‌; 9隁⯮.‌; [C1]; xn--9-mfs8024b.xn--0ug; ; xn--9-mfs8024b.; [] # 9隁⯮.
+9隁⯮.᠍‌; 9隁⯮.‌; [C1]; xn--9-mfs8024b.xn--0ug; ; xn--9-mfs8024b.; [] # 9隁⯮.
+xn--9-mfs8024b.; 9隁⯮.; ; xn--9-mfs8024b.; ; ; # 9隁⯮.
+9隁⯮.; ; ; xn--9-mfs8024b.; ; ; # 9隁⯮.
+xn--9-mfs8024b.xn--0ug; 9隁⯮.‌; [C1]; xn--9-mfs8024b.xn--0ug; ; ; # 9隁⯮.
+⒏𐹧。Ⴣ྄彦; ⒏𐹧.Ⴣ྄彦; [B1, P1, V6]; xn--0sh2466f.xn--3ed15dt93o; ; ; # ⒏𐹧.Ⴣ྄彦
+8.𐹧。Ⴣ྄彦; 8.𐹧.Ⴣ྄彦; [B1, P1, V6]; 8.xn--fo0d.xn--3ed15dt93o; ; ; # 8.𐹧.Ⴣ྄彦
+8.𐹧。ⴣ྄彦; 8.𐹧.ⴣ྄彦; [B1]; 8.xn--fo0d.xn--3ed972m6o8a; ; ; # 8.𐹧.ⴣ྄彦
+8.xn--fo0d.xn--3ed972m6o8a; 8.𐹧.ⴣ྄彦; [B1]; 8.xn--fo0d.xn--3ed972m6o8a; ; ; # 8.𐹧.ⴣ྄彦
+8.xn--fo0d.xn--3ed15dt93o; 8.𐹧.Ⴣ྄彦; [B1, V6]; 8.xn--fo0d.xn--3ed15dt93o; ; ; # 8.𐹧.Ⴣ྄彦
+⒏𐹧。ⴣ྄彦; ⒏𐹧.ⴣ྄彦; [B1, P1, V6]; xn--0sh2466f.xn--3ed972m6o8a; ; ; # ⒏𐹧.ⴣ྄彦
+xn--0sh2466f.xn--3ed972m6o8a; ⒏𐹧.ⴣ྄彦; [B1, V6]; xn--0sh2466f.xn--3ed972m6o8a; ; ; # ⒏𐹧.ⴣ྄彦
+xn--0sh2466f.xn--3ed15dt93o; ⒏𐹧.Ⴣ྄彦; [B1, V6]; xn--0sh2466f.xn--3ed15dt93o; ; ; # ⒏𐹧.Ⴣ྄彦
+-问񬰔⒛。؄-񜗉橬; -问񬰔⒛.؄-񜗉橬; [B1, P1, V3, V6]; xn----hdpu849bhis3e.xn----ykc7228efm46d; ; ; # -问⒛.-橬
+-问񬰔20.。؄-񜗉橬; -问񬰔20..؄-񜗉橬; [B1, P1, V3, V6, X4_2]; xn---20-658jx1776d..xn----ykc7228efm46d; [B1, P1, V3, V6, A4_2]; ; # -问20..-橬
+xn---20-658jx1776d..xn----ykc7228efm46d; -问񬰔20..؄-񜗉橬; [B1, V3, V6, X4_2]; xn---20-658jx1776d..xn----ykc7228efm46d; [B1, V3, V6, A4_2]; ; # -问20..-橬
+xn----hdpu849bhis3e.xn----ykc7228efm46d; -问񬰔⒛.؄-񜗉橬; [B1, V3, V6]; xn----hdpu849bhis3e.xn----ykc7228efm46d; ; ; # -问⒛.-橬
+ᮬႬ‌̥。𝟸; ᮬႬ‌̥.2; [C1, P1, V5, V6]; xn--mta930emribme.2; ; xn--mta930emri.2; [P1, V5, V6] # ᮬႬ̥.2
+ᮬႬ‌̥。2; ᮬႬ‌̥.2; [C1, P1, V5, V6]; xn--mta930emribme.2; ; xn--mta930emri.2; [P1, V5, V6] # ᮬႬ̥.2
+ᮬⴌ‌̥。2; ᮬⴌ‌̥.2; [C1, V5]; xn--mta176j97cl2q.2; ; xn--mta176jjjm.2; [V5] # ᮬⴌ̥.2
+xn--mta176jjjm.2; ᮬⴌ̥.2; [V5]; xn--mta176jjjm.2; ; ; # ᮬⴌ̥.2
+xn--mta176j97cl2q.2; ᮬⴌ‌̥.2; [C1, V5]; xn--mta176j97cl2q.2; ; ; # ᮬⴌ̥.2
+xn--mta930emri.2; ᮬႬ̥.2; [V5, V6]; xn--mta930emri.2; ; ; # ᮬႬ̥.2
+xn--mta930emribme.2; ᮬႬ‌̥.2; [C1, V5, V6]; xn--mta930emribme.2; ; ; # ᮬႬ̥.2
+ᮬⴌ‌̥。𝟸; ᮬⴌ‌̥.2; [C1, V5]; xn--mta176j97cl2q.2; ; xn--mta176jjjm.2; [V5] # ᮬⴌ̥.2
+?。꠆٩󠒩; ?.꠆٩󠒩; [B1, P1, V5, V6]; ?.xn--iib9583fusy0i; ; ; # ?.꠆٩
+?.xn--iib9583fusy0i; ?.꠆٩󠒩; [B1, P1, V5, V6]; ?.xn--iib9583fusy0i; ; ; # ?.꠆٩
+󠄁͟⾶。₇︒눇≮; ͟飛.7︒눇≮; [P1, V5, V6]; xn--9ua0567e.xn--7-ngou006d1ttc; ; ; # ͟飛.7︒눇≮
+󠄁͟⾶。₇︒눇≮; ͟飛.7︒눇≮; [P1, V5, V6]; xn--9ua0567e.xn--7-ngou006d1ttc; ; ; # ͟飛.7︒눇≮
+󠄁͟飛。7。눇≮; ͟飛.7.눇≮; [P1, V5, V6]; xn--9ua0567e.7.xn--gdh6767c; ; ; # ͟飛.7.눇≮
+󠄁͟飛。7。눇≮; ͟飛.7.눇≮; [P1, V5, V6]; xn--9ua0567e.7.xn--gdh6767c; ; ; # ͟飛.7.눇≮
+xn--9ua0567e.7.xn--gdh6767c; ͟飛.7.눇≮; [V5, V6]; xn--9ua0567e.7.xn--gdh6767c; ; ; # ͟飛.7.눇≮
+xn--9ua0567e.xn--7-ngou006d1ttc; ͟飛.7︒눇≮; [V5, V6]; xn--9ua0567e.xn--7-ngou006d1ttc; ; ; # ͟飛.7︒눇≮
+‌︉𐹴‍.‌⿃; ‌𐹴‍.‌鳥; [B1, C1, C2]; xn--0ugc6024p.xn--0ug1920c; ; xn--so0d.xn--6x6a; [B1] # 𐹴.鳥
+‌︉𐹴‍.‌鳥; ‌𐹴‍.‌鳥; [B1, C1, C2]; xn--0ugc6024p.xn--0ug1920c; ; xn--so0d.xn--6x6a; [B1] # 𐹴.鳥
+xn--so0d.xn--6x6a; 𐹴.鳥; [B1]; xn--so0d.xn--6x6a; ; ; # 𐹴.鳥
+xn--0ugc6024p.xn--0ug1920c; ‌𐹴‍.‌鳥; [B1, C1, C2]; xn--0ugc6024p.xn--0ug1920c; ; ; # 𐹴.鳥
+🍮.‍󠗒𐦁𝨝; 🍮.‍󠗒𐦁𝨝; [B1, C2, P1, V6]; xn--lj8h.xn--1ug6603gr1pfwq37h; ; xn--lj8h.xn--ln9ci476aqmr2g; [B1, P1, V6] # 🍮.𐦁𝨝
+🍮.‍󠗒𐦁𝨝; ; [B1, C2, P1, V6]; xn--lj8h.xn--1ug6603gr1pfwq37h; ; xn--lj8h.xn--ln9ci476aqmr2g; [B1, P1, V6] # 🍮.𐦁𝨝
+xn--lj8h.xn--ln9ci476aqmr2g; 🍮.󠗒𐦁𝨝; [B1, V6]; xn--lj8h.xn--ln9ci476aqmr2g; ; ; # 🍮.𐦁𝨝
+xn--lj8h.xn--1ug6603gr1pfwq37h; 🍮.‍󠗒𐦁𝨝; [B1, C2, V6]; xn--lj8h.xn--1ug6603gr1pfwq37h; ; ; # 🍮.𐦁𝨝
+ٽृ.𞤓‍; ٽृ.𞤵‍; [B3, C2]; xn--2ib43l.xn--1ugy711p; ; xn--2ib43l.xn--te6h; [] # ٽृ.𞤵
+ٽृ.𞤵‍; ; [B3, C2]; xn--2ib43l.xn--1ugy711p; ; xn--2ib43l.xn--te6h; [] # ٽृ.𞤵
+xn--2ib43l.xn--te6h; ٽृ.𞤵; ; xn--2ib43l.xn--te6h; ; ; # ٽृ.𞤵
+ٽृ.𞤵; ; ; xn--2ib43l.xn--te6h; ; ; # ٽृ.𞤵
+ٽृ.𞤓; ٽृ.𞤵; ; xn--2ib43l.xn--te6h; ; ; # ٽृ.𞤵
+xn--2ib43l.xn--1ugy711p; ٽृ.𞤵‍; [B3, C2]; xn--2ib43l.xn--1ugy711p; ; ; # ٽृ.𞤵
+٤੍-.󥜽္񦦐; ٤੍-.󥜽္񦦐; [B1, P1, V3, V6]; xn----gqc711a.xn--9jd88234f3qm0b; ; ; # ٤੍-.္
+٤੍-.󥜽္񦦐; ; [B1, P1, V3, V6]; xn----gqc711a.xn--9jd88234f3qm0b; ; ; # ٤੍-.္
+xn----gqc711a.xn--9jd88234f3qm0b; ٤੍-.󥜽္񦦐; [B1, V3, V6]; xn----gqc711a.xn--9jd88234f3qm0b; ; ; # ٤੍-.္
+4်-𐹸。ꨩ‌𐹴≮; 4်-𐹸.ꨩ‌𐹴≮; [B1, C1, P1, V5, V6]; xn--4--e4j7831r.xn--0ugy6gjy5sl3ud; ; xn--4--e4j7831r.xn--gdh8754cz40c; [B1, P1, V5, V6] # 4်-𐹸.ꨩ𐹴≮
+4်-𐹸。ꨩ‌𐹴≮; 4်-𐹸.ꨩ‌𐹴≮; [B1, C1, P1, V5, V6]; xn--4--e4j7831r.xn--0ugy6gjy5sl3ud; ; xn--4--e4j7831r.xn--gdh8754cz40c; [B1, P1, V5, V6] # 4်-𐹸.ꨩ𐹴≮
+4်-𐹸。ꨩ‌𐹴≮; 4်-𐹸.ꨩ‌𐹴≮; [B1, C1, P1, V5, V6]; xn--4--e4j7831r.xn--0ugy6gjy5sl3ud; ; xn--4--e4j7831r.xn--gdh8754cz40c; [B1, P1, V5, V6] # 4်-𐹸.ꨩ𐹴≮
+4်-𐹸。ꨩ‌𐹴≮; 4်-𐹸.ꨩ‌𐹴≮; [B1, C1, P1, V5, V6]; xn--4--e4j7831r.xn--0ugy6gjy5sl3ud; ; xn--4--e4j7831r.xn--gdh8754cz40c; [B1, P1, V5, V6] # 4်-𐹸.ꨩ𐹴≮
+xn--4--e4j7831r.xn--gdh8754cz40c; 4်-𐹸.ꨩ𐹴≮; [B1, V5, V6]; xn--4--e4j7831r.xn--gdh8754cz40c; ; ; # 4်-𐹸.ꨩ𐹴≮
+xn--4--e4j7831r.xn--0ugy6gjy5sl3ud; 4်-𐹸.ꨩ‌𐹴≮; [B1, C1, V5, V6]; xn--4--e4j7831r.xn--0ugy6gjy5sl3ud; ; ; # 4်-𐹸.ꨩ𐹴≮
+‌。ᅠ྄ྖ; ‌.ᅠ྄ྖ; [C1, P1, V6]; xn--0ug.xn--3ed0by082k; ; .xn--3ed0by082k; [P1, V6, A4_2] # .྄ྖ
+‌。ᅠ྄ྖ; ‌.ᅠ྄ྖ; [C1, P1, V6]; xn--0ug.xn--3ed0b20h; ; .xn--3ed0b20h; [P1, V6, A4_2] # .྄ྖ
+.xn--3ed0b20h; .ᅠ྄ྖ; [V6, X4_2]; .xn--3ed0b20h; [V6, A4_2]; ; # .྄ྖ
+xn--0ug.xn--3ed0b20h; ‌.ᅠ྄ྖ; [C1, V6]; xn--0ug.xn--3ed0b20h; ; ; # .྄ྖ
+.xn--3ed0by082k; .ᅠ྄ྖ; [V6, X4_2]; .xn--3ed0by082k; [V6, A4_2]; ; # .྄ྖ
+xn--0ug.xn--3ed0by082k; ‌.ᅠ྄ྖ; [C1, V6]; xn--0ug.xn--3ed0by082k; ; ; # .྄ྖ
+≯򍘅.‍𐅼򲇛; ≯򍘅.‍𐅼򲇛; [C2, P1, V6]; xn--hdh84488f.xn--1ug8099fbjp4e; ; xn--hdh84488f.xn--xy7cw2886b; [P1, V6] # ≯.𐅼
+≯򍘅.‍𐅼򲇛; ≯򍘅.‍𐅼򲇛; [C2, P1, V6]; xn--hdh84488f.xn--1ug8099fbjp4e; ; xn--hdh84488f.xn--xy7cw2886b; [P1, V6] # ≯.𐅼
+≯򍘅.‍𐅼򲇛; ; [C2, P1, V6]; xn--hdh84488f.xn--1ug8099fbjp4e; ; xn--hdh84488f.xn--xy7cw2886b; [P1, V6] # ≯.𐅼
+≯򍘅.‍𐅼򲇛; ≯򍘅.‍𐅼򲇛; [C2, P1, V6]; xn--hdh84488f.xn--1ug8099fbjp4e; ; xn--hdh84488f.xn--xy7cw2886b; [P1, V6] # ≯.𐅼
+xn--hdh84488f.xn--xy7cw2886b; ≯򍘅.𐅼򲇛; [V6]; xn--hdh84488f.xn--xy7cw2886b; ; ; # ≯.𐅼
+xn--hdh84488f.xn--1ug8099fbjp4e; ≯򍘅.‍𐅼򲇛; [C2, V6]; xn--hdh84488f.xn--1ug8099fbjp4e; ; ; # ≯.𐅼
+فß𐰯。𝟕𐫫; فß𐰯.7𐫫; [B1, B2]; xn--zca96ys96y.xn--7-mm5i; ; xn--ss-jvd2339x.xn--7-mm5i; # فß𐰯.7𐫫
+فß𐰯。7𐫫; فß𐰯.7𐫫; [B1, B2]; xn--zca96ys96y.xn--7-mm5i; ; xn--ss-jvd2339x.xn--7-mm5i; # فß𐰯.7𐫫
+فSS𐰯。7𐫫; فss𐰯.7𐫫; [B1, B2]; xn--ss-jvd2339x.xn--7-mm5i; ; ; # فss𐰯.7𐫫
+فss𐰯。7𐫫; فss𐰯.7𐫫; [B1, B2]; xn--ss-jvd2339x.xn--7-mm5i; ; ; # فss𐰯.7𐫫
+xn--ss-jvd2339x.xn--7-mm5i; فss𐰯.7𐫫; [B1, B2]; xn--ss-jvd2339x.xn--7-mm5i; ; ; # فss𐰯.7𐫫
+xn--zca96ys96y.xn--7-mm5i; فß𐰯.7𐫫; [B1, B2]; xn--zca96ys96y.xn--7-mm5i; ; ; # فß𐰯.7𐫫
+فSS𐰯。𝟕𐫫; فss𐰯.7𐫫; [B1, B2]; xn--ss-jvd2339x.xn--7-mm5i; ; ; # فss𐰯.7𐫫
+فss𐰯。𝟕𐫫; فss𐰯.7𐫫; [B1, B2]; xn--ss-jvd2339x.xn--7-mm5i; ; ; # فss𐰯.7𐫫
+فSs𐰯。7𐫫; فss𐰯.7𐫫; [B1, B2]; xn--ss-jvd2339x.xn--7-mm5i; ; ; # فss𐰯.7𐫫
+فSs𐰯。𝟕𐫫; فss𐰯.7𐫫; [B1, B2]; xn--ss-jvd2339x.xn--7-mm5i; ; ; # فss𐰯.7𐫫
+ßެާࢱ。𐭁􅮙𐹲; ßެާࢱ.𐭁􅮙𐹲; [B2, B5, B6, P1, V6]; xn--zca685aoa95h.xn--e09co8cr9861c; ; xn--ss-9qet02k.xn--e09co8cr9861c; # ßެާࢱ.𐭁𐹲
+SSެާࢱ。𐭁􅮙𐹲; ssެާࢱ.𐭁􅮙𐹲; [B2, B5, B6, P1, V6]; xn--ss-9qet02k.xn--e09co8cr9861c; ; ; # ssެާࢱ.𐭁𐹲
+ssެާࢱ。𐭁􅮙𐹲; ssެާࢱ.𐭁􅮙𐹲; [B2, B5, B6, P1, V6]; xn--ss-9qet02k.xn--e09co8cr9861c; ; ; # ssެާࢱ.𐭁𐹲
+Ssެާࢱ。𐭁􅮙𐹲; ssެާࢱ.𐭁􅮙𐹲; [B2, B5, B6, P1, V6]; xn--ss-9qet02k.xn--e09co8cr9861c; ; ; # ssެާࢱ.𐭁𐹲
+xn--ss-9qet02k.xn--e09co8cr9861c; ssެާࢱ.𐭁􅮙𐹲; [B2, B5, B6, V6]; xn--ss-9qet02k.xn--e09co8cr9861c; ; ; # ssެާࢱ.𐭁𐹲
+xn--zca685aoa95h.xn--e09co8cr9861c; ßެާࢱ.𐭁􅮙𐹲; [B2, B5, B6, V6]; xn--zca685aoa95h.xn--e09co8cr9861c; ; ; # ßެާࢱ.𐭁𐹲
+-。󠉗⒌𞯛; -.󠉗⒌𞯛; [B1, P1, V3, V6]; -.xn--xsh6367n1bi3e; ; ; # -.⒌
+-。󠉗5.𞯛; -.󠉗5.𞯛; [B1, P1, V3, V6]; -.xn--5-zz21m.xn--6x6h; ; ; # -.5.
+-.xn--5-zz21m.xn--6x6h; -.󠉗5.𞯛; [B1, V3, V6]; -.xn--5-zz21m.xn--6x6h; ; ; # -.5.
+-.xn--xsh6367n1bi3e; -.󠉗⒌𞯛; [B1, V3, V6]; -.xn--xsh6367n1bi3e; ; ; # -.⒌
+𼎏ς.-≮ﲫ; 𼎏ς.-≮خج; [B1, P1, V3, V6]; xn--3xa13520c.xn----9mcf1400a; ; xn--4xa92520c.xn----9mcf1400a; # ς.-≮خج
+𼎏ς.-≮ﲫ; 𼎏ς.-≮خج; [B1, P1, V3, V6]; xn--3xa13520c.xn----9mcf1400a; ; xn--4xa92520c.xn----9mcf1400a; # ς.-≮خج
+𼎏ς.-≮خج; ; [B1, P1, V3, V6]; xn--3xa13520c.xn----9mcf1400a; ; xn--4xa92520c.xn----9mcf1400a; # ς.-≮خج
+𼎏ς.-≮خج; 𼎏ς.-≮خج; [B1, P1, V3, V6]; xn--3xa13520c.xn----9mcf1400a; ; xn--4xa92520c.xn----9mcf1400a; # ς.-≮خج
+𼎏Σ.-≮خج; 𼎏σ.-≮خج; [B1, P1, V3, V6]; xn--4xa92520c.xn----9mcf1400a; ; ; # σ.-≮خج
+𼎏Σ.-≮خج; 𼎏σ.-≮خج; [B1, P1, V3, V6]; xn--4xa92520c.xn----9mcf1400a; ; ; # σ.-≮خج
+𼎏σ.-≮خج; ; [B1, P1, V3, V6]; xn--4xa92520c.xn----9mcf1400a; ; ; # σ.-≮خج
+𼎏σ.-≮خج; 𼎏σ.-≮خج; [B1, P1, V3, V6]; xn--4xa92520c.xn----9mcf1400a; ; ; # σ.-≮خج
+xn--4xa92520c.xn----9mcf1400a; 𼎏σ.-≮خج; [B1, V3, V6]; xn--4xa92520c.xn----9mcf1400a; ; ; # σ.-≮خج
+xn--3xa13520c.xn----9mcf1400a; 𼎏ς.-≮خج; [B1, V3, V6]; xn--3xa13520c.xn----9mcf1400a; ; ; # ς.-≮خج
+𼎏Σ.-≮ﲫ; 𼎏σ.-≮خج; [B1, P1, V3, V6]; xn--4xa92520c.xn----9mcf1400a; ; ; # σ.-≮خج
+𼎏Σ.-≮ﲫ; 𼎏σ.-≮خج; [B1, P1, V3, V6]; xn--4xa92520c.xn----9mcf1400a; ; ; # σ.-≮خج
+𼎏σ.-≮ﲫ; 𼎏σ.-≮خج; [B1, P1, V3, V6]; xn--4xa92520c.xn----9mcf1400a; ; ; # σ.-≮خج
+𼎏σ.-≮ﲫ; 𼎏σ.-≮خج; [B1, P1, V3, V6]; xn--4xa92520c.xn----9mcf1400a; ; ; # σ.-≮خج
+ꡗࢸܙ.񔤔󠛙్ﰾ; ꡗࢸܙ.񔤔󠛙్كي; [B5, B6, P1, V6]; xn--jnb34fs003a.xn--fhbo927bk128mpi24d; ; ; # ꡗࢸܙ.్كي
+ꡗࢸܙ.񔤔󠛙్كي; ; [B5, B6, P1, V6]; xn--jnb34fs003a.xn--fhbo927bk128mpi24d; ; ; # ꡗࢸܙ.్كي
+xn--jnb34fs003a.xn--fhbo927bk128mpi24d; ꡗࢸܙ.񔤔󠛙్كي; [B5, B6, V6]; xn--jnb34fs003a.xn--fhbo927bk128mpi24d; ; ; # ꡗࢸܙ.్كي
+𐠰ࢷ𞤌𐫭。𐋦៍𝩃; 𐠰ࢷ𞤮𐫭.𐋦៍𝩃; [B1]; xn--dzb5191kezbrw47a.xn--p4e3841jz9tf; ; ; # 𐠰ࢷ𞤮𐫭.𐋦៍𝩃
+𐠰ࢷ𞤮𐫭。𐋦៍𝩃; 𐠰ࢷ𞤮𐫭.𐋦៍𝩃; [B1]; xn--dzb5191kezbrw47a.xn--p4e3841jz9tf; ; ; # 𐠰ࢷ𞤮𐫭.𐋦៍𝩃
+xn--dzb5191kezbrw47a.xn--p4e3841jz9tf; 𐠰ࢷ𞤮𐫭.𐋦៍𝩃; [B1]; xn--dzb5191kezbrw47a.xn--p4e3841jz9tf; ; ; # 𐠰ࢷ𞤮𐫭.𐋦៍𝩃
+𐠰ࢷ𞤮𐫭.𐋦៍𝩃; ; [B1]; xn--dzb5191kezbrw47a.xn--p4e3841jz9tf; ; ; # 𐠰ࢷ𞤮𐫭.𐋦៍𝩃
+𐠰ࢷ𞤌𐫭.𐋦៍𝩃; 𐠰ࢷ𞤮𐫭.𐋦៍𝩃; [B1]; xn--dzb5191kezbrw47a.xn--p4e3841jz9tf; ; ; # 𐠰ࢷ𞤮𐫭.𐋦៍𝩃
+₂㘷--。ۓ‌𐫆𑖿; 2㘷--.ۓ‌𐫆𑖿; [B1, C1, V2, V3]; xn--2---u58b.xn--jlb820ku99nbgj; ; xn--2---u58b.xn--jlb8024k14g; [B1, V2, V3] # 2㘷--.ۓ𐫆𑖿
+₂㘷--。ۓ‌𐫆𑖿; 2㘷--.ۓ‌𐫆𑖿; [B1, C1, V2, V3]; xn--2---u58b.xn--jlb820ku99nbgj; ; xn--2---u58b.xn--jlb8024k14g; [B1, V2, V3] # 2㘷--.ۓ𐫆𑖿
+2㘷--。ۓ‌𐫆𑖿; 2㘷--.ۓ‌𐫆𑖿; [B1, C1, V2, V3]; xn--2---u58b.xn--jlb820ku99nbgj; ; xn--2---u58b.xn--jlb8024k14g; [B1, V2, V3] # 2㘷--.ۓ𐫆𑖿
+2㘷--。ۓ‌𐫆𑖿; 2㘷--.ۓ‌𐫆𑖿; [B1, C1, V2, V3]; xn--2---u58b.xn--jlb820ku99nbgj; ; xn--2---u58b.xn--jlb8024k14g; [B1, V2, V3] # 2㘷--.ۓ𐫆𑖿
+xn--2---u58b.xn--jlb8024k14g; 2㘷--.ۓ𐫆𑖿; [B1, V2, V3]; xn--2---u58b.xn--jlb8024k14g; ; ; # 2㘷--.ۓ𐫆𑖿
+xn--2---u58b.xn--jlb820ku99nbgj; 2㘷--.ۓ‌𐫆𑖿; [B1, C1, V2, V3]; xn--2---u58b.xn--jlb820ku99nbgj; ; ; # 2㘷--.ۓ𐫆𑖿
+-𘊻.ᡮح-; -𘊻.ᡮح-; [B1, B5, B6, V3]; xn----bp5n.xn----bnc231l; ; ; # -𘊻.ᡮح-
+-𘊻.ᡮح-; ; [B1, B5, B6, V3]; xn----bp5n.xn----bnc231l; ; ; # -𘊻.ᡮح-
+xn----bp5n.xn----bnc231l; -𘊻.ᡮح-; [B1, B5, B6, V3]; xn----bp5n.xn----bnc231l; ; ; # -𘊻.ᡮح-
+‌-ß。ᢣ𐹭ؿ; ‌-ß.ᢣ𐹭ؿ; [B1, B5, B6, C1]; xn----qfa550v.xn--bhb925glx3p; ; -ss.xn--bhb925glx3p; [B1, B5, B6, V3] # -ß.ᢣ𐹭ؿ
+‌-ß。ᢣ𐹭ؿ; ‌-ß.ᢣ𐹭ؿ; [B1, B5, B6, C1]; xn----qfa550v.xn--bhb925glx3p; ; -ss.xn--bhb925glx3p; [B1, B5, B6, V3] # -ß.ᢣ𐹭ؿ
+‌-SS。ᢣ𐹭ؿ; ‌-ss.ᢣ𐹭ؿ; [B1, B5, B6, C1]; xn---ss-8m0a.xn--bhb925glx3p; ; -ss.xn--bhb925glx3p; [B1, B5, B6, V3] # -ss.ᢣ𐹭ؿ
+‌-ss。ᢣ𐹭ؿ; ‌-ss.ᢣ𐹭ؿ; [B1, B5, B6, C1]; xn---ss-8m0a.xn--bhb925glx3p; ; -ss.xn--bhb925glx3p; [B1, B5, B6, V3] # -ss.ᢣ𐹭ؿ
+‌-Ss。ᢣ𐹭ؿ; ‌-ss.ᢣ𐹭ؿ; [B1, B5, B6, C1]; xn---ss-8m0a.xn--bhb925glx3p; ; -ss.xn--bhb925glx3p; [B1, B5, B6, V3] # -ss.ᢣ𐹭ؿ
+-ss.xn--bhb925glx3p; -ss.ᢣ𐹭ؿ; [B1, B5, B6, V3]; -ss.xn--bhb925glx3p; ; ; # -ss.ᢣ𐹭ؿ
+xn---ss-8m0a.xn--bhb925glx3p; ‌-ss.ᢣ𐹭ؿ; [B1, B5, B6, C1]; xn---ss-8m0a.xn--bhb925glx3p; ; ; # -ss.ᢣ𐹭ؿ
+xn----qfa550v.xn--bhb925glx3p; ‌-ß.ᢣ𐹭ؿ; [B1, B5, B6, C1]; xn----qfa550v.xn--bhb925glx3p; ; ; # -ß.ᢣ𐹭ؿ
+‌-SS。ᢣ𐹭ؿ; ‌-ss.ᢣ𐹭ؿ; [B1, B5, B6, C1]; xn---ss-8m0a.xn--bhb925glx3p; ; -ss.xn--bhb925glx3p; [B1, B5, B6, V3] # -ss.ᢣ𐹭ؿ
+‌-ss。ᢣ𐹭ؿ; ‌-ss.ᢣ𐹭ؿ; [B1, B5, B6, C1]; xn---ss-8m0a.xn--bhb925glx3p; ; -ss.xn--bhb925glx3p; [B1, B5, B6, V3] # -ss.ᢣ𐹭ؿ
+‌-Ss。ᢣ𐹭ؿ; ‌-ss.ᢣ𐹭ؿ; [B1, B5, B6, C1]; xn---ss-8m0a.xn--bhb925glx3p; ; -ss.xn--bhb925glx3p; [B1, B5, B6, V3] # -ss.ᢣ𐹭ؿ
+꧐Ӏ᮪ࣶ.눵; ꧐Ӏ᮪ࣶ.눵; [P1, V6]; xn--d5a07sn4u297k.xn--2e1b; ; ; # ꧐Ӏ᮪ࣶ.눵
+꧐Ӏ᮪ࣶ.눵; ꧐Ӏ᮪ࣶ.눵; [P1, V6]; xn--d5a07sn4u297k.xn--2e1b; ; ; # ꧐Ӏ᮪ࣶ.눵
+꧐Ӏ᮪ࣶ.눵; ; [P1, V6]; xn--d5a07sn4u297k.xn--2e1b; ; ; # ꧐Ӏ᮪ࣶ.눵
+꧐Ӏ᮪ࣶ.눵; ꧐Ӏ᮪ࣶ.눵; [P1, V6]; xn--d5a07sn4u297k.xn--2e1b; ; ; # ꧐Ӏ᮪ࣶ.눵
+꧐ӏ᮪ࣶ.눵; ꧐ӏ᮪ࣶ.눵; ; xn--s5a04sn4u297k.xn--2e1b; ; ; # ꧐ӏ᮪ࣶ.눵
+꧐ӏ᮪ࣶ.눵; ; ; xn--s5a04sn4u297k.xn--2e1b; ; ; # ꧐ӏ᮪ࣶ.눵
+xn--s5a04sn4u297k.xn--2e1b; ꧐ӏ᮪ࣶ.눵; ; xn--s5a04sn4u297k.xn--2e1b; ; ; # ꧐ӏ᮪ࣶ.눵
+xn--d5a07sn4u297k.xn--2e1b; ꧐Ӏ᮪ࣶ.눵; [V6]; xn--d5a07sn4u297k.xn--2e1b; ; ; # ꧐Ӏ᮪ࣶ.눵
+꧐ӏ᮪ࣶ.눵; ꧐ӏ᮪ࣶ.눵; ; xn--s5a04sn4u297k.xn--2e1b; ; ; # ꧐ӏ᮪ࣶ.눵
+꧐ӏ᮪ࣶ.눵; ꧐ӏ᮪ࣶ.눵; ; xn--s5a04sn4u297k.xn--2e1b; ; ; # ꧐ӏ᮪ࣶ.눵
+꣪。𖄿𑆾󠇗; ꣪.𖄿𑆾; [P1, V5, V6]; xn--3g9a.xn--ud1dz07k; ; ; # ꣪.𑆾
+꣪。𖄿𑆾󠇗; ꣪.𖄿𑆾; [P1, V5, V6]; xn--3g9a.xn--ud1dz07k; ; ; # ꣪.𑆾
+xn--3g9a.xn--ud1dz07k; ꣪.𖄿𑆾; [V5, V6]; xn--3g9a.xn--ud1dz07k; ; ; # ꣪.𑆾
+󇓓𑚳。񐷿≯⾇; 󇓓𑚳.񐷿≯舛; [P1, V6]; xn--3e2d79770c.xn--hdh0088abyy1c; ; ; # 𑚳.≯舛
+󇓓𑚳。񐷿≯⾇; 󇓓𑚳.񐷿≯舛; [P1, V6]; xn--3e2d79770c.xn--hdh0088abyy1c; ; ; # 𑚳.≯舛
+󇓓𑚳。񐷿≯舛; 󇓓𑚳.񐷿≯舛; [P1, V6]; xn--3e2d79770c.xn--hdh0088abyy1c; ; ; # 𑚳.≯舛
+󇓓𑚳。񐷿≯舛; 󇓓𑚳.񐷿≯舛; [P1, V6]; xn--3e2d79770c.xn--hdh0088abyy1c; ; ; # 𑚳.≯舛
+xn--3e2d79770c.xn--hdh0088abyy1c; 󇓓𑚳.񐷿≯舛; [V6]; xn--3e2d79770c.xn--hdh0088abyy1c; ; ; # 𑚳.≯舛
+𐫇١‌.‍‌; 𐫇١‌.‍‌; [B1, B3, C1, C2]; xn--9hb652kv99n.xn--0ugb; ; xn--9hb7344k.; [] # 𐫇١.
+𐫇١‌.‍‌; ; [B1, B3, C1, C2]; xn--9hb652kv99n.xn--0ugb; ; xn--9hb7344k.; [] # 𐫇١.
+xn--9hb7344k.; 𐫇١.; ; xn--9hb7344k.; ; ; # 𐫇١.
+𐫇١.; ; ; xn--9hb7344k.; ; ; # 𐫇١.
+xn--9hb652kv99n.xn--0ugb; 𐫇١‌.‍‌; [B1, B3, C1, C2]; xn--9hb652kv99n.xn--0ugb; ; ; # 𐫇١.
+񡅈砪≯ᢑ。≯𝩚򓴔‌; 񡅈砪≯ᢑ.≯𝩚򓴔‌; [C1, P1, V6]; xn--bbf561cf95e57y3e.xn--0ugz6gc910ejro8c; ; xn--bbf561cf95e57y3e.xn--hdh0834o7mj6b; [P1, V6] # 砪≯ᢑ.≯𝩚
+񡅈砪≯ᢑ。≯𝩚򓴔‌; 񡅈砪≯ᢑ.≯𝩚򓴔‌; [C1, P1, V6]; xn--bbf561cf95e57y3e.xn--0ugz6gc910ejro8c; ; xn--bbf561cf95e57y3e.xn--hdh0834o7mj6b; [P1, V6] # 砪≯ᢑ.≯𝩚
+񡅈砪≯ᢑ。≯𝩚򓴔‌; 񡅈砪≯ᢑ.≯𝩚򓴔‌; [C1, P1, V6]; xn--bbf561cf95e57y3e.xn--0ugz6gc910ejro8c; ; xn--bbf561cf95e57y3e.xn--hdh0834o7mj6b; [P1, V6] # 砪≯ᢑ.≯𝩚
+񡅈砪≯ᢑ。≯𝩚򓴔‌; 񡅈砪≯ᢑ.≯𝩚򓴔‌; [C1, P1, V6]; xn--bbf561cf95e57y3e.xn--0ugz6gc910ejro8c; ; xn--bbf561cf95e57y3e.xn--hdh0834o7mj6b; [P1, V6] # 砪≯ᢑ.≯𝩚
+xn--bbf561cf95e57y3e.xn--hdh0834o7mj6b; 񡅈砪≯ᢑ.≯𝩚򓴔; [V6]; xn--bbf561cf95e57y3e.xn--hdh0834o7mj6b; ; ; # 砪≯ᢑ.≯𝩚
+xn--bbf561cf95e57y3e.xn--0ugz6gc910ejro8c; 񡅈砪≯ᢑ.≯𝩚򓴔‌; [C1, V6]; xn--bbf561cf95e57y3e.xn--0ugz6gc910ejro8c; ; ; # 砪≯ᢑ.≯𝩚
+Ⴥ.𑄳㊸; Ⴥ.𑄳43; [P1, V5, V6]; xn--9nd.xn--43-274o; ; ; # Ⴥ.𑄳43
+Ⴥ.𑄳43; ; [P1, V5, V6]; xn--9nd.xn--43-274o; ; ; # Ⴥ.𑄳43
+ⴥ.𑄳43; ; [V5]; xn--tlj.xn--43-274o; ; ; # ⴥ.𑄳43
+xn--tlj.xn--43-274o; ⴥ.𑄳43; [V5]; xn--tlj.xn--43-274o; ; ; # ⴥ.𑄳43
+xn--9nd.xn--43-274o; Ⴥ.𑄳43; [V5, V6]; xn--9nd.xn--43-274o; ; ; # Ⴥ.𑄳43
+ⴥ.𑄳㊸; ⴥ.𑄳43; [V5]; xn--tlj.xn--43-274o; ; ; # ⴥ.𑄳43
+𝟎٣。Ⴒᡇࣲ𐹠; 0٣.Ⴒᡇࣲ𐹠; [B1, B5, B6, P1, V6]; xn--0-fqc.xn--10b180bnwgfy0z; ; ; # 0٣.Ⴒᡇࣲ𐹠
+0٣。Ⴒᡇࣲ𐹠; 0٣.Ⴒᡇࣲ𐹠; [B1, B5, B6, P1, V6]; xn--0-fqc.xn--10b180bnwgfy0z; ; ; # 0٣.Ⴒᡇࣲ𐹠
+0٣。ⴒᡇࣲ𐹠; 0٣.ⴒᡇࣲ𐹠; [B1, B5, B6]; xn--0-fqc.xn--10b369eivp359r; ; ; # 0٣.ⴒᡇࣲ𐹠
+xn--0-fqc.xn--10b369eivp359r; 0٣.ⴒᡇࣲ𐹠; [B1, B5, B6]; xn--0-fqc.xn--10b369eivp359r; ; ; # 0٣.ⴒᡇࣲ𐹠
+xn--0-fqc.xn--10b180bnwgfy0z; 0٣.Ⴒᡇࣲ𐹠; [B1, B5, B6, V6]; xn--0-fqc.xn--10b180bnwgfy0z; ; ; # 0٣.Ⴒᡇࣲ𐹠
+𝟎٣。ⴒᡇࣲ𐹠; 0٣.ⴒᡇࣲ𐹠; [B1, B5, B6]; xn--0-fqc.xn--10b369eivp359r; ; ; # 0٣.ⴒᡇࣲ𐹠
+񗪨󠄉ᅠྷ.񸞰꥓; 񗪨ᅠྷ.񸞰꥓; [P1, V6]; xn--kgd7493jee34a.xn--3j9au7544a; ; ; # ྷ.꥓
+񗪨󠄉ᅠྷ.񸞰꥓; 񗪨ᅠྷ.񸞰꥓; [P1, V6]; xn--kgd36f9z57y.xn--3j9au7544a; ; ; # ྷ.꥓
+xn--kgd36f9z57y.xn--3j9au7544a; 񗪨ᅠྷ.񸞰꥓; [V6]; xn--kgd36f9z57y.xn--3j9au7544a; ; ; # ྷ.꥓
+xn--kgd7493jee34a.xn--3j9au7544a; 񗪨ᅠྷ.񸞰꥓; [V6]; xn--kgd7493jee34a.xn--3j9au7544a; ; ; # ྷ.꥓
+ؘ.۳‌꥓; ; [C1, V5]; xn--6fb.xn--gmb469jjf1h; ; xn--6fb.xn--gmb0524f; [V5] # ؘ.۳꥓
+xn--6fb.xn--gmb0524f; ؘ.۳꥓; [V5]; xn--6fb.xn--gmb0524f; ; ; # ؘ.۳꥓
+xn--6fb.xn--gmb469jjf1h; ؘ.۳‌꥓; [C1, V5]; xn--6fb.xn--gmb469jjf1h; ; ; # ؘ.۳꥓
+ᡌ.︒ᢑ; ᡌ.︒ᢑ; [P1, V6]; xn--c8e.xn--bbf9168i; ; ; # ᡌ.︒ᢑ
+ᡌ.。ᢑ; ᡌ..ᢑ; [X4_2]; xn--c8e..xn--bbf; [A4_2]; ; # ᡌ..ᢑ
+xn--c8e..xn--bbf; ᡌ..ᢑ; [X4_2]; xn--c8e..xn--bbf; [A4_2]; ; # ᡌ..ᢑ
+xn--c8e.xn--bbf9168i; ᡌ.︒ᢑ; [V6]; xn--c8e.xn--bbf9168i; ; ; # ᡌ.︒ᢑ
+𑋪ၳ。𞽧; 𑋪ၳ.𞽧; [B1, B3, B6, P1, V5, V6]; xn--xld7443k.xn--4o7h; ; ; # 𑋪ၳ.
+𑋪ၳ。𞽧; 𑋪ၳ.𞽧; [B1, B3, B6, P1, V5, V6]; xn--xld7443k.xn--4o7h; ; ; # 𑋪ၳ.
+xn--xld7443k.xn--4o7h; 𑋪ၳ.𞽧; [B1, B3, B6, V5, V6]; xn--xld7443k.xn--4o7h; ; ; # 𑋪ၳ.
+𞷏。ᠢ򓘆; 𞷏.ᠢ򓘆; [P1, V6]; xn--hd7h.xn--46e66060j; ; ; # .ᠢ
+xn--hd7h.xn--46e66060j; 𞷏.ᠢ򓘆; [V6]; xn--hd7h.xn--46e66060j; ; ; # .ᠢ
+𑄳㴼.‌𐹡⃫񫺦; 𑄳㴼.‌𐹡⃫񫺦; [B1, C1, P1, V5, V6]; xn--iym9428c.xn--0ug46a7218cllv0c; ; xn--iym9428c.xn--e1g3464g08p3b; [B1, P1, V5, V6] # 𑄳㴼.𐹡⃫
+𑄳㴼.‌𐹡⃫񫺦; ; [B1, C1, P1, V5, V6]; xn--iym9428c.xn--0ug46a7218cllv0c; ; xn--iym9428c.xn--e1g3464g08p3b; [B1, P1, V5, V6] # 𑄳㴼.𐹡⃫
+xn--iym9428c.xn--e1g3464g08p3b; 𑄳㴼.𐹡⃫񫺦; [B1, V5, V6]; xn--iym9428c.xn--e1g3464g08p3b; ; ; # 𑄳㴼.𐹡⃫
+xn--iym9428c.xn--0ug46a7218cllv0c; 𑄳㴼.‌𐹡⃫񫺦; [B1, C1, V5, V6]; xn--iym9428c.xn--0ug46a7218cllv0c; ; ; # 𑄳㴼.𐹡⃫
+񠻟𐹳𑈯。̝; 񠻟𐹳𑈯.̝; [B1, B3, B5, B6, P1, V5, V6]; xn--ro0dw7dey96m.xn--eta; ; ; # 𐹳𑈯.̝
+񠻟𐹳𑈯。̝; 񠻟𐹳𑈯.̝; [B1, B3, B5, B6, P1, V5, V6]; xn--ro0dw7dey96m.xn--eta; ; ; # 𐹳𑈯.̝
+xn--ro0dw7dey96m.xn--eta; 񠻟𐹳𑈯.̝; [B1, B3, B5, B6, V5, V6]; xn--ro0dw7dey96m.xn--eta; ; ; # 𐹳𑈯.̝
+ᢊ뾜󠱴𑚶。࢝𐹥; ᢊ뾜󠱴𑚶.࢝𐹥; [B1, P1, V5, V6]; xn--39e4566fjv8bwmt6n.xn--myb6415k; ; ; # ᢊ뾜𑚶.࢝𐹥
+ᢊ뾜󠱴𑚶。࢝𐹥; ᢊ뾜󠱴𑚶.࢝𐹥; [B1, P1, V5, V6]; xn--39e4566fjv8bwmt6n.xn--myb6415k; ; ; # ᢊ뾜𑚶.࢝𐹥
+xn--39e4566fjv8bwmt6n.xn--myb6415k; ᢊ뾜󠱴𑚶.࢝𐹥; [B1, V5, V6]; xn--39e4566fjv8bwmt6n.xn--myb6415k; ; ; # ᢊ뾜𑚶.࢝𐹥
+𐹥≠。𐋲󠧠‌; 𐹥≠.𐋲󠧠‌; [B1, C1, P1, V6]; xn--1ch6704g.xn--0ug3840g51u4g; ; xn--1ch6704g.xn--m97cw2999c; [B1, P1, V6] # 𐹥≠.𐋲
+𐹥≠。𐋲󠧠‌; 𐹥≠.𐋲󠧠‌; [B1, C1, P1, V6]; xn--1ch6704g.xn--0ug3840g51u4g; ; xn--1ch6704g.xn--m97cw2999c; [B1, P1, V6] # 𐹥≠.𐋲
+𐹥≠。𐋲󠧠‌; 𐹥≠.𐋲󠧠‌; [B1, C1, P1, V6]; xn--1ch6704g.xn--0ug3840g51u4g; ; xn--1ch6704g.xn--m97cw2999c; [B1, P1, V6] # 𐹥≠.𐋲
+𐹥≠。𐋲󠧠‌; 𐹥≠.𐋲󠧠‌; [B1, C1, P1, V6]; xn--1ch6704g.xn--0ug3840g51u4g; ; xn--1ch6704g.xn--m97cw2999c; [B1, P1, V6] # 𐹥≠.𐋲
+xn--1ch6704g.xn--m97cw2999c; 𐹥≠.𐋲󠧠; [B1, V6]; xn--1ch6704g.xn--m97cw2999c; ; ; # 𐹥≠.𐋲
+xn--1ch6704g.xn--0ug3840g51u4g; 𐹥≠.𐋲󠧠‌; [B1, C1, V6]; xn--1ch6704g.xn--0ug3840g51u4g; ; ; # 𐹥≠.𐋲
+ᅟ񙯠्.‍꥓𐪤; ᅟ񙯠्.‍꥓𐪤; [B1, C2, P1, V6]; xn--n3b542bb085j.xn--1ug6815co9wc; ; xn--n3b542bb085j.xn--3j9al95p; [B5, B6, P1, V5, V6] # ्.꥓
+ᅟ񙯠्.‍꥓𐪤; ; [B1, C2, P1, V6]; xn--n3b542bb085j.xn--1ug6815co9wc; ; xn--n3b542bb085j.xn--3j9al95p; [B5, B6, P1, V5, V6] # ्.꥓
+xn--n3b542bb085j.xn--3j9al95p; ᅟ񙯠्.꥓𐪤; [B5, B6, V5, V6]; xn--n3b542bb085j.xn--3j9al95p; ; ; # ्.꥓
+xn--n3b542bb085j.xn--1ug6815co9wc; ᅟ񙯠्.‍꥓𐪤; [B1, C2, V6]; xn--n3b542bb085j.xn--1ug6815co9wc; ; ; # ्.꥓
+򌋔󠆎󠆗𑲕。≮; 򌋔𑲕.≮; [P1, V6]; xn--4m3dv4354a.xn--gdh; ; ; # 𑲕.≮
+򌋔󠆎󠆗𑲕。≮; 򌋔𑲕.≮; [P1, V6]; xn--4m3dv4354a.xn--gdh; ; ; # 𑲕.≮
+xn--4m3dv4354a.xn--gdh; 򌋔𑲕.≮; [V6]; xn--4m3dv4354a.xn--gdh; ; ; # 𑲕.≮
+󠆦.ࣣ暀≠; .ࣣ暀≠; [P1, V5, V6, X4_2]; .xn--m0b461k3g2c; [P1, V5, V6, A4_2]; ; # .ࣣ暀≠
+󠆦.ࣣ暀≠; .ࣣ暀≠; [P1, V5, V6, X4_2]; .xn--m0b461k3g2c; [P1, V5, V6, A4_2]; ; # .ࣣ暀≠
+.xn--m0b461k3g2c; .ࣣ暀≠; [V5, V6, X4_2]; .xn--m0b461k3g2c; [V5, V6, A4_2]; ; # .ࣣ暀≠
+𐡤꯭。ﴰ򜖅ᷰ; 𐡤꯭.شم򜖅ᷰ; [B2, B3, P1, V6]; xn--429ak76o.xn--zgb8a701kox37t; ; ; # 𐡤꯭.شمᷰ
+𐡤꯭。شم򜖅ᷰ; 𐡤꯭.شم򜖅ᷰ; [B2, B3, P1, V6]; xn--429ak76o.xn--zgb8a701kox37t; ; ; # 𐡤꯭.شمᷰ
+xn--429ak76o.xn--zgb8a701kox37t; 𐡤꯭.شم򜖅ᷰ; [B2, B3, V6]; xn--429ak76o.xn--zgb8a701kox37t; ; ; # 𐡤꯭.شمᷰ
+𝉃‍⒈。Ⴌ𞱓; 𝉃‍⒈.Ⴌ𞱓; [B1, B5, B6, C2, P1, V5, V6]; xn--1ug68oq348b.xn--knd8464v; ; xn--tshz828m.xn--knd8464v; [B1, B5, B6, P1, V5, V6] # 𝉃⒈.Ⴌ
+𝉃‍1.。Ⴌ𞱓; 𝉃‍1..Ⴌ𞱓; [B1, B5, B6, C2, P1, V5, V6, X4_2]; xn--1-tgn9827q..xn--knd8464v; [B1, B5, B6, C2, P1, V5, V6, A4_2]; xn--1-px8q..xn--knd8464v; [B1, B5, B6, P1, V5, V6, A4_2] # 𝉃1..Ⴌ
+𝉃‍1.。ⴌ𞱓; 𝉃‍1..ⴌ𞱓; [B1, B5, B6, C2, P1, V5, V6, X4_2]; xn--1-tgn9827q..xn--3kj4524l; [B1, B5, B6, C2, P1, V5, V6, A4_2]; xn--1-px8q..xn--3kj4524l; [B1, B5, B6, P1, V5, V6, A4_2] # 𝉃1..ⴌ
+xn--1-px8q..xn--3kj4524l; 𝉃1..ⴌ𞱓; [B1, B5, B6, V5, V6, X4_2]; xn--1-px8q..xn--3kj4524l; [B1, B5, B6, V5, V6, A4_2]; ; # 𝉃1..ⴌ
+xn--1-tgn9827q..xn--3kj4524l; 𝉃‍1..ⴌ𞱓; [B1, B5, B6, C2, V5, V6, X4_2]; xn--1-tgn9827q..xn--3kj4524l; [B1, B5, B6, C2, V5, V6, A4_2]; ; # 𝉃1..ⴌ
+xn--1-px8q..xn--knd8464v; 𝉃1..Ⴌ𞱓; [B1, B5, B6, V5, V6, X4_2]; xn--1-px8q..xn--knd8464v; [B1, B5, B6, V5, V6, A4_2]; ; # 𝉃1..Ⴌ
+xn--1-tgn9827q..xn--knd8464v; 𝉃‍1..Ⴌ𞱓; [B1, B5, B6, C2, V5, V6, X4_2]; xn--1-tgn9827q..xn--knd8464v; [B1, B5, B6, C2, V5, V6, A4_2]; ; # 𝉃1..Ⴌ
+𝉃‍⒈。ⴌ𞱓; 𝉃‍⒈.ⴌ𞱓; [B1, B5, B6, C2, P1, V5, V6]; xn--1ug68oq348b.xn--3kj4524l; ; xn--tshz828m.xn--3kj4524l; [B1, B5, B6, P1, V5, V6] # 𝉃⒈.ⴌ
+xn--tshz828m.xn--3kj4524l; 𝉃⒈.ⴌ𞱓; [B1, B5, B6, V5, V6]; xn--tshz828m.xn--3kj4524l; ; ; # 𝉃⒈.ⴌ
+xn--1ug68oq348b.xn--3kj4524l; 𝉃‍⒈.ⴌ𞱓; [B1, B5, B6, C2, V5, V6]; xn--1ug68oq348b.xn--3kj4524l; ; ; # 𝉃⒈.ⴌ
+xn--tshz828m.xn--knd8464v; 𝉃⒈.Ⴌ𞱓; [B1, B5, B6, V5, V6]; xn--tshz828m.xn--knd8464v; ; ; # 𝉃⒈.Ⴌ
+xn--1ug68oq348b.xn--knd8464v; 𝉃‍⒈.Ⴌ𞱓; [B1, B5, B6, C2, V5, V6]; xn--1ug68oq348b.xn--knd8464v; ; ; # 𝉃⒈.Ⴌ
+󠣙੍𱫘𞤸.ς񵯞􈰔; ; [B1, P1, V6]; xn--ybc0236vjvxgt5q0g.xn--3xa03737giye6b; ; xn--ybc0236vjvxgt5q0g.xn--4xa82737giye6b; # ੍𞤸.ς
+󠣙੍𱫘𞤖.Σ񵯞􈰔; 󠣙੍𱫘𞤸.σ񵯞􈰔; [B1, P1, V6]; xn--ybc0236vjvxgt5q0g.xn--4xa82737giye6b; ; ; # ੍𞤸.σ
+󠣙੍𱫘𞤸.σ񵯞􈰔; ; [B1, P1, V6]; xn--ybc0236vjvxgt5q0g.xn--4xa82737giye6b; ; ; # ੍𞤸.σ
+󠣙੍𱫘𞤖.σ񵯞􈰔; 󠣙੍𱫘𞤸.σ񵯞􈰔; [B1, P1, V6]; xn--ybc0236vjvxgt5q0g.xn--4xa82737giye6b; ; ; # ੍𞤸.σ
+xn--ybc0236vjvxgt5q0g.xn--4xa82737giye6b; 󠣙੍𱫘𞤸.σ񵯞􈰔; [B1, V6]; xn--ybc0236vjvxgt5q0g.xn--4xa82737giye6b; ; ; # ੍𞤸.σ
+󠣙੍𱫘𞤖.ς񵯞􈰔; 󠣙੍𱫘𞤸.ς񵯞􈰔; [B1, P1, V6]; xn--ybc0236vjvxgt5q0g.xn--3xa03737giye6b; ; xn--ybc0236vjvxgt5q0g.xn--4xa82737giye6b; # ੍𞤸.ς
+xn--ybc0236vjvxgt5q0g.xn--3xa03737giye6b; 󠣙੍𱫘𞤸.ς񵯞􈰔; [B1, V6]; xn--ybc0236vjvxgt5q0g.xn--3xa03737giye6b; ; ; # ੍𞤸.ς
+󠣙੍𱫘𞤸.Σ񵯞􈰔; 󠣙੍𱫘𞤸.σ񵯞􈰔; [B1, P1, V6]; xn--ybc0236vjvxgt5q0g.xn--4xa82737giye6b; ; ; # ੍𞤸.σ
+ߓ。‌𐫀򞭱; ߓ.‌𐫀򞭱; [B1, C1, P1, V6]; xn--usb.xn--0ug9553gm3v5d; ; xn--usb.xn--pw9ci1099a; [B2, B3, P1, V6] # ߓ.𐫀
+xn--usb.xn--pw9ci1099a; ߓ.𐫀򞭱; [B2, B3, V6]; xn--usb.xn--pw9ci1099a; ; ; # ߓ.𐫀
+xn--usb.xn--0ug9553gm3v5d; ߓ.‌𐫀򞭱; [B1, C1, V6]; xn--usb.xn--0ug9553gm3v5d; ; ; # ߓ.𐫀
+ᰮ𞀝.֦ꡟ𞤕󠆖; ᰮ𞀝.֦ꡟ𞤷; [B1, B3, B6, V5]; xn--q1f4493q.xn--xcb8244fifvj; ; ; # ᰮ𞀝.֦ꡟ𞤷
+ᰮ𞀝.֦ꡟ𞤷󠆖; ᰮ𞀝.֦ꡟ𞤷; [B1, B3, B6, V5]; xn--q1f4493q.xn--xcb8244fifvj; ; ; # ᰮ𞀝.֦ꡟ𞤷
+xn--q1f4493q.xn--xcb8244fifvj; ᰮ𞀝.֦ꡟ𞤷; [B1, B3, B6, V5]; xn--q1f4493q.xn--xcb8244fifvj; ; ; # ᰮ𞀝.֦ꡟ𞤷
+䂹󾖅𐋦.‍; 䂹󾖅𐋦.‍; [C2, P1, V6]; xn--0on3543c5981i.xn--1ug; ; xn--0on3543c5981i.; [P1, V6] # 䂹𐋦.
+䂹󾖅𐋦.‍; ; [C2, P1, V6]; xn--0on3543c5981i.xn--1ug; ; xn--0on3543c5981i.; [P1, V6] # 䂹𐋦.
+xn--0on3543c5981i.; 䂹󾖅𐋦.; [V6]; xn--0on3543c5981i.; ; ; # 䂹𐋦.
+xn--0on3543c5981i.xn--1ug; 䂹󾖅𐋦.‍; [C2, V6]; xn--0on3543c5981i.xn--1ug; ; ; # 䂹𐋦.
+꧀‌𐹲‌。ݧ🄉; ꧀‌𐹲‌.ݧ🄉; [B5, B6, C1, P1, V5, V6]; xn--0uga8686hdgvd.xn--rpb6081w; ; xn--7m9an32q.xn--rpb6081w; [B5, B6, P1, V5, V6] # ꧀𐹲.ݧ🄉
+꧀‌𐹲‌。ݧ8,; ꧀‌𐹲‌.ݧ8,; [B3, B5, B6, C1, P1, V5, V6]; xn--0uga8686hdgvd.xn--8,-qle; ; xn--7m9an32q.xn--8,-qle; [B3, B5, B6, P1, V5, V6] # ꧀𐹲.ݧ8,
+xn--7m9an32q.xn--8,-qle; ꧀𐹲.ݧ8,; [B3, B5, B6, P1, V5, V6]; xn--7m9an32q.xn--8,-qle; ; ; # ꧀𐹲.ݧ8,
+xn--0uga8686hdgvd.xn--8,-qle; ꧀‌𐹲‌.ݧ8,; [B3, B5, B6, C1, P1, V5, V6]; xn--0uga8686hdgvd.xn--8,-qle; ; ; # ꧀𐹲.ݧ8,
+xn--7m9an32q.xn--rpb6081w; ꧀𐹲.ݧ🄉; [B5, B6, V5, V6]; xn--7m9an32q.xn--rpb6081w; ; ; # ꧀𐹲.ݧ🄉
+xn--0uga8686hdgvd.xn--rpb6081w; ꧀‌𐹲‌.ݧ🄉; [B5, B6, C1, V5, V6]; xn--0uga8686hdgvd.xn--rpb6081w; ; ; # ꧀𐹲.ݧ🄉
+︒。Ⴃ≯; ︒.Ⴃ≯; [P1, V6]; xn--y86c.xn--bnd622g; ; ; # ︒.Ⴃ≯
+︒。Ⴃ≯; ︒.Ⴃ≯; [P1, V6]; xn--y86c.xn--bnd622g; ; ; # ︒.Ⴃ≯
+。。Ⴃ≯; ..Ⴃ≯; [P1, V6, X4_2]; ..xn--bnd622g; [P1, V6, A4_2]; ; # ..Ⴃ≯
+。。Ⴃ≯; ..Ⴃ≯; [P1, V6, X4_2]; ..xn--bnd622g; [P1, V6, A4_2]; ; # ..Ⴃ≯
+。。ⴃ≯; ..ⴃ≯; [P1, V6, X4_2]; ..xn--hdh782b; [P1, V6, A4_2]; ; # ..ⴃ≯
+。。ⴃ≯; ..ⴃ≯; [P1, V6, X4_2]; ..xn--hdh782b; [P1, V6, A4_2]; ; # ..ⴃ≯
+..xn--hdh782b; ..ⴃ≯; [V6, X4_2]; ..xn--hdh782b; [V6, A4_2]; ; # ..ⴃ≯
+..xn--bnd622g; ..Ⴃ≯; [V6, X4_2]; ..xn--bnd622g; [V6, A4_2]; ; # ..Ⴃ≯
+︒。ⴃ≯; ︒.ⴃ≯; [P1, V6]; xn--y86c.xn--hdh782b; ; ; # ︒.ⴃ≯
+︒。ⴃ≯; ︒.ⴃ≯; [P1, V6]; xn--y86c.xn--hdh782b; ; ; # ︒.ⴃ≯
+xn--y86c.xn--hdh782b; ︒.ⴃ≯; [V6]; xn--y86c.xn--hdh782b; ; ; # ︒.ⴃ≯
+xn--y86c.xn--bnd622g; ︒.Ⴃ≯; [V6]; xn--y86c.xn--bnd622g; ; ; # ︒.Ⴃ≯
+𐹮。󠢼‍; 𐹮.󠢼‍; [B1, C2, P1, V6]; xn--mo0d.xn--1ug18431l; ; xn--mo0d.xn--wy46e; [B1, P1, V6] # 𐹮.
+𐹮。󠢼‍; 𐹮.󠢼‍; [B1, C2, P1, V6]; xn--mo0d.xn--1ug18431l; ; xn--mo0d.xn--wy46e; [B1, P1, V6] # 𐹮.
+xn--mo0d.xn--wy46e; 𐹮.󠢼; [B1, V6]; xn--mo0d.xn--wy46e; ; ; # 𐹮.
+xn--mo0d.xn--1ug18431l; 𐹮.󠢼‍; [B1, C2, V6]; xn--mo0d.xn--1ug18431l; ; ; # 𐹮.
+Ⴞ𐹨。︒ݽ‍Ⴏ; Ⴞ𐹨.︒ݽ‍Ⴏ; [B1, B5, B6, C2, P1, V6]; xn--2nd0990k.xn--eqb228bgzmvp0t; ; xn--2nd0990k.xn--eqb228b583r; [B1, B5, B6, P1, V6] # Ⴞ𐹨.︒ݽႯ
+Ⴞ𐹨。。ݽ‍Ⴏ; Ⴞ𐹨..ݽ‍Ⴏ; [B2, B3, B5, B6, C2, P1, V6, X4_2]; xn--2nd0990k..xn--eqb228bgzm; [B2, B3, B5, B6, C2, P1, V6, A4_2]; xn--2nd0990k..xn--eqb228b; [B2, B3, B5, B6, P1, V6, A4_2] # Ⴞ𐹨..ݽႯ
+ⴞ𐹨。。ݽ‍ⴏ; ⴞ𐹨..ݽ‍ⴏ; [B2, B3, B5, B6, C2, X4_2]; xn--mlju223e..xn--eqb096jpgj; [B2, B3, B5, B6, C2, A4_2]; xn--mlju223e..xn--eqb053q; [B2, B3, B5, B6, A4_2] # ⴞ𐹨..ݽⴏ
+Ⴞ𐹨。。ݽ‍ⴏ; Ⴞ𐹨..ݽ‍ⴏ; [B2, B3, B5, B6, C2, P1, V6, X4_2]; xn--2nd0990k..xn--eqb096jpgj; [B2, B3, B5, B6, C2, P1, V6, A4_2]; xn--2nd0990k..xn--eqb053q; [B2, B3, B5, B6, P1, V6, A4_2] # Ⴞ𐹨..ݽⴏ
+xn--2nd0990k..xn--eqb053q; Ⴞ𐹨..ݽⴏ; [B2, B3, B5, B6, V6, X4_2]; xn--2nd0990k..xn--eqb053q; [B2, B3, B5, B6, V6, A4_2]; ; # Ⴞ𐹨..ݽⴏ
+xn--2nd0990k..xn--eqb096jpgj; Ⴞ𐹨..ݽ‍ⴏ; [B2, B3, B5, B6, C2, V6, X4_2]; xn--2nd0990k..xn--eqb096jpgj; [B2, B3, B5, B6, C2, V6, A4_2]; ; # Ⴞ𐹨..ݽⴏ
+xn--mlju223e..xn--eqb053q; ⴞ𐹨..ݽⴏ; [B2, B3, B5, B6, X4_2]; xn--mlju223e..xn--eqb053q; [B2, B3, B5, B6, A4_2]; ; # ⴞ𐹨..ݽⴏ
+xn--mlju223e..xn--eqb096jpgj; ⴞ𐹨..ݽ‍ⴏ; [B2, B3, B5, B6, C2, X4_2]; xn--mlju223e..xn--eqb096jpgj; [B2, B3, B5, B6, C2, A4_2]; ; # ⴞ𐹨..ݽⴏ
+xn--2nd0990k..xn--eqb228b; Ⴞ𐹨..ݽႯ; [B2, B3, B5, B6, V6, X4_2]; xn--2nd0990k..xn--eqb228b; [B2, B3, B5, B6, V6, A4_2]; ; # Ⴞ𐹨..ݽႯ
+xn--2nd0990k..xn--eqb228bgzm; Ⴞ𐹨..ݽ‍Ⴏ; [B2, B3, B5, B6, C2, V6, X4_2]; xn--2nd0990k..xn--eqb228bgzm; [B2, B3, B5, B6, C2, V6, A4_2]; ; # Ⴞ𐹨..ݽႯ
+ⴞ𐹨。︒ݽ‍ⴏ; ⴞ𐹨.︒ݽ‍ⴏ; [B1, B5, B6, C2, P1, V6]; xn--mlju223e.xn--eqb096jpgj9y7r; ; xn--mlju223e.xn--eqb053qjk7l; [B1, B5, B6, P1, V6] # ⴞ𐹨.︒ݽⴏ
+Ⴞ𐹨。︒ݽ‍ⴏ; Ⴞ𐹨.︒ݽ‍ⴏ; [B1, B5, B6, C2, P1, V6]; xn--2nd0990k.xn--eqb096jpgj9y7r; ; xn--2nd0990k.xn--eqb053qjk7l; [B1, B5, B6, P1, V6] # Ⴞ𐹨.︒ݽⴏ
+xn--2nd0990k.xn--eqb053qjk7l; Ⴞ𐹨.︒ݽⴏ; [B1, B5, B6, V6]; xn--2nd0990k.xn--eqb053qjk7l; ; ; # Ⴞ𐹨.︒ݽⴏ
+xn--2nd0990k.xn--eqb096jpgj9y7r; Ⴞ𐹨.︒ݽ‍ⴏ; [B1, B5, B6, C2, V6]; xn--2nd0990k.xn--eqb096jpgj9y7r; ; ; # Ⴞ𐹨.︒ݽⴏ
+xn--mlju223e.xn--eqb053qjk7l; ⴞ𐹨.︒ݽⴏ; [B1, B5, B6, V6]; xn--mlju223e.xn--eqb053qjk7l; ; ; # ⴞ𐹨.︒ݽⴏ
+xn--mlju223e.xn--eqb096jpgj9y7r; ⴞ𐹨.︒ݽ‍ⴏ; [B1, B5, B6, C2, V6]; xn--mlju223e.xn--eqb096jpgj9y7r; ; ; # ⴞ𐹨.︒ݽⴏ
+xn--2nd0990k.xn--eqb228b583r; Ⴞ𐹨.︒ݽႯ; [B1, B5, B6, V6]; xn--2nd0990k.xn--eqb228b583r; ; ; # Ⴞ𐹨.︒ݽႯ
+xn--2nd0990k.xn--eqb228bgzmvp0t; Ⴞ𐹨.︒ݽ‍Ⴏ; [B1, B5, B6, C2, V6]; xn--2nd0990k.xn--eqb228bgzmvp0t; ; ; # Ⴞ𐹨.︒ݽႯ
+‌Ⴆ𝟹。-⃒-ߑ; ‌Ⴆ3.-⃒-ߑ; [B1, C1, P1, V3, V6]; xn--3-i0g939i.xn-----vue617w; ; xn--3-i0g.xn-----vue617w; [B1, P1, V3, V6] # Ⴆ3.-⃒-ߑ
+‌Ⴆ3。-⃒-ߑ; ‌Ⴆ3.-⃒-ߑ; [B1, C1, P1, V3, V6]; xn--3-i0g939i.xn-----vue617w; ; xn--3-i0g.xn-----vue617w; [B1, P1, V3, V6] # Ⴆ3.-⃒-ߑ
+‌ⴆ3。-⃒-ߑ; ‌ⴆ3.-⃒-ߑ; [B1, C1, V3]; xn--3-rgnv99c.xn-----vue617w; ; xn--3-lvs.xn-----vue617w; [B1, V3] # ⴆ3.-⃒-ߑ
+xn--3-lvs.xn-----vue617w; ⴆ3.-⃒-ߑ; [B1, V3]; xn--3-lvs.xn-----vue617w; ; ; # ⴆ3.-⃒-ߑ
+xn--3-rgnv99c.xn-----vue617w; ‌ⴆ3.-⃒-ߑ; [B1, C1, V3]; xn--3-rgnv99c.xn-----vue617w; ; ; # ⴆ3.-⃒-ߑ
+xn--3-i0g.xn-----vue617w; Ⴆ3.-⃒-ߑ; [B1, V3, V6]; xn--3-i0g.xn-----vue617w; ; ; # Ⴆ3.-⃒-ߑ
+xn--3-i0g939i.xn-----vue617w; ‌Ⴆ3.-⃒-ߑ; [B1, C1, V3, V6]; xn--3-i0g939i.xn-----vue617w; ; ; # Ⴆ3.-⃒-ߑ
+‌ⴆ𝟹。-⃒-ߑ; ‌ⴆ3.-⃒-ߑ; [B1, C1, V3]; xn--3-rgnv99c.xn-----vue617w; ; xn--3-lvs.xn-----vue617w; [B1, V3] # ⴆ3.-⃒-ߑ
+箃Ⴡ-󠁝。≠-🤖; 箃Ⴡ-󠁝.≠-🤖; [P1, V6]; xn----11g3013fy8x5m.xn----tfot873s; ; ; # 箃Ⴡ-.≠-🤖
+箃Ⴡ-󠁝。≠-🤖; 箃Ⴡ-󠁝.≠-🤖; [P1, V6]; xn----11g3013fy8x5m.xn----tfot873s; ; ; # 箃Ⴡ-.≠-🤖
+箃Ⴡ-󠁝。≠-🤖; 箃Ⴡ-󠁝.≠-🤖; [P1, V6]; xn----11g3013fy8x5m.xn----tfot873s; ; ; # 箃Ⴡ-.≠-🤖
+箃Ⴡ-󠁝。≠-🤖; 箃Ⴡ-󠁝.≠-🤖; [P1, V6]; xn----11g3013fy8x5m.xn----tfot873s; ; ; # 箃Ⴡ-.≠-🤖
+箃ⴡ-󠁝。≠-🤖; 箃ⴡ-󠁝.≠-🤖; [P1, V6]; xn----4wsr321ay823p.xn----tfot873s; ; ; # 箃ⴡ-.≠-🤖
+箃ⴡ-󠁝。≠-🤖; 箃ⴡ-󠁝.≠-🤖; [P1, V6]; xn----4wsr321ay823p.xn----tfot873s; ; ; # 箃ⴡ-.≠-🤖
+xn----4wsr321ay823p.xn----tfot873s; 箃ⴡ-󠁝.≠-🤖; [V6]; xn----4wsr321ay823p.xn----tfot873s; ; ; # 箃ⴡ-.≠-🤖
+xn----11g3013fy8x5m.xn----tfot873s; 箃Ⴡ-󠁝.≠-🤖; [V6]; xn----11g3013fy8x5m.xn----tfot873s; ; ; # 箃Ⴡ-.≠-🤖
+箃ⴡ-󠁝。≠-🤖; 箃ⴡ-󠁝.≠-🤖; [P1, V6]; xn----4wsr321ay823p.xn----tfot873s; ; ; # 箃ⴡ-.≠-🤖
+箃ⴡ-󠁝。≠-🤖; 箃ⴡ-󠁝.≠-🤖; [P1, V6]; xn----4wsr321ay823p.xn----tfot873s; ; ; # 箃ⴡ-.≠-🤖
+ߥ.ڵ; ; ; xn--dtb.xn--okb; ; ; # ߥ.ڵ
+xn--dtb.xn--okb; ߥ.ڵ; ; xn--dtb.xn--okb; ; ; # ߥ.ڵ
+‌‍.𞤿; ; [B1, C1, C2]; xn--0ugc.xn--3e6h; ; .xn--3e6h; [A4_2] # .𞤿
+‌‍.𞤝; ‌‍.𞤿; [B1, C1, C2]; xn--0ugc.xn--3e6h; ; .xn--3e6h; [A4_2] # .𞤿
+.xn--3e6h; .𞤿; [X4_2]; .xn--3e6h; [A4_2]; ; # .𞤿
+xn--0ugc.xn--3e6h; ‌‍.𞤿; [B1, C1, C2]; xn--0ugc.xn--3e6h; ; ; # .𞤿
+xn--3e6h; 𞤿; ; xn--3e6h; ; ; # 𞤿
+𞤿; ; ; xn--3e6h; ; ; # 𞤿
+𞤝; 𞤿; ; xn--3e6h; ; ; # 𞤿
+🜑𐹧ع.ς𑍍蜹; ; [B1]; xn--4gb3736kk4zf.xn--3xa4248dy27d; ; xn--4gb3736kk4zf.xn--4xa2248dy27d; # 🜑𐹧ع.ς𑍍蜹
+🜑𐹧ع.Σ𑍍蜹; 🜑𐹧ع.σ𑍍蜹; [B1]; xn--4gb3736kk4zf.xn--4xa2248dy27d; ; ; # 🜑𐹧ع.σ𑍍蜹
+🜑𐹧ع.σ𑍍蜹; ; [B1]; xn--4gb3736kk4zf.xn--4xa2248dy27d; ; ; # 🜑𐹧ع.σ𑍍蜹
+xn--4gb3736kk4zf.xn--4xa2248dy27d; 🜑𐹧ع.σ𑍍蜹; [B1]; xn--4gb3736kk4zf.xn--4xa2248dy27d; ; ; # 🜑𐹧ع.σ𑍍蜹
+xn--4gb3736kk4zf.xn--3xa4248dy27d; 🜑𐹧ع.ς𑍍蜹; [B1]; xn--4gb3736kk4zf.xn--3xa4248dy27d; ; ; # 🜑𐹧ع.ς𑍍蜹
+򫠐ス􆟤٩.󚃟; 򫠐ス􆟤٩.󚃟; [B5, B6, P1, V6]; xn--iib777sp230oo708a.xn--7824e; ; ; # ス٩.
+򫠐ス􆟤٩.󚃟; ; [B5, B6, P1, V6]; xn--iib777sp230oo708a.xn--7824e; ; ; # ス٩.
+xn--iib777sp230oo708a.xn--7824e; 򫠐ス􆟤٩.󚃟; [B5, B6, V6]; xn--iib777sp230oo708a.xn--7824e; ; ; # ス٩.
+𝪣򕡝.֚?ۂ; 𝪣򕡝.֚?ۂ; [B1, P1, V5, V6]; xn--8c3hu7971a.xn--?-wec30g; ; ; # 𝪣.֚?ۂ
+𝪣򕡝.֚?ۂ; 𝪣򕡝.֚?ۂ; [B1, P1, V5, V6]; xn--8c3hu7971a.xn--?-wec30g; ; ; # 𝪣.֚?ۂ
+𝪣򕡝.֚?ۂ; ; [B1, P1, V5, V6]; xn--8c3hu7971a.xn--?-wec30g; ; ; # 𝪣.֚?ۂ
+𝪣򕡝.֚?ۂ; 𝪣򕡝.֚?ۂ; [B1, P1, V5, V6]; xn--8c3hu7971a.xn--?-wec30g; ; ; # 𝪣.֚?ۂ
+xn--8c3hu7971a.xn--?-wec30g; 𝪣򕡝.֚?ۂ; [B1, P1, V5, V6]; xn--8c3hu7971a.xn--?-wec30g; ; ; # 𝪣.֚?ۂ
+xn--8c3hu7971a.֚?ۂ; 𝪣򕡝.֚?ۂ; [B1, P1, V5, V6]; xn--8c3hu7971a.xn--?-wec30g; ; ; # 𝪣.֚?ۂ
+xn--8c3hu7971a.֚?ۂ; 𝪣򕡝.֚?ۂ; [B1, P1, V5, V6]; xn--8c3hu7971a.xn--?-wec30g; ; ; # 𝪣.֚?ۂ
+XN--8C3HU7971A.֚?ۂ; 𝪣򕡝.֚?ۂ; [B1, P1, V5, V6]; xn--8c3hu7971a.xn--?-wec30g; ; ; # 𝪣.֚?ۂ
+XN--8C3HU7971A.֚?ۂ; 𝪣򕡝.֚?ۂ; [B1, P1, V5, V6]; xn--8c3hu7971a.xn--?-wec30g; ; ; # 𝪣.֚?ۂ
+Xn--8c3hu7971a.֚?ۂ; 𝪣򕡝.֚?ۂ; [B1, P1, V5, V6]; xn--8c3hu7971a.xn--?-wec30g; ; ; # 𝪣.֚?ۂ
+Xn--8c3hu7971a.֚?ۂ; 𝪣򕡝.֚?ۂ; [B1, P1, V5, V6]; xn--8c3hu7971a.xn--?-wec30g; ; ; # 𝪣.֚?ۂ
+٠򪓵‌。ݗ; ٠򪓵‌.ݗ; [B1, C1, P1, V6]; xn--8hb852ke991q.xn--bpb; ; xn--8hb82030l.xn--bpb; [B1, P1, V6] # ٠.ݗ
+xn--8hb82030l.xn--bpb; ٠򪓵.ݗ; [B1, V6]; xn--8hb82030l.xn--bpb; ; ; # ٠.ݗ
+xn--8hb852ke991q.xn--bpb; ٠򪓵‌.ݗ; [B1, C1, V6]; xn--8hb852ke991q.xn--bpb; ; ; # ٠.ݗ
+်‍‌。-‌; ်‍‌.-‌; [C1, V3, V5]; xn--bkd412fca.xn----sgn; ; xn--bkd.-; [V3, V5] # ်.-
+xn--bkd.-; ်.-; [V3, V5]; xn--bkd.-; ; ; # ်.-
+xn--bkd412fca.xn----sgn; ်‍‌.-‌; [C1, V3, V5]; xn--bkd412fca.xn----sgn; ; ; # ်.-
+︒。᭄ᡉ; ︒.᭄ᡉ; [P1, V5, V6]; xn--y86c.xn--87e93m; ; ; # ︒.᭄ᡉ
+。。᭄ᡉ; ..᭄ᡉ; [V5, X4_2]; ..xn--87e93m; [V5, A4_2]; ; # ..᭄ᡉ
+..xn--87e93m; ..᭄ᡉ; [V5, X4_2]; ..xn--87e93m; [V5, A4_2]; ; # ..᭄ᡉ
+xn--y86c.xn--87e93m; ︒.᭄ᡉ; [V5, V6]; xn--y86c.xn--87e93m; ; ; # ︒.᭄ᡉ
+ݘß。ጫᢊݨ𝟐; ݘß.ጫᢊݨ2; [B2, B3, B5]; xn--zca724a.xn--2-b5c641gfmf; ; xn--ss-gke.xn--2-b5c641gfmf; # ݘß.ጫᢊݨ2
+ݘß。ጫᢊݨ2; ݘß.ጫᢊݨ2; [B2, B3, B5]; xn--zca724a.xn--2-b5c641gfmf; ; xn--ss-gke.xn--2-b5c641gfmf; # ݘß.ጫᢊݨ2
+ݘSS。ጫᢊݨ2; ݘss.ጫᢊݨ2; [B2, B3, B5]; xn--ss-gke.xn--2-b5c641gfmf; ; ; # ݘss.ጫᢊݨ2
+ݘss。ጫᢊݨ2; ݘss.ጫᢊݨ2; [B2, B3, B5]; xn--ss-gke.xn--2-b5c641gfmf; ; ; # ݘss.ጫᢊݨ2
+xn--ss-gke.xn--2-b5c641gfmf; ݘss.ጫᢊݨ2; [B2, B3, B5]; xn--ss-gke.xn--2-b5c641gfmf; ; ; # ݘss.ጫᢊݨ2
+xn--zca724a.xn--2-b5c641gfmf; ݘß.ጫᢊݨ2; [B2, B3, B5]; xn--zca724a.xn--2-b5c641gfmf; ; ; # ݘß.ጫᢊݨ2
+ݘSS。ጫᢊݨ𝟐; ݘss.ጫᢊݨ2; [B2, B3, B5]; xn--ss-gke.xn--2-b5c641gfmf; ; ; # ݘss.ጫᢊݨ2
+ݘss。ጫᢊݨ𝟐; ݘss.ጫᢊݨ2; [B2, B3, B5]; xn--ss-gke.xn--2-b5c641gfmf; ; ; # ݘss.ጫᢊݨ2
+ݘSs。ጫᢊݨ2; ݘss.ጫᢊݨ2; [B2, B3, B5]; xn--ss-gke.xn--2-b5c641gfmf; ; ; # ݘss.ጫᢊݨ2
+ݘSs。ጫᢊݨ𝟐; ݘss.ጫᢊݨ2; [B2, B3, B5]; xn--ss-gke.xn--2-b5c641gfmf; ; ; # ݘss.ጫᢊݨ2
+߃𞶇ᚲ.ं͓𝟚্; ߃𞶇ᚲ.ं͓2্; [B1, B2, B3, P1, V5, V6]; xn--esb067enh07a.xn--2-lgb874bjxa; ; ; # ߃ᚲ.ं͓2্
+߃𞶇ᚲ.ं͓2্; ; [B1, B2, B3, P1, V5, V6]; xn--esb067enh07a.xn--2-lgb874bjxa; ; ; # ߃ᚲ.ं͓2্
+xn--esb067enh07a.xn--2-lgb874bjxa; ߃𞶇ᚲ.ं͓2্; [B1, B2, B3, V5, V6]; xn--esb067enh07a.xn--2-lgb874bjxa; ; ; # ߃ᚲ.ं͓2্
+-᮫︒‍.񒶈񥹓; ; [C2, P1, V3, V6]; xn----qmlv7tw180a.xn--x50zy803a; ; xn----qml1407i.xn--x50zy803a; [P1, V3, V6] # -᮫︒.
+-᮫。‍.񒶈񥹓; -᮫.‍.񒶈񥹓; [C2, P1, V3, V6]; xn----qml.xn--1ug.xn--x50zy803a; ; xn----qml..xn--x50zy803a; [P1, V3, V6, A4_2] # -᮫..
+xn----qml..xn--x50zy803a; -᮫..񒶈񥹓; [V3, V6, X4_2]; xn----qml..xn--x50zy803a; [V3, V6, A4_2]; ; # -᮫..
+xn----qml.xn--1ug.xn--x50zy803a; -᮫.‍.񒶈񥹓; [C2, V3, V6]; xn----qml.xn--1ug.xn--x50zy803a; ; ; # -᮫..
+xn----qml1407i.xn--x50zy803a; -᮫︒.񒶈񥹓; [V3, V6]; xn----qml1407i.xn--x50zy803a; ; ; # -᮫︒.
+xn----qmlv7tw180a.xn--x50zy803a; -᮫︒‍.񒶈񥹓; [C2, V3, V6]; xn----qmlv7tw180a.xn--x50zy803a; ; ; # -᮫︒.
+󠦮.≯𞀆; ; [P1, V6]; xn--t546e.xn--hdh5166o; ; ; # .≯𞀆
+󠦮.≯𞀆; 󠦮.≯𞀆; [P1, V6]; xn--t546e.xn--hdh5166o; ; ; # .≯𞀆
+xn--t546e.xn--hdh5166o; 󠦮.≯𞀆; [V6]; xn--t546e.xn--hdh5166o; ; ; # .≯𞀆
+-𑄳󠊗𐹩。𞮱; -𑄳󠊗𐹩.𞮱; [B1, P1, V3, V6]; xn----p26i72em2894c.xn--zw6h; ; ; # -𑄳𐹩.
+xn----p26i72em2894c.xn--zw6h; -𑄳󠊗𐹩.𞮱; [B1, V3, V6]; xn----p26i72em2894c.xn--zw6h; ; ; # -𑄳𐹩.
+ڹ.ᡳᅟ; ڹ.ᡳᅟ; [P1, V6]; xn--skb.xn--osd737a; ; ; # ڹ.ᡳ
+ڹ.ᡳᅟ; ; [P1, V6]; xn--skb.xn--osd737a; ; ; # ڹ.ᡳ
+xn--skb.xn--osd737a; ڹ.ᡳᅟ; [V6]; xn--skb.xn--osd737a; ; ; # ڹ.ᡳ
+㨛𘱎.︒𝟕ഁ; 㨛𘱎.︒7ഁ; [P1, V6]; xn--mbm8237g.xn--7-7hf1526p; ; ; # 㨛𘱎.︒7ഁ
+㨛𘱎.。7ഁ; 㨛𘱎..7ഁ; [X4_2]; xn--mbm8237g..xn--7-7hf; [A4_2]; ; # 㨛𘱎..7ഁ
+xn--mbm8237g..xn--7-7hf; 㨛𘱎..7ഁ; [X4_2]; xn--mbm8237g..xn--7-7hf; [A4_2]; ; # 㨛𘱎..7ഁ
+xn--mbm8237g.xn--7-7hf1526p; 㨛𘱎.︒7ഁ; [V6]; xn--mbm8237g.xn--7-7hf1526p; ; ; # 㨛𘱎.︒7ഁ
+۝𻱧-。𞷁⁤𞤣≮; ۝𻱧-.𞷁𞤣≮; [B1, B3, P1, V3, V6]; xn----dxc06304e.xn--gdh5020pk5c; ; ; # -.𞤣≮
+۝𻱧-。𞷁⁤𞤣≮; ۝𻱧-.𞷁𞤣≮; [B1, B3, P1, V3, V6]; xn----dxc06304e.xn--gdh5020pk5c; ; ; # -.𞤣≮
+۝𻱧-。𞷁⁤𞤣≮; ۝𻱧-.𞷁𞤣≮; [B1, B3, P1, V3, V6]; xn----dxc06304e.xn--gdh5020pk5c; ; ; # -.𞤣≮
+۝𻱧-。𞷁⁤𞤣≮; ۝𻱧-.𞷁𞤣≮; [B1, B3, P1, V3, V6]; xn----dxc06304e.xn--gdh5020pk5c; ; ; # -.𞤣≮
+۝𻱧-。𞷁⁤𞤁≮; ۝𻱧-.𞷁𞤣≮; [B1, B3, P1, V3, V6]; xn----dxc06304e.xn--gdh5020pk5c; ; ; # -.𞤣≮
+۝𻱧-。𞷁⁤𞤁≮; ۝𻱧-.𞷁𞤣≮; [B1, B3, P1, V3, V6]; xn----dxc06304e.xn--gdh5020pk5c; ; ; # -.𞤣≮
+xn----dxc06304e.xn--gdh5020pk5c; ۝𻱧-.𞷁𞤣≮; [B1, B3, V3, V6]; xn----dxc06304e.xn--gdh5020pk5c; ; ; # -.𞤣≮
+۝𻱧-。𞷁⁤𞤁≮; ۝𻱧-.𞷁𞤣≮; [B1, B3, P1, V3, V6]; xn----dxc06304e.xn--gdh5020pk5c; ; ; # -.𞤣≮
+۝𻱧-。𞷁⁤𞤁≮; ۝𻱧-.𞷁𞤣≮; [B1, B3, P1, V3, V6]; xn----dxc06304e.xn--gdh5020pk5c; ; ; # -.𞤣≮
+ß‌꫶ᢥ.⊶ჁႶ; ß‌꫶ᢥ.⊶ჁႶ; [C1, P1, V6]; xn--zca682johfi89m.xn--undv409k; ; xn--ss-4epx629f.xn--undv409k; [P1, V6] # ß꫶ᢥ.⊶ჁႶ
+ß‌꫶ᢥ.⊶ჁႶ; ; [C1, P1, V6]; xn--zca682johfi89m.xn--undv409k; ; xn--ss-4epx629f.xn--undv409k; [P1, V6] # ß꫶ᢥ.⊶ჁႶ
+ß‌꫶ᢥ.⊶ⴡⴖ; ; [C1]; xn--zca682johfi89m.xn--ifh802b6a; ; xn--ss-4epx629f.xn--ifh802b6a; [] # ß꫶ᢥ.⊶ⴡⴖ
+SS‌꫶ᢥ.⊶ჁႶ; ss‌꫶ᢥ.⊶ჁႶ; [C1, P1, V6]; xn--ss-4ep585bkm5p.xn--undv409k; ; xn--ss-4epx629f.xn--undv409k; [P1, V6] # ss꫶ᢥ.⊶ჁႶ
+ss‌꫶ᢥ.⊶ⴡⴖ; ; [C1]; xn--ss-4ep585bkm5p.xn--ifh802b6a; ; xn--ss-4epx629f.xn--ifh802b6a; [] # ss꫶ᢥ.⊶ⴡⴖ
+Ss‌꫶ᢥ.⊶Ⴡⴖ; ss‌꫶ᢥ.⊶Ⴡⴖ; [C1, P1, V6]; xn--ss-4ep585bkm5p.xn--5nd703gyrh; ; xn--ss-4epx629f.xn--5nd703gyrh; [P1, V6] # ss꫶ᢥ.⊶Ⴡⴖ
+xn--ss-4epx629f.xn--5nd703gyrh; ss꫶ᢥ.⊶Ⴡⴖ; [V6]; xn--ss-4epx629f.xn--5nd703gyrh; ; ; # ss꫶ᢥ.⊶Ⴡⴖ
+xn--ss-4ep585bkm5p.xn--5nd703gyrh; ss‌꫶ᢥ.⊶Ⴡⴖ; [C1, V6]; xn--ss-4ep585bkm5p.xn--5nd703gyrh; ; ; # ss꫶ᢥ.⊶Ⴡⴖ
+xn--ss-4epx629f.xn--ifh802b6a; ss꫶ᢥ.⊶ⴡⴖ; ; xn--ss-4epx629f.xn--ifh802b6a; ; ; # ss꫶ᢥ.⊶ⴡⴖ
+ss꫶ᢥ.⊶ⴡⴖ; ; ; xn--ss-4epx629f.xn--ifh802b6a; ; ; # ss꫶ᢥ.⊶ⴡⴖ
+SS꫶ᢥ.⊶ჁႶ; ss꫶ᢥ.⊶ჁႶ; [P1, V6]; xn--ss-4epx629f.xn--undv409k; ; ; # ss꫶ᢥ.⊶ჁႶ
+Ss꫶ᢥ.⊶Ⴡⴖ; ss꫶ᢥ.⊶Ⴡⴖ; [P1, V6]; xn--ss-4epx629f.xn--5nd703gyrh; ; ; # ss꫶ᢥ.⊶Ⴡⴖ
+xn--ss-4epx629f.xn--undv409k; ss꫶ᢥ.⊶ჁႶ; [V6]; xn--ss-4epx629f.xn--undv409k; ; ; # ss꫶ᢥ.⊶ჁႶ
+xn--ss-4ep585bkm5p.xn--ifh802b6a; ss‌꫶ᢥ.⊶ⴡⴖ; [C1]; xn--ss-4ep585bkm5p.xn--ifh802b6a; ; ; # ss꫶ᢥ.⊶ⴡⴖ
+xn--ss-4ep585bkm5p.xn--undv409k; ss‌꫶ᢥ.⊶ჁႶ; [C1, V6]; xn--ss-4ep585bkm5p.xn--undv409k; ; ; # ss꫶ᢥ.⊶ჁႶ
+xn--zca682johfi89m.xn--ifh802b6a; ß‌꫶ᢥ.⊶ⴡⴖ; [C1]; xn--zca682johfi89m.xn--ifh802b6a; ; ; # ß꫶ᢥ.⊶ⴡⴖ
+xn--zca682johfi89m.xn--undv409k; ß‌꫶ᢥ.⊶ჁႶ; [C1, V6]; xn--zca682johfi89m.xn--undv409k; ; ; # ß꫶ᢥ.⊶ჁႶ
+ß‌꫶ᢥ.⊶ⴡⴖ; ß‌꫶ᢥ.⊶ⴡⴖ; [C1]; xn--zca682johfi89m.xn--ifh802b6a; ; xn--ss-4epx629f.xn--ifh802b6a; [] # ß꫶ᢥ.⊶ⴡⴖ
+SS‌꫶ᢥ.⊶ჁႶ; ss‌꫶ᢥ.⊶ჁႶ; [C1, P1, V6]; xn--ss-4ep585bkm5p.xn--undv409k; ; xn--ss-4epx629f.xn--undv409k; [P1, V6] # ss꫶ᢥ.⊶ჁႶ
+ss‌꫶ᢥ.⊶ⴡⴖ; ss‌꫶ᢥ.⊶ⴡⴖ; [C1]; xn--ss-4ep585bkm5p.xn--ifh802b6a; ; xn--ss-4epx629f.xn--ifh802b6a; [] # ss꫶ᢥ.⊶ⴡⴖ
+Ss‌꫶ᢥ.⊶Ⴡⴖ; ss‌꫶ᢥ.⊶Ⴡⴖ; [C1, P1, V6]; xn--ss-4ep585bkm5p.xn--5nd703gyrh; ; xn--ss-4epx629f.xn--5nd703gyrh; [P1, V6] # ss꫶ᢥ.⊶Ⴡⴖ
+‍。ς󠁉; ‍.ς󠁉; [C2, P1, V6]; xn--1ug.xn--3xa44344p; ; .xn--4xa24344p; [P1, V6, A4_2] # .ς
+‍。Σ󠁉; ‍.σ󠁉; [C2, P1, V6]; xn--1ug.xn--4xa24344p; ; .xn--4xa24344p; [P1, V6, A4_2] # .σ
+‍。σ󠁉; ‍.σ󠁉; [C2, P1, V6]; xn--1ug.xn--4xa24344p; ; .xn--4xa24344p; [P1, V6, A4_2] # .σ
+.xn--4xa24344p; .σ󠁉; [V6, X4_2]; .xn--4xa24344p; [V6, A4_2]; ; # .σ
+xn--1ug.xn--4xa24344p; ‍.σ󠁉; [C2, V6]; xn--1ug.xn--4xa24344p; ; ; # .σ
+xn--1ug.xn--3xa44344p; ‍.ς󠁉; [C2, V6]; xn--1ug.xn--3xa44344p; ; ; # .ς
+𞵑ß.ݑ‍𞤛-; 𞵑ß.ݑ‍𞤽-; [B2, B3, C2, P1, V3, V6]; xn--zca5423w.xn----z3c011q9513b; ; xn--ss-2722a.xn----z3c03218a; [B2, B3, P1, V3, V6] # ß.ݑ𞤽-
+𞵑ß.ݑ‍𞤽-; ; [B2, B3, C2, P1, V3, V6]; xn--zca5423w.xn----z3c011q9513b; ; xn--ss-2722a.xn----z3c03218a; [B2, B3, P1, V3, V6] # ß.ݑ𞤽-
+𞵑SS.ݑ‍𞤛-; 𞵑ss.ݑ‍𞤽-; [B2, B3, C2, P1, V3, V6]; xn--ss-2722a.xn----z3c011q9513b; ; xn--ss-2722a.xn----z3c03218a; [B2, B3, P1, V3, V6] # ss.ݑ𞤽-
+𞵑ss.ݑ‍𞤽-; ; [B2, B3, C2, P1, V3, V6]; xn--ss-2722a.xn----z3c011q9513b; ; xn--ss-2722a.xn----z3c03218a; [B2, B3, P1, V3, V6] # ss.ݑ𞤽-
+𞵑Ss.ݑ‍𞤽-; 𞵑ss.ݑ‍𞤽-; [B2, B3, C2, P1, V3, V6]; xn--ss-2722a.xn----z3c011q9513b; ; xn--ss-2722a.xn----z3c03218a; [B2, B3, P1, V3, V6] # ss.ݑ𞤽-
+xn--ss-2722a.xn----z3c03218a; 𞵑ss.ݑ𞤽-; [B2, B3, V3, V6]; xn--ss-2722a.xn----z3c03218a; ; ; # ss.ݑ𞤽-
+xn--ss-2722a.xn----z3c011q9513b; 𞵑ss.ݑ‍𞤽-; [B2, B3, C2, V3, V6]; xn--ss-2722a.xn----z3c011q9513b; ; ; # ss.ݑ𞤽-
+xn--zca5423w.xn----z3c011q9513b; 𞵑ß.ݑ‍𞤽-; [B2, B3, C2, V3, V6]; xn--zca5423w.xn----z3c011q9513b; ; ; # ß.ݑ𞤽-
+𞵑ss.ݑ‍𞤛-; 𞵑ss.ݑ‍𞤽-; [B2, B3, C2, P1, V3, V6]; xn--ss-2722a.xn----z3c011q9513b; ; xn--ss-2722a.xn----z3c03218a; [B2, B3, P1, V3, V6] # ss.ݑ𞤽-
+𞵑Ss.ݑ‍𞤛-; 𞵑ss.ݑ‍𞤽-; [B2, B3, C2, P1, V3, V6]; xn--ss-2722a.xn----z3c011q9513b; ; xn--ss-2722a.xn----z3c03218a; [B2, B3, P1, V3, V6] # ss.ݑ𞤽-
+𑘽‍𞤧.𐹧󡦪-; 𑘽‍𞤧.𐹧󡦪-; [B1, C2, P1, V3, V5, V6]; xn--1ugz808gdimf.xn----k26iq1483f; ; xn--qb2ds317a.xn----k26iq1483f; [B1, P1, V3, V5, V6] # 𑘽𞤧.𐹧-
+𑘽‍𞤧.𐹧󡦪-; ; [B1, C2, P1, V3, V5, V6]; xn--1ugz808gdimf.xn----k26iq1483f; ; xn--qb2ds317a.xn----k26iq1483f; [B1, P1, V3, V5, V6] # 𑘽𞤧.𐹧-
+𑘽‍𞤅.𐹧󡦪-; 𑘽‍𞤧.𐹧󡦪-; [B1, C2, P1, V3, V5, V6]; xn--1ugz808gdimf.xn----k26iq1483f; ; xn--qb2ds317a.xn----k26iq1483f; [B1, P1, V3, V5, V6] # 𑘽𞤧.𐹧-
+xn--qb2ds317a.xn----k26iq1483f; 𑘽𞤧.𐹧󡦪-; [B1, V3, V5, V6]; xn--qb2ds317a.xn----k26iq1483f; ; ; # 𑘽𞤧.𐹧-
+xn--1ugz808gdimf.xn----k26iq1483f; 𑘽‍𞤧.𐹧󡦪-; [B1, C2, V3, V5, V6]; xn--1ugz808gdimf.xn----k26iq1483f; ; ; # 𑘽𞤧.𐹧-
+𑘽‍𞤅.𐹧󡦪-; 𑘽‍𞤧.𐹧󡦪-; [B1, C2, P1, V3, V5, V6]; xn--1ugz808gdimf.xn----k26iq1483f; ; xn--qb2ds317a.xn----k26iq1483f; [B1, P1, V3, V5, V6] # 𑘽𞤧.𐹧-
+⒒򨘙򳳠𑓀.-󞡊; ; [P1, V3, V6]; xn--3shy698frsu9dt1me.xn----x310m; ; ; # ⒒𑓀.-
+11.򨘙򳳠𑓀.-󞡊; ; [P1, V3, V6]; 11.xn--uz1d59632bxujd.xn----x310m; ; ; # 11.𑓀.-
+11.xn--uz1d59632bxujd.xn----x310m; 11.򨘙򳳠𑓀.-󞡊; [V3, V6]; 11.xn--uz1d59632bxujd.xn----x310m; ; ; # 11.𑓀.-
+xn--3shy698frsu9dt1me.xn----x310m; ⒒򨘙򳳠𑓀.-󞡊; [V3, V6]; xn--3shy698frsu9dt1me.xn----x310m; ; ; # ⒒𑓀.-
+-。‍; -.‍; [C2, V3]; -.xn--1ug; ; -.; [V3] # -.
+-。‍; -.‍; [C2, V3]; -.xn--1ug; ; -.; [V3] # -.
+-.; ; [V3]; ; ; ; # -.
+-.xn--1ug; -.‍; [C2, V3]; -.xn--1ug; ; ; # -.
+≮ᡬ.ς¹-?; ≮ᡬ.ς1-?; [P1, V6]; xn--88e732c.xn--1-?-lzc; ; xn--88e732c.xn--1-?-pzc; # ≮ᡬ.ς1-?
+≮ᡬ.ς¹-?; ≮ᡬ.ς1-?; [P1, V6]; xn--88e732c.xn--1-?-lzc; ; xn--88e732c.xn--1-?-pzc; # ≮ᡬ.ς1-?
+≮ᡬ.ς1-?; ; [P1, V6]; xn--88e732c.xn--1-?-lzc; ; xn--88e732c.xn--1-?-pzc; # ≮ᡬ.ς1-?
+≮ᡬ.ς1-?; ≮ᡬ.ς1-?; [P1, V6]; xn--88e732c.xn--1-?-lzc; ; xn--88e732c.xn--1-?-pzc; # ≮ᡬ.ς1-?
+≮ᡬ.Σ1-?; ≮ᡬ.σ1-?; [P1, V6]; xn--88e732c.xn--1-?-pzc; ; ; # ≮ᡬ.σ1-?
+≮ᡬ.Σ1-?; ≮ᡬ.σ1-?; [P1, V6]; xn--88e732c.xn--1-?-pzc; ; ; # ≮ᡬ.σ1-?
+≮ᡬ.σ1-?; ; [P1, V6]; xn--88e732c.xn--1-?-pzc; ; ; # ≮ᡬ.σ1-?
+≮ᡬ.σ1-?; ≮ᡬ.σ1-?; [P1, V6]; xn--88e732c.xn--1-?-pzc; ; ; # ≮ᡬ.σ1-?
+xn--88e732c.xn--1-?-pzc; ≮ᡬ.σ1-?; [P1, V6]; xn--88e732c.xn--1-?-pzc; ; ; # ≮ᡬ.σ1-?
+xn--88e732c.xn--1-?-lzc; ≮ᡬ.ς1-?; [P1, V6]; xn--88e732c.xn--1-?-lzc; ; ; # ≮ᡬ.ς1-?
+≮ᡬ.Σ¹-?; ≮ᡬ.σ1-?; [P1, V6]; xn--88e732c.xn--1-?-pzc; ; ; # ≮ᡬ.σ1-?
+≮ᡬ.Σ¹-?; ≮ᡬ.σ1-?; [P1, V6]; xn--88e732c.xn--1-?-pzc; ; ; # ≮ᡬ.σ1-?
+≮ᡬ.σ¹-?; ≮ᡬ.σ1-?; [P1, V6]; xn--88e732c.xn--1-?-pzc; ; ; # ≮ᡬ.σ1-?
+≮ᡬ.σ¹-?; ≮ᡬ.σ1-?; [P1, V6]; xn--88e732c.xn--1-?-pzc; ; ; # ≮ᡬ.σ1-?
+xn--88e732c.σ1-?; ≮ᡬ.σ1-?; [P1, V6]; xn--88e732c.xn--1-?-pzc; ; ; # ≮ᡬ.σ1-?
+XN--88E732C.Σ1-?; ≮ᡬ.σ1-?; [P1, V6]; xn--88e732c.xn--1-?-pzc; ; ; # ≮ᡬ.σ1-?
+xn--88e732c.ς1-?; ≮ᡬ.ς1-?; [P1, V6]; xn--88e732c.xn--1-?-lzc; ; xn--88e732c.xn--1-?-pzc; # ≮ᡬ.ς1-?
+Xn--88e732c.ς1-?; ≮ᡬ.ς1-?; [P1, V6]; xn--88e732c.xn--1-?-lzc; ; xn--88e732c.xn--1-?-pzc; # ≮ᡬ.ς1-?
+Xn--88e732c.σ1-?; ≮ᡬ.σ1-?; [P1, V6]; xn--88e732c.xn--1-?-pzc; ; ; # ≮ᡬ.σ1-?
+ቬ򔠼񁗶。𐨬𝟠; ቬ򔠼񁗶.𐨬8; [P1, V6]; xn--d0d41273c887z.xn--8-ob5i; ; ; # ቬ.𐨬8
+ቬ򔠼񁗶。𐨬8; ቬ򔠼񁗶.𐨬8; [P1, V6]; xn--d0d41273c887z.xn--8-ob5i; ; ; # ቬ.𐨬8
+xn--d0d41273c887z.xn--8-ob5i; ቬ򔠼񁗶.𐨬8; [V6]; xn--d0d41273c887z.xn--8-ob5i; ; ; # ቬ.𐨬8
+𐱲。蔫ݦ; 𐱲.蔫ݦ; [B5, B6, P1, V6]; xn--389c.xn--qpb7055d; ; ; # .蔫ݦ
+xn--389c.xn--qpb7055d; 𐱲.蔫ݦ; [B5, B6, V6]; xn--389c.xn--qpb7055d; ; ; # .蔫ݦ
+򒲧₃。ꡚ𛇑󠄳ه; 򒲧3.ꡚ𛇑ه; [B5, B6, P1, V6]; xn--3-ep59g.xn--jhb5904fcp0h; ; ; # 3.ꡚ𛇑ه
+򒲧3。ꡚ𛇑󠄳ه; 򒲧3.ꡚ𛇑ه; [B5, B6, P1, V6]; xn--3-ep59g.xn--jhb5904fcp0h; ; ; # 3.ꡚ𛇑ه
+xn--3-ep59g.xn--jhb5904fcp0h; 򒲧3.ꡚ𛇑ه; [B5, B6, V6]; xn--3-ep59g.xn--jhb5904fcp0h; ; ; # 3.ꡚ𛇑ه
+蓸ق≠.ß; ; [B5, B6, P1, V6]; xn--ehb015lnt1e.xn--zca; ; xn--ehb015lnt1e.ss; # 蓸ق≠.ß
+蓸ق≠.ß; 蓸ق≠.ß; [B5, B6, P1, V6]; xn--ehb015lnt1e.xn--zca; ; xn--ehb015lnt1e.ss; # 蓸ق≠.ß
+蓸ق≠.SS; 蓸ق≠.ss; [B5, B6, P1, V6]; xn--ehb015lnt1e.ss; ; ; # 蓸ق≠.ss
+蓸ق≠.SS; 蓸ق≠.ss; [B5, B6, P1, V6]; xn--ehb015lnt1e.ss; ; ; # 蓸ق≠.ss
+蓸ق≠.ss; ; [B5, B6, P1, V6]; xn--ehb015lnt1e.ss; ; ; # 蓸ق≠.ss
+蓸ق≠.ss; 蓸ق≠.ss; [B5, B6, P1, V6]; xn--ehb015lnt1e.ss; ; ; # 蓸ق≠.ss
+蓸ق≠.Ss; 蓸ق≠.ss; [B5, B6, P1, V6]; xn--ehb015lnt1e.ss; ; ; # 蓸ق≠.ss
+蓸ق≠.Ss; 蓸ق≠.ss; [B5, B6, P1, V6]; xn--ehb015lnt1e.ss; ; ; # 蓸ق≠.ss
+xn--ehb015lnt1e.ss; 蓸ق≠.ss; [B5, B6, V6]; xn--ehb015lnt1e.ss; ; ; # 蓸ق≠.ss
+xn--ehb015lnt1e.xn--zca; 蓸ق≠.ß; [B5, B6, V6]; xn--ehb015lnt1e.xn--zca; ; ; # 蓸ق≠.ß
+ࡎٺී⒊.𐹹𞱩󠃪‌; ; [B1, C1, P1, V6]; xn--zib94gfziuq1a.xn--0ug3205g7eyf3c96h; ; xn--zib94gfziuq1a.xn--xo0dw109an237f; [B1, P1, V6] # ࡎٺී⒊.𐹹
+ࡎٺී3..𐹹𞱩󠃪‌; ; [B1, C1, P1, V6, X4_2]; xn--3-prc71ls9j..xn--0ug3205g7eyf3c96h; [B1, C1, P1, V6, A4_2]; xn--3-prc71ls9j..xn--xo0dw109an237f; [B1, P1, V6, A4_2] # ࡎٺී3..𐹹
+xn--3-prc71ls9j..xn--xo0dw109an237f; ࡎٺී3..𐹹𞱩󠃪; [B1, V6, X4_2]; xn--3-prc71ls9j..xn--xo0dw109an237f; [B1, V6, A4_2]; ; # ࡎٺී3..𐹹
+xn--3-prc71ls9j..xn--0ug3205g7eyf3c96h; ࡎٺී3..𐹹𞱩󠃪‌; [B1, C1, V6, X4_2]; xn--3-prc71ls9j..xn--0ug3205g7eyf3c96h; [B1, C1, V6, A4_2]; ; # ࡎٺී3..𐹹
+xn--zib94gfziuq1a.xn--xo0dw109an237f; ࡎٺී⒊.𐹹𞱩󠃪; [B1, V6]; xn--zib94gfziuq1a.xn--xo0dw109an237f; ; ; # ࡎٺී⒊.𐹹
+xn--zib94gfziuq1a.xn--0ug3205g7eyf3c96h; ࡎٺී⒊.𐹹𞱩󠃪‌; [B1, C1, V6]; xn--zib94gfziuq1a.xn--0ug3205g7eyf3c96h; ; ; # ࡎٺී⒊.𐹹
+ς‍-.Ⴣ𦟙; ; [C2, P1, V3, V6]; xn----xmb348s.xn--7nd64871a; ; xn----zmb.xn--7nd64871a; [P1, V3, V6] # ς-.Ⴣ𦟙
+ς‍-.ⴣ𦟙; ; [C2, V3]; xn----xmb348s.xn--rlj2573p; ; xn----zmb.xn--rlj2573p; [V3] # ς-.ⴣ𦟙
+Σ‍-.Ⴣ𦟙; σ‍-.Ⴣ𦟙; [C2, P1, V3, V6]; xn----zmb048s.xn--7nd64871a; ; xn----zmb.xn--7nd64871a; [P1, V3, V6] # σ-.Ⴣ𦟙
+σ‍-.ⴣ𦟙; ; [C2, V3]; xn----zmb048s.xn--rlj2573p; ; xn----zmb.xn--rlj2573p; [V3] # σ-.ⴣ𦟙
+xn----zmb.xn--rlj2573p; σ-.ⴣ𦟙; [V3]; xn----zmb.xn--rlj2573p; ; ; # σ-.ⴣ𦟙
+xn----zmb048s.xn--rlj2573p; σ‍-.ⴣ𦟙; [C2, V3]; xn----zmb048s.xn--rlj2573p; ; ; # σ-.ⴣ𦟙
+xn----zmb.xn--7nd64871a; σ-.Ⴣ𦟙; [V3, V6]; xn----zmb.xn--7nd64871a; ; ; # σ-.Ⴣ𦟙
+xn----zmb048s.xn--7nd64871a; σ‍-.Ⴣ𦟙; [C2, V3, V6]; xn----zmb048s.xn--7nd64871a; ; ; # σ-.Ⴣ𦟙
+xn----xmb348s.xn--rlj2573p; ς‍-.ⴣ𦟙; [C2, V3]; xn----xmb348s.xn--rlj2573p; ; ; # ς-.ⴣ𦟙
+xn----xmb348s.xn--7nd64871a; ς‍-.Ⴣ𦟙; [C2, V3, V6]; xn----xmb348s.xn--7nd64871a; ; ; # ς-.Ⴣ𦟙
+≠。🞳𝟲; ≠.🞳6; [P1, V6]; xn--1ch.xn--6-dl4s; ; ; # ≠.🞳6
+≠。🞳𝟲; ≠.🞳6; [P1, V6]; xn--1ch.xn--6-dl4s; ; ; # ≠.🞳6
+≠。🞳6; ≠.🞳6; [P1, V6]; xn--1ch.xn--6-dl4s; ; ; # ≠.🞳6
+≠。🞳6; ≠.🞳6; [P1, V6]; xn--1ch.xn--6-dl4s; ; ; # ≠.🞳6
+xn--1ch.xn--6-dl4s; ≠.🞳6; [V6]; xn--1ch.xn--6-dl4s; ; ; # ≠.🞳6
+󅬽.蠔; ; [P1, V6]; xn--g747d.xn--xl2a; ; ; # .蠔
+xn--g747d.xn--xl2a; 󅬽.蠔; [V6]; xn--g747d.xn--xl2a; ; ; # .蠔
+ࣦ‍.뼽; ࣦ‍.뼽; [C2, V5]; xn--p0b869i.xn--e43b; ; xn--p0b.xn--e43b; [V5] # ࣦ.뼽
+ࣦ‍.뼽; ࣦ‍.뼽; [C2, V5]; xn--p0b869i.xn--e43b; ; xn--p0b.xn--e43b; [V5] # ࣦ.뼽
+ࣦ‍.뼽; ; [C2, V5]; xn--p0b869i.xn--e43b; ; xn--p0b.xn--e43b; [V5] # ࣦ.뼽
+ࣦ‍.뼽; ࣦ‍.뼽; [C2, V5]; xn--p0b869i.xn--e43b; ; xn--p0b.xn--e43b; [V5] # ࣦ.뼽
+xn--p0b.xn--e43b; ࣦ.뼽; [V5]; xn--p0b.xn--e43b; ; ; # ࣦ.뼽
+xn--p0b869i.xn--e43b; ࣦ‍.뼽; [C2, V5]; xn--p0b869i.xn--e43b; ; ; # ࣦ.뼽
+₇்􃂷ے。👖ٵ-𞪑; 7்􃂷ے.👖اٴ-𞪑; [B1, P1, V6]; xn--7-rwc839aj3073c.xn----ymc5uv818oghka; ; ; # 7்ے.👖اٴ-
+7்􃂷ے。👖اٴ-𞪑; 7்􃂷ے.👖اٴ-𞪑; [B1, P1, V6]; xn--7-rwc839aj3073c.xn----ymc5uv818oghka; ; ; # 7்ے.👖اٴ-
+xn--7-rwc839aj3073c.xn----ymc5uv818oghka; 7்􃂷ے.👖اٴ-𞪑; [B1, V6]; xn--7-rwc839aj3073c.xn----ymc5uv818oghka; ; ; # 7்ے.👖اٴ-
+-。ݻ; -.ݻ; [B1, V3]; -.xn--cqb; ; ; # -.ݻ
+-。ݻ; -.ݻ; [B1, V3]; -.xn--cqb; ; ; # -.ݻ
+-.xn--cqb; -.ݻ; [B1, V3]; -.xn--cqb; ; ; # -.ݻ
+𑇌𵛓。-⒈ꡏܫ; 𑇌𵛓.-⒈ꡏܫ; [B1, P1, V3, V5, V6]; xn--8d1dg030h.xn----u1c466tp10j; ; ; # 𑇌.-⒈ꡏܫ
+𑇌𵛓。-1.ꡏܫ; 𑇌𵛓.-1.ꡏܫ; [B1, B5, B6, P1, V3, V5, V6]; xn--8d1dg030h.-1.xn--1nb7163f; ; ; # 𑇌.-1.ꡏܫ
+xn--8d1dg030h.-1.xn--1nb7163f; 𑇌𵛓.-1.ꡏܫ; [B1, B5, B6, V3, V5, V6]; xn--8d1dg030h.-1.xn--1nb7163f; ; ; # 𑇌.-1.ꡏܫ
+xn--8d1dg030h.xn----u1c466tp10j; 𑇌𵛓.-⒈ꡏܫ; [B1, V3, V5, V6]; xn--8d1dg030h.xn----u1c466tp10j; ; ; # 𑇌.-⒈ꡏܫ
+璛᜴گ.-; ; [B1, B5, B6, V3]; xn--ikb175frt4e.-; ; ; # 璛᜴گ.-
+xn--ikb175frt4e.-; 璛᜴گ.-; [B1, B5, B6, V3]; xn--ikb175frt4e.-; ; ; # 璛᜴گ.-
+󠆰ࢡ੍샕.𐹲휁; ࢡ੍샕.𐹲휁; [B1, B2, B3]; xn--qyb07fj857a.xn--728bv72h; ; ; # ࢡ੍샕.𐹲휁
+󠆰ࢡ੍샕.𐹲휁; ࢡ੍샕.𐹲휁; [B1, B2, B3]; xn--qyb07fj857a.xn--728bv72h; ; ; # ࢡ੍샕.𐹲휁
+󠆰ࢡ੍샕.𐹲휁; ࢡ੍샕.𐹲휁; [B1, B2, B3]; xn--qyb07fj857a.xn--728bv72h; ; ; # ࢡ੍샕.𐹲휁
+󠆰ࢡ੍샕.𐹲휁; ࢡ੍샕.𐹲휁; [B1, B2, B3]; xn--qyb07fj857a.xn--728bv72h; ; ; # ࢡ੍샕.𐹲휁
+xn--qyb07fj857a.xn--728bv72h; ࢡ੍샕.𐹲휁; [B1, B2, B3]; xn--qyb07fj857a.xn--728bv72h; ; ; # ࢡ੍샕.𐹲휁
+񍨽.񋸕; 񍨽.񋸕; [P1, V6]; xn--pr3x.xn--rv7w; ; ; # .
+񍨽.񋸕; ; [P1, V6]; xn--pr3x.xn--rv7w; ; ; # .
+xn--pr3x.xn--rv7w; 񍨽.񋸕; [V6]; xn--pr3x.xn--rv7w; ; ; # .
+ٽ𞥕。𑑂𞤶Ⴍ-; ٽ𞥕.𑑂𞤶Ⴍ-; [B1, P1, V3, V5, V6]; xn--2ib0338v.xn----w0g2740ro9vg; ; ; # ٽ𞥕.𑑂𞤶Ⴍ-
+ٽ𞥕。𑑂𞤶Ⴍ-; ٽ𞥕.𑑂𞤶Ⴍ-; [B1, P1, V3, V5, V6]; xn--2ib0338v.xn----w0g2740ro9vg; ; ; # ٽ𞥕.𑑂𞤶Ⴍ-
+ٽ𞥕。𑑂𞤶ⴍ-; ٽ𞥕.𑑂𞤶ⴍ-; [B1, V3, V5]; xn--2ib0338v.xn----zvs0199fo91g; ; ; # ٽ𞥕.𑑂𞤶ⴍ-
+ٽ𞥕。𑑂𞤔Ⴍ-; ٽ𞥕.𑑂𞤶Ⴍ-; [B1, P1, V3, V5, V6]; xn--2ib0338v.xn----w0g2740ro9vg; ; ; # ٽ𞥕.𑑂𞤶Ⴍ-
+ٽ𞥕。𑑂𞤔ⴍ-; ٽ𞥕.𑑂𞤶ⴍ-; [B1, V3, V5]; xn--2ib0338v.xn----zvs0199fo91g; ; ; # ٽ𞥕.𑑂𞤶ⴍ-
+xn--2ib0338v.xn----zvs0199fo91g; ٽ𞥕.𑑂𞤶ⴍ-; [B1, V3, V5]; xn--2ib0338v.xn----zvs0199fo91g; ; ; # ٽ𞥕.𑑂𞤶ⴍ-
+xn--2ib0338v.xn----w0g2740ro9vg; ٽ𞥕.𑑂𞤶Ⴍ-; [B1, V3, V5, V6]; xn--2ib0338v.xn----w0g2740ro9vg; ; ; # ٽ𞥕.𑑂𞤶Ⴍ-
+ٽ𞥕。𑑂𞤶ⴍ-; ٽ𞥕.𑑂𞤶ⴍ-; [B1, V3, V5]; xn--2ib0338v.xn----zvs0199fo91g; ; ; # ٽ𞥕.𑑂𞤶ⴍ-
+ٽ𞥕。𑑂𞤔Ⴍ-; ٽ𞥕.𑑂𞤶Ⴍ-; [B1, P1, V3, V5, V6]; xn--2ib0338v.xn----w0g2740ro9vg; ; ; # ٽ𞥕.𑑂𞤶Ⴍ-
+ٽ𞥕。𑑂𞤔ⴍ-; ٽ𞥕.𑑂𞤶ⴍ-; [B1, V3, V5]; xn--2ib0338v.xn----zvs0199fo91g; ; ; # ٽ𞥕.𑑂𞤶ⴍ-
+𐯀𐸉𞧏。񢚧₄Ⴋ񂹫; 𐯀𐸉𞧏.񢚧4Ⴋ񂹫; [P1, V6]; xn--039c42bq865a.xn--4-t0g49302fnrzm; ; ; # .4Ⴋ
+𐯀𐸉𞧏。񢚧4Ⴋ񂹫; 𐯀𐸉𞧏.񢚧4Ⴋ񂹫; [P1, V6]; xn--039c42bq865a.xn--4-t0g49302fnrzm; ; ; # .4Ⴋ
+𐯀𐸉𞧏。񢚧4ⴋ񂹫; 𐯀𐸉𞧏.񢚧4ⴋ񂹫; [P1, V6]; xn--039c42bq865a.xn--4-wvs27840bnrzm; ; ; # .4ⴋ
+xn--039c42bq865a.xn--4-wvs27840bnrzm; 𐯀𐸉𞧏.񢚧4ⴋ񂹫; [V6]; xn--039c42bq865a.xn--4-wvs27840bnrzm; ; ; # .4ⴋ
+xn--039c42bq865a.xn--4-t0g49302fnrzm; 𐯀𐸉𞧏.񢚧4Ⴋ񂹫; [V6]; xn--039c42bq865a.xn--4-t0g49302fnrzm; ; ; # .4Ⴋ
+𐯀𐸉𞧏。񢚧₄ⴋ񂹫; 𐯀𐸉𞧏.񢚧4ⴋ񂹫; [P1, V6]; xn--039c42bq865a.xn--4-wvs27840bnrzm; ; ; # .4ⴋ
+4ڽ︒󠑥.≠; ; [B1, P1, V6]; xn--4-kvc5601q2h50i.xn--1ch; ; ; # 4ڽ︒.≠
+4ڽ︒󠑥.≠; 4ڽ︒󠑥.≠; [B1, P1, V6]; xn--4-kvc5601q2h50i.xn--1ch; ; ; # 4ڽ︒.≠
+4ڽ。󠑥.≠; 4ڽ.󠑥.≠; [B1, P1, V6]; xn--4-kvc.xn--5136e.xn--1ch; ; ; # 4ڽ..≠
+4ڽ。󠑥.≠; 4ڽ.󠑥.≠; [B1, P1, V6]; xn--4-kvc.xn--5136e.xn--1ch; ; ; # 4ڽ..≠
+xn--4-kvc.xn--5136e.xn--1ch; 4ڽ.󠑥.≠; [B1, V6]; xn--4-kvc.xn--5136e.xn--1ch; ; ; # 4ڽ..≠
+xn--4-kvc5601q2h50i.xn--1ch; 4ڽ︒󠑥.≠; [B1, V6]; xn--4-kvc5601q2h50i.xn--1ch; ; ; # 4ڽ︒.≠
+𝟓。ۗ; 5.ۗ; [V5]; 5.xn--nlb; ; ; # 5.ۗ
+5。ۗ; 5.ۗ; [V5]; 5.xn--nlb; ; ; # 5.ۗ
+5.xn--nlb; 5.ۗ; [V5]; 5.xn--nlb; ; ; # 5.ۗ
+‌򺸩.⾕; ‌򺸩.谷; [C1, P1, V6]; xn--0ug26167i.xn--6g3a; ; xn--i183d.xn--6g3a; [P1, V6] # .谷
+‌򺸩.谷; ; [C1, P1, V6]; xn--0ug26167i.xn--6g3a; ; xn--i183d.xn--6g3a; [P1, V6] # .谷
+xn--i183d.xn--6g3a; 򺸩.谷; [V6]; xn--i183d.xn--6g3a; ; ; # .谷
+xn--0ug26167i.xn--6g3a; ‌򺸩.谷; [C1, V6]; xn--0ug26167i.xn--6g3a; ; ; # .谷
+︒󎰇‍.-ܼ‌; ; [C1, C2, P1, V3, V6]; xn--1ug1658ftw26f.xn----t2c071q; ; xn--y86c71305c.xn----t2c; [P1, V3, V6] # ︒.-ܼ
+。󎰇‍.-ܼ‌; .󎰇‍.-ܼ‌; [C1, C2, P1, V3, V6, X4_2]; .xn--1ug05310k.xn----t2c071q; [C1, C2, P1, V3, V6, A4_2]; .xn--hh50e.xn----t2c; [P1, V3, V6, A4_2] # ..-ܼ
+.xn--hh50e.xn----t2c; .󎰇.-ܼ; [V3, V6, X4_2]; .xn--hh50e.xn----t2c; [V3, V6, A4_2]; ; # ..-ܼ
+.xn--1ug05310k.xn----t2c071q; .󎰇‍.-ܼ‌; [C1, C2, V3, V6, X4_2]; .xn--1ug05310k.xn----t2c071q; [C1, C2, V3, V6, A4_2]; ; # ..-ܼ
+xn--y86c71305c.xn----t2c; ︒󎰇.-ܼ; [V3, V6]; xn--y86c71305c.xn----t2c; ; ; # ︒.-ܼ
+xn--1ug1658ftw26f.xn----t2c071q; ︒󎰇‍.-ܼ‌; [C1, C2, V3, V6]; xn--1ug1658ftw26f.xn----t2c071q; ; ; # ︒.-ܼ
+≯𞤟。ᡨ; ≯𞥁.ᡨ; [B1, P1, V6]; xn--hdhz520p.xn--48e; ; ; # ≯𞥁.ᡨ
+≯𞤟。ᡨ; ≯𞥁.ᡨ; [B1, P1, V6]; xn--hdhz520p.xn--48e; ; ; # ≯𞥁.ᡨ
+≯𞥁。ᡨ; ≯𞥁.ᡨ; [B1, P1, V6]; xn--hdhz520p.xn--48e; ; ; # ≯𞥁.ᡨ
+≯𞥁。ᡨ; ≯𞥁.ᡨ; [B1, P1, V6]; xn--hdhz520p.xn--48e; ; ; # ≯𞥁.ᡨ
+xn--hdhz520p.xn--48e; ≯𞥁.ᡨ; [B1, V6]; xn--hdhz520p.xn--48e; ; ; # ≯𞥁.ᡨ
+ུ𫫰𝨄。ܓ𐹦; ུ𫫰𝨄.ܓ𐹦; [B1, V5]; xn--ned8985uo92e.xn--dnb6395k; ; ; # ུ𫫰𝨄.ܓ𐹦
+xn--ned8985uo92e.xn--dnb6395k; ུ𫫰𝨄.ܓ𐹦; [B1, V5]; xn--ned8985uo92e.xn--dnb6395k; ; ; # ུ𫫰𝨄.ܓ𐹦
+̼ߛ⁷𝟹。𝟬; ̼ߛ73.0; [B1, V5]; xn--73-9yb648b.0; ; ; # ̼ߛ73.0
+̼ߛ73。0; ̼ߛ73.0; [B1, V5]; xn--73-9yb648b.0; ; ; # ̼ߛ73.0
+xn--73-9yb648b.0; ̼ߛ73.0; [B1, V5]; xn--73-9yb648b.0; ; ; # ̼ߛ73.0
+‍.𝟗; ‍.9; [C2]; xn--1ug.9; ; .9; [A4_2] # .9
+‍.9; ; [C2]; xn--1ug.9; ; .9; [A4_2] # .9
+.9; ; [X4_2]; ; [A4_2]; ; # .9
+xn--1ug.9; ‍.9; [C2]; xn--1ug.9; ; ; # .9
+9; ; ; ; ; ; # 9
+ݹᡭ𪕈。ڶࣙ; ݹᡭ𪕈.ڶࣙ; [B2, B3]; xn--9pb497fs270c.xn--pkb80i; ; ; # ݹᡭ𪕈.ڶࣙ
+xn--9pb497fs270c.xn--pkb80i; ݹᡭ𪕈.ڶࣙ; [B2, B3]; xn--9pb497fs270c.xn--pkb80i; ; ; # ݹᡭ𪕈.ڶࣙ
+ܦ5ߢ겙。᳴𐷚; ܦ5ߢ겙.᳴𐷚; [B1, B2, B3, P1, V5, V6]; xn--5-j1c97c2483c.xn--e7f2093h; ; ; # ܦ5ߢ겙.᳴
+ܦ5ߢ겙。᳴𐷚; ܦ5ߢ겙.᳴𐷚; [B1, B2, B3, P1, V5, V6]; xn--5-j1c97c2483c.xn--e7f2093h; ; ; # ܦ5ߢ겙.᳴
+ܦ5ߢ겙。᳴𐷚; ܦ5ߢ겙.᳴𐷚; [B1, B2, B3, P1, V5, V6]; xn--5-j1c97c2483c.xn--e7f2093h; ; ; # ܦ5ߢ겙.᳴
+ܦ5ߢ겙。᳴𐷚; ܦ5ߢ겙.᳴𐷚; [B1, B2, B3, P1, V5, V6]; xn--5-j1c97c2483c.xn--e7f2093h; ; ; # ܦ5ߢ겙.᳴
+xn--5-j1c97c2483c.xn--e7f2093h; ܦ5ߢ겙.᳴𐷚; [B1, B2, B3, V5, V6]; xn--5-j1c97c2483c.xn--e7f2093h; ; ; # ܦ5ߢ겙.᳴
+Ⴍ𿣍ꡨ֮。Ⴞ‌‌; Ⴍ𿣍ꡨ֮.Ⴞ‌‌; [C1, P1, V6]; xn--5cb347co96jug15a.xn--2nd059ea; ; xn--5cb347co96jug15a.xn--2nd; [P1, V6] # Ⴍꡨ֮.Ⴞ
+ⴍ𿣍ꡨ֮。ⴞ‌‌; ⴍ𿣍ꡨ֮.ⴞ‌‌; [C1, P1, V6]; xn--5cb172r175fug38a.xn--0uga051h; ; xn--5cb172r175fug38a.xn--mlj; [P1, V6] # ⴍꡨ֮.ⴞ
+xn--5cb172r175fug38a.xn--mlj; ⴍ𿣍ꡨ֮.ⴞ; [V6]; xn--5cb172r175fug38a.xn--mlj; ; ; # ⴍꡨ֮.ⴞ
+xn--5cb172r175fug38a.xn--0uga051h; ⴍ𿣍ꡨ֮.ⴞ‌‌; [C1, V6]; xn--5cb172r175fug38a.xn--0uga051h; ; ; # ⴍꡨ֮.ⴞ
+xn--5cb347co96jug15a.xn--2nd; Ⴍ𿣍ꡨ֮.Ⴞ; [V6]; xn--5cb347co96jug15a.xn--2nd; ; ; # Ⴍꡨ֮.Ⴞ
+xn--5cb347co96jug15a.xn--2nd059ea; Ⴍ𿣍ꡨ֮.Ⴞ‌‌; [C1, V6]; xn--5cb347co96jug15a.xn--2nd059ea; ; ; # Ⴍꡨ֮.Ⴞ
+𐋰。󑓱; 𐋰.󑓱; [P1, V6]; xn--k97c.xn--q031e; ; ; # 𐋰.
+xn--k97c.xn--q031e; 𐋰.󑓱; [V6]; xn--k97c.xn--q031e; ; ; # 𐋰.
+󡎦឴୍.𐹾; ; [B1, P1, V6]; xn--9ic364dho91z.xn--2o0d; ; ; # ୍.𐹾
+xn--9ic364dho91z.xn--2o0d; 󡎦឴୍.𐹾; [B1, V6]; xn--9ic364dho91z.xn--2o0d; ; ; # ୍.𐹾
+ࣟႫ𶿸귤.򠅼𝟢휪ૣ; ࣟႫ𶿸귤.򠅼0휪ૣ; [P1, V5, V6]; xn--i0b601b6r7l2hs0a.xn--0-8le8997mulr5f; ; ; # ࣟႫ귤.0휪ૣ
+ࣟႫ𶿸귤.򠅼𝟢휪ૣ; ࣟႫ𶿸귤.򠅼0휪ૣ; [P1, V5, V6]; xn--i0b601b6r7l2hs0a.xn--0-8le8997mulr5f; ; ; # ࣟႫ귤.0휪ૣ
+ࣟႫ𶿸귤.򠅼0휪ૣ; ; [P1, V5, V6]; xn--i0b601b6r7l2hs0a.xn--0-8le8997mulr5f; ; ; # ࣟႫ귤.0휪ૣ
+ࣟႫ𶿸귤.򠅼0휪ૣ; ࣟႫ𶿸귤.򠅼0휪ૣ; [P1, V5, V6]; xn--i0b601b6r7l2hs0a.xn--0-8le8997mulr5f; ; ; # ࣟႫ귤.0휪ૣ
+ࣟⴋ𶿸귤.򠅼0휪ૣ; ࣟⴋ𶿸귤.򠅼0휪ૣ; [P1, V5, V6]; xn--i0b436pkl2g2h42a.xn--0-8le8997mulr5f; ; ; # ࣟⴋ귤.0휪ૣ
+ࣟⴋ𶿸귤.򠅼0휪ૣ; ; [P1, V5, V6]; xn--i0b436pkl2g2h42a.xn--0-8le8997mulr5f; ; ; # ࣟⴋ귤.0휪ૣ
+xn--i0b436pkl2g2h42a.xn--0-8le8997mulr5f; ࣟⴋ𶿸귤.򠅼0휪ૣ; [V5, V6]; xn--i0b436pkl2g2h42a.xn--0-8le8997mulr5f; ; ; # ࣟⴋ귤.0휪ૣ
+xn--i0b601b6r7l2hs0a.xn--0-8le8997mulr5f; ࣟႫ𶿸귤.򠅼0휪ૣ; [V5, V6]; xn--i0b601b6r7l2hs0a.xn--0-8le8997mulr5f; ; ; # ࣟႫ귤.0휪ૣ
+ࣟⴋ𶿸귤.򠅼𝟢휪ૣ; ࣟⴋ𶿸귤.򠅼0휪ૣ; [P1, V5, V6]; xn--i0b436pkl2g2h42a.xn--0-8le8997mulr5f; ; ; # ࣟⴋ귤.0휪ૣ
+ࣟⴋ𶿸귤.򠅼𝟢휪ૣ; ࣟⴋ𶿸귤.򠅼0휪ૣ; [P1, V5, V6]; xn--i0b436pkl2g2h42a.xn--0-8le8997mulr5f; ; ; # ࣟⴋ귤.0휪ૣ
+ބ.𞡝؁; ބ.𞡝؁; [P1, V6]; xn--lqb.xn--jfb1808v; ; ; # ބ.𞡝
+ބ.𞡝؁; ; [P1, V6]; xn--lqb.xn--jfb1808v; ; ; # ބ.𞡝
+xn--lqb.xn--jfb1808v; ބ.𞡝؁; [V6]; xn--lqb.xn--jfb1808v; ; ; # ބ.𞡝
+્₃.8꣄‍🃤; ્3.8꣄‍🃤; [V5]; xn--3-yke.xn--8-ugnv982dbkwm; ; xn--3-yke.xn--8-sl4et308f; # ્3.8꣄🃤
+્3.8꣄‍🃤; ; [V5]; xn--3-yke.xn--8-ugnv982dbkwm; ; xn--3-yke.xn--8-sl4et308f; # ્3.8꣄🃤
+xn--3-yke.xn--8-sl4et308f; ્3.8꣄🃤; [V5]; xn--3-yke.xn--8-sl4et308f; ; ; # ્3.8꣄🃤
+xn--3-yke.xn--8-ugnv982dbkwm; ્3.8꣄‍🃤; [V5]; xn--3-yke.xn--8-ugnv982dbkwm; ; ; # ્3.8꣄🃤
+℻⩷𝆆。𞤠󠆁᠌; fax⩷𝆆.𞥂; [B6]; xn--fax-4c9a1676t.xn--6e6h; ; ; # fax⩷𝆆.𞥂
+FAX⩷𝆆。𞤠󠆁᠌; fax⩷𝆆.𞥂; [B6]; xn--fax-4c9a1676t.xn--6e6h; ; ; # fax⩷𝆆.𞥂
+fax⩷𝆆。𞥂󠆁᠌; fax⩷𝆆.𞥂; [B6]; xn--fax-4c9a1676t.xn--6e6h; ; ; # fax⩷𝆆.𞥂
+Fax⩷𝆆。𞤠󠆁᠌; fax⩷𝆆.𞥂; [B6]; xn--fax-4c9a1676t.xn--6e6h; ; ; # fax⩷𝆆.𞥂
+xn--fax-4c9a1676t.xn--6e6h; fax⩷𝆆.𞥂; [B6]; xn--fax-4c9a1676t.xn--6e6h; ; ; # fax⩷𝆆.𞥂
+℻⩷𝆆。𞥂󠆁᠌; fax⩷𝆆.𞥂; [B6]; xn--fax-4c9a1676t.xn--6e6h; ; ; # fax⩷𝆆.𞥂
+FAX⩷𝆆。𞥂󠆁᠌; fax⩷𝆆.𞥂; [B6]; xn--fax-4c9a1676t.xn--6e6h; ; ; # fax⩷𝆆.𞥂
+fax⩷𝆆。𞤠󠆁᠌; fax⩷𝆆.𞥂; [B6]; xn--fax-4c9a1676t.xn--6e6h; ; ; # fax⩷𝆆.𞥂
+fax⩷𝆆.𞥂; ; [B6]; xn--fax-4c9a1676t.xn--6e6h; ; ; # fax⩷𝆆.𞥂
+FAX⩷𝆆.𞤠; fax⩷𝆆.𞥂; [B6]; xn--fax-4c9a1676t.xn--6e6h; ; ; # fax⩷𝆆.𞥂
+Fax⩷𝆆.𞤠; fax⩷𝆆.𞥂; [B6]; xn--fax-4c9a1676t.xn--6e6h; ; ; # fax⩷𝆆.𞥂
+FAX⩷𝆆.𞥂; fax⩷𝆆.𞥂; [B6]; xn--fax-4c9a1676t.xn--6e6h; ; ; # fax⩷𝆆.𞥂
+Fax⩷𝆆.𞥂; fax⩷𝆆.𞥂; [B6]; xn--fax-4c9a1676t.xn--6e6h; ; ; # fax⩷𝆆.𞥂
+ꡕ≠ၞ󮿱。𐵧󠄫ᅠ; ꡕ≠ၞ󮿱.𐵧ᅠ; [B2, B3, P1, V6]; xn--cld333gn31h0158l.xn--cl7c96v; ; ; # ꡕ≠ၞ.
+ꡕ≠ၞ󮿱。𐵧󠄫ᅠ; ꡕ≠ၞ󮿱.𐵧ᅠ; [B2, B3, P1, V6]; xn--cld333gn31h0158l.xn--cl7c96v; ; ; # ꡕ≠ၞ.
+ꡕ≠ၞ󮿱。𐵧󠄫ᅠ; ꡕ≠ၞ󮿱.𐵧ᅠ; [B2, B3, P1, V6]; xn--cld333gn31h0158l.xn--psd1510k; ; ; # ꡕ≠ၞ.
+ꡕ≠ၞ󮿱。𐵧󠄫ᅠ; ꡕ≠ၞ󮿱.𐵧ᅠ; [B2, B3, P1, V6]; xn--cld333gn31h0158l.xn--psd1510k; ; ; # ꡕ≠ၞ.
+xn--cld333gn31h0158l.xn--psd1510k; ꡕ≠ၞ󮿱.𐵧ᅠ; [B2, B3, V6]; xn--cld333gn31h0158l.xn--psd1510k; ; ; # ꡕ≠ၞ.
+xn--cld333gn31h0158l.xn--cl7c96v; ꡕ≠ၞ󮿱.𐵧ᅠ; [B2, B3, V6]; xn--cld333gn31h0158l.xn--cl7c96v; ; ; # ꡕ≠ၞ.
+鱊。‌; 鱊.‌; [C1]; xn--rt6a.xn--0ug; ; xn--rt6a.; [] # 鱊.
+xn--rt6a.; 鱊.; ; xn--rt6a.; ; ; # 鱊.
+鱊.; ; ; xn--rt6a.; ; ; # 鱊.
+xn--rt6a.xn--0ug; 鱊.‌; [C1]; xn--rt6a.xn--0ug; ; ; # 鱊.
+8𐹣.𑍨; 8𐹣.𑍨; [B1, B3, B6, V5]; xn--8-d26i.xn--0p1d; ; ; # 8𐹣.𑍨
+8𐹣.𑍨; ; [B1, B3, B6, V5]; xn--8-d26i.xn--0p1d; ; ; # 8𐹣.𑍨
+xn--8-d26i.xn--0p1d; 8𐹣.𑍨; [B1, B3, B6, V5]; xn--8-d26i.xn--0p1d; ; ; # 8𐹣.𑍨
+⏹𐧀.𐫯; ⏹𐧀.𐫯; [B1]; xn--qoh9161g.xn--1x9c; ; ; # ⏹𐧀.𐫯
+⏹𐧀.𐫯; ; [B1]; xn--qoh9161g.xn--1x9c; ; ; # ⏹𐧀.𐫯
+xn--qoh9161g.xn--1x9c; ⏹𐧀.𐫯; [B1]; xn--qoh9161g.xn--1x9c; ; ; # ⏹𐧀.𐫯
+𞤺ߌ4.‍; 𞤺ߌ4.‍; [B1, C2]; xn--4-0bd15808a.xn--1ug; ; xn--4-0bd15808a.; [] # 𞤺ߌ4.
+𞤺ߌ4.‍; ; [B1, C2]; xn--4-0bd15808a.xn--1ug; ; xn--4-0bd15808a.; [] # 𞤺ߌ4.
+𞤘ߌ4.‍; 𞤺ߌ4.‍; [B1, C2]; xn--4-0bd15808a.xn--1ug; ; xn--4-0bd15808a.; [] # 𞤺ߌ4.
+xn--4-0bd15808a.; 𞤺ߌ4.; ; xn--4-0bd15808a.; ; ; # 𞤺ߌ4.
+𞤺ߌ4.; ; ; xn--4-0bd15808a.; ; ; # 𞤺ߌ4.
+𞤘ߌ4.; 𞤺ߌ4.; ; xn--4-0bd15808a.; ; ; # 𞤺ߌ4.
+xn--4-0bd15808a.xn--1ug; 𞤺ߌ4.‍; [B1, C2]; xn--4-0bd15808a.xn--1ug; ; ; # 𞤺ߌ4.
+𞤘ߌ4.‍; 𞤺ߌ4.‍; [B1, C2]; xn--4-0bd15808a.xn--1ug; ; xn--4-0bd15808a.; [] # 𞤺ߌ4.
+⒗ঁ⃯-.࣢•; ; [B1, P1, V3, V6]; xn----z0d801p6kd.xn--l0b810j; ; ; # ⒗ঁ⃯-.•
+16.ঁ⃯-.࣢•; ; [B1, P1, V3, V5, V6]; 16.xn----z0d801p.xn--l0b810j; ; ; # 16.ঁ⃯-.•
+16.xn----z0d801p.xn--l0b810j; 16.ঁ⃯-.࣢•; [B1, V3, V5, V6]; 16.xn----z0d801p.xn--l0b810j; ; ; # 16.ঁ⃯-.•
+xn----z0d801p6kd.xn--l0b810j; ⒗ঁ⃯-.࣢•; [B1, V3, V6]; xn----z0d801p6kd.xn--l0b810j; ; ; # ⒗ঁ⃯-.•
+-。䏛; -.䏛; [V3]; -.xn--xco; ; ; # -.䏛
+-。䏛; -.䏛; [V3]; -.xn--xco; ; ; # -.䏛
+-.xn--xco; -.䏛; [V3]; -.xn--xco; ; ; # -.䏛
+‌񒃠.‍; ‌񒃠.‍; [C1, C2, P1, V6]; xn--0ugz7551c.xn--1ug; ; xn--dj8y.; [P1, V6] # .
+‌񒃠.‍; ; [C1, C2, P1, V6]; xn--0ugz7551c.xn--1ug; ; xn--dj8y.; [P1, V6] # .
+xn--dj8y.; 񒃠.; [V6]; xn--dj8y.; ; ; # .
+xn--0ugz7551c.xn--1ug; ‌񒃠.‍; [C1, C2, V6]; xn--0ugz7551c.xn--1ug; ; ; # .
+⒈⓰󥣇。𐹠‍򗷦Ⴕ; ⒈⓰󥣇.𐹠‍򗷦Ⴕ; [B1, C2, P1, V6]; xn--tsh0nz9380h.xn--tnd969erj4psgl3e; ; xn--tsh0nz9380h.xn--tnd1990ke579c; [B1, P1, V6] # ⒈⓰.𐹠Ⴕ
+1.⓰󥣇。𐹠‍򗷦Ⴕ; 1.⓰󥣇.𐹠‍򗷦Ⴕ; [B1, C2, P1, V6]; 1.xn--svh00804k.xn--tnd969erj4psgl3e; ; 1.xn--svh00804k.xn--tnd1990ke579c; [B1, P1, V6] # 1.⓰.𐹠Ⴕ
+1.⓰󥣇。𐹠‍򗷦ⴕ; 1.⓰󥣇.𐹠‍򗷦ⴕ; [B1, C2, P1, V6]; 1.xn--svh00804k.xn--1ug352csp0psg45e; ; 1.xn--svh00804k.xn--dljv223ee5t2d; [B1, P1, V6] # 1.⓰.𐹠ⴕ
+1.xn--svh00804k.xn--dljv223ee5t2d; 1.⓰󥣇.𐹠򗷦ⴕ; [B1, V6]; 1.xn--svh00804k.xn--dljv223ee5t2d; ; ; # 1.⓰.𐹠ⴕ
+1.xn--svh00804k.xn--1ug352csp0psg45e; 1.⓰󥣇.𐹠‍򗷦ⴕ; [B1, C2, V6]; 1.xn--svh00804k.xn--1ug352csp0psg45e; ; ; # 1.⓰.𐹠ⴕ
+1.xn--svh00804k.xn--tnd1990ke579c; 1.⓰󥣇.𐹠򗷦Ⴕ; [B1, V6]; 1.xn--svh00804k.xn--tnd1990ke579c; ; ; # 1.⓰.𐹠Ⴕ
+1.xn--svh00804k.xn--tnd969erj4psgl3e; 1.⓰󥣇.𐹠‍򗷦Ⴕ; [B1, C2, V6]; 1.xn--svh00804k.xn--tnd969erj4psgl3e; ; ; # 1.⓰.𐹠Ⴕ
+⒈⓰󥣇。𐹠‍򗷦ⴕ; ⒈⓰󥣇.𐹠‍򗷦ⴕ; [B1, C2, P1, V6]; xn--tsh0nz9380h.xn--1ug352csp0psg45e; ; xn--tsh0nz9380h.xn--dljv223ee5t2d; [B1, P1, V6] # ⒈⓰.𐹠ⴕ
+xn--tsh0nz9380h.xn--dljv223ee5t2d; ⒈⓰󥣇.𐹠򗷦ⴕ; [B1, V6]; xn--tsh0nz9380h.xn--dljv223ee5t2d; ; ; # ⒈⓰.𐹠ⴕ
+xn--tsh0nz9380h.xn--1ug352csp0psg45e; ⒈⓰󥣇.𐹠‍򗷦ⴕ; [B1, C2, V6]; xn--tsh0nz9380h.xn--1ug352csp0psg45e; ; ; # ⒈⓰.𐹠ⴕ
+xn--tsh0nz9380h.xn--tnd1990ke579c; ⒈⓰󥣇.𐹠򗷦Ⴕ; [B1, V6]; xn--tsh0nz9380h.xn--tnd1990ke579c; ; ; # ⒈⓰.𐹠Ⴕ
+xn--tsh0nz9380h.xn--tnd969erj4psgl3e; ⒈⓰󥣇.𐹠‍򗷦Ⴕ; [B1, C2, V6]; xn--tsh0nz9380h.xn--tnd969erj4psgl3e; ; ; # ⒈⓰.𐹠Ⴕ
+𞠊ᠮ-ß。᳐効؁𷣭; 𞠊ᠮ-ß.᳐効؁𷣭; [B1, B2, B3, P1, V5, V6]; xn----qfa310pg973b.xn--jfb197i791bi6x4c; ; xn---ss-21t18904a.xn--jfb197i791bi6x4c; # 𞠊ᠮ-ß.᳐効
+𞠊ᠮ-ß。᳐効؁𷣭; 𞠊ᠮ-ß.᳐効؁𷣭; [B1, B2, B3, P1, V5, V6]; xn----qfa310pg973b.xn--jfb197i791bi6x4c; ; xn---ss-21t18904a.xn--jfb197i791bi6x4c; # 𞠊ᠮ-ß.᳐効
+𞠊ᠮ-SS。᳐効؁𷣭; 𞠊ᠮ-ss.᳐効؁𷣭; [B1, B2, B3, P1, V5, V6]; xn---ss-21t18904a.xn--jfb197i791bi6x4c; ; ; # 𞠊ᠮ-ss.᳐効
+𞠊ᠮ-ss。᳐効؁𷣭; 𞠊ᠮ-ss.᳐効؁𷣭; [B1, B2, B3, P1, V5, V6]; xn---ss-21t18904a.xn--jfb197i791bi6x4c; ; ; # 𞠊ᠮ-ss.᳐効
+𞠊ᠮ-Ss。᳐効؁𷣭; 𞠊ᠮ-ss.᳐効؁𷣭; [B1, B2, B3, P1, V5, V6]; xn---ss-21t18904a.xn--jfb197i791bi6x4c; ; ; # 𞠊ᠮ-ss.᳐効
+xn---ss-21t18904a.xn--jfb197i791bi6x4c; 𞠊ᠮ-ss.᳐効؁𷣭; [B1, B2, B3, V5, V6]; xn---ss-21t18904a.xn--jfb197i791bi6x4c; ; ; # 𞠊ᠮ-ss.᳐効
+xn----qfa310pg973b.xn--jfb197i791bi6x4c; 𞠊ᠮ-ß.᳐効؁𷣭; [B1, B2, B3, V5, V6]; xn----qfa310pg973b.xn--jfb197i791bi6x4c; ; ; # 𞠊ᠮ-ß.᳐効
+𞠊ᠮ-SS。᳐効؁𷣭; 𞠊ᠮ-ss.᳐効؁𷣭; [B1, B2, B3, P1, V5, V6]; xn---ss-21t18904a.xn--jfb197i791bi6x4c; ; ; # 𞠊ᠮ-ss.᳐効
+𞠊ᠮ-ss。᳐効؁𷣭; 𞠊ᠮ-ss.᳐効؁𷣭; [B1, B2, B3, P1, V5, V6]; xn---ss-21t18904a.xn--jfb197i791bi6x4c; ; ; # 𞠊ᠮ-ss.᳐効
+𞠊ᠮ-Ss。᳐効؁𷣭; 𞠊ᠮ-ss.᳐効؁𷣭; [B1, B2, B3, P1, V5, V6]; xn---ss-21t18904a.xn--jfb197i791bi6x4c; ; ; # 𞠊ᠮ-ss.᳐効
+𑇀.󠨱; ; [P1, V5, V6]; xn--wd1d.xn--k946e; ; ; # 𑇀.
+xn--wd1d.xn--k946e; 𑇀.󠨱; [V5, V6]; xn--wd1d.xn--k946e; ; ; # 𑇀.
+␒3ﮈ。𝟘𐨿𐹆; ␒3ڈ.0𐨿𐹆; [B1, P1, V6]; xn--3-jsc897t.xn--0-sc5iy3h; ; ; # ␒3ڈ.0𐨿
+␒3ڈ。0𐨿𐹆; ␒3ڈ.0𐨿𐹆; [B1, P1, V6]; xn--3-jsc897t.xn--0-sc5iy3h; ; ; # ␒3ڈ.0𐨿
+xn--3-jsc897t.xn--0-sc5iy3h; ␒3ڈ.0𐨿𐹆; [B1, V6]; xn--3-jsc897t.xn--0-sc5iy3h; ; ; # ␒3ڈ.0𐨿
+ݫ6ઁࢦ。ᷣ; ݫ6ઁࢦ.ᷣ; [B1, B3, B6, V5]; xn--6-h5c06gj6c.xn--7eg; ; ; # ݫ6ઁࢦ.ᷣ
+ݫ6ઁࢦ。ᷣ; ݫ6ઁࢦ.ᷣ; [B1, B3, B6, V5]; xn--6-h5c06gj6c.xn--7eg; ; ; # ݫ6ઁࢦ.ᷣ
+xn--6-h5c06gj6c.xn--7eg; ݫ6ઁࢦ.ᷣ; [B1, B3, B6, V5]; xn--6-h5c06gj6c.xn--7eg; ; ; # ݫ6ઁࢦ.ᷣ
+؅-𽤞Ⴂ。򅤶‍; ؅-𽤞Ⴂ.򅤶‍; [B1, B6, C2, P1, V6]; xn----0kc662fc152h.xn--1ugy3204f; ; xn----0kc662fc152h.xn--ss06b; [B1, P1, V6] # -Ⴂ.
+؅-𽤞ⴂ。򅤶‍; ؅-𽤞ⴂ.򅤶‍; [B1, B6, C2, P1, V6]; xn----0kc8501a5399e.xn--1ugy3204f; ; xn----0kc8501a5399e.xn--ss06b; [B1, P1, V6] # -ⴂ.
+xn----0kc8501a5399e.xn--ss06b; ؅-𽤞ⴂ.򅤶; [B1, V6]; xn----0kc8501a5399e.xn--ss06b; ; ; # -ⴂ.
+xn----0kc8501a5399e.xn--1ugy3204f; ؅-𽤞ⴂ.򅤶‍; [B1, B6, C2, V6]; xn----0kc8501a5399e.xn--1ugy3204f; ; ; # -ⴂ.
+xn----0kc662fc152h.xn--ss06b; ؅-𽤞Ⴂ.򅤶; [B1, V6]; xn----0kc662fc152h.xn--ss06b; ; ; # -Ⴂ.
+xn----0kc662fc152h.xn--1ugy3204f; ؅-𽤞Ⴂ.򅤶‍; [B1, B6, C2, V6]; xn----0kc662fc152h.xn--1ugy3204f; ; ; # -Ⴂ.
+⾆.ꡈ5≯ß; 舌.ꡈ5≯ß; [P1, V6]; xn--tc1a.xn--5-qfa988w745i; ; xn--tc1a.xn--5ss-3m2a5009e; # 舌.ꡈ5≯ß
+⾆.ꡈ5≯ß; 舌.ꡈ5≯ß; [P1, V6]; xn--tc1a.xn--5-qfa988w745i; ; xn--tc1a.xn--5ss-3m2a5009e; # 舌.ꡈ5≯ß
+舌.ꡈ5≯ß; ; [P1, V6]; xn--tc1a.xn--5-qfa988w745i; ; xn--tc1a.xn--5ss-3m2a5009e; # 舌.ꡈ5≯ß
+舌.ꡈ5≯ß; 舌.ꡈ5≯ß; [P1, V6]; xn--tc1a.xn--5-qfa988w745i; ; xn--tc1a.xn--5ss-3m2a5009e; # 舌.ꡈ5≯ß
+舌.ꡈ5≯SS; 舌.ꡈ5≯ss; [P1, V6]; xn--tc1a.xn--5ss-3m2a5009e; ; ; # 舌.ꡈ5≯ss
+舌.ꡈ5≯SS; 舌.ꡈ5≯ss; [P1, V6]; xn--tc1a.xn--5ss-3m2a5009e; ; ; # 舌.ꡈ5≯ss
+舌.ꡈ5≯ss; ; [P1, V6]; xn--tc1a.xn--5ss-3m2a5009e; ; ; # 舌.ꡈ5≯ss
+舌.ꡈ5≯ss; 舌.ꡈ5≯ss; [P1, V6]; xn--tc1a.xn--5ss-3m2a5009e; ; ; # 舌.ꡈ5≯ss
+舌.ꡈ5≯Ss; 舌.ꡈ5≯ss; [P1, V6]; xn--tc1a.xn--5ss-3m2a5009e; ; ; # 舌.ꡈ5≯ss
+舌.ꡈ5≯Ss; 舌.ꡈ5≯ss; [P1, V6]; xn--tc1a.xn--5ss-3m2a5009e; ; ; # 舌.ꡈ5≯ss
+xn--tc1a.xn--5ss-3m2a5009e; 舌.ꡈ5≯ss; [V6]; xn--tc1a.xn--5ss-3m2a5009e; ; ; # 舌.ꡈ5≯ss
+xn--tc1a.xn--5-qfa988w745i; 舌.ꡈ5≯ß; [V6]; xn--tc1a.xn--5-qfa988w745i; ; ; # 舌.ꡈ5≯ß
+⾆.ꡈ5≯SS; 舌.ꡈ5≯ss; [P1, V6]; xn--tc1a.xn--5ss-3m2a5009e; ; ; # 舌.ꡈ5≯ss
+⾆.ꡈ5≯SS; 舌.ꡈ5≯ss; [P1, V6]; xn--tc1a.xn--5ss-3m2a5009e; ; ; # 舌.ꡈ5≯ss
+⾆.ꡈ5≯ss; 舌.ꡈ5≯ss; [P1, V6]; xn--tc1a.xn--5ss-3m2a5009e; ; ; # 舌.ꡈ5≯ss
+⾆.ꡈ5≯ss; 舌.ꡈ5≯ss; [P1, V6]; xn--tc1a.xn--5ss-3m2a5009e; ; ; # 舌.ꡈ5≯ss
+⾆.ꡈ5≯Ss; 舌.ꡈ5≯ss; [P1, V6]; xn--tc1a.xn--5ss-3m2a5009e; ; ; # 舌.ꡈ5≯ss
+⾆.ꡈ5≯Ss; 舌.ꡈ5≯ss; [P1, V6]; xn--tc1a.xn--5ss-3m2a5009e; ; ; # 舌.ꡈ5≯ss
+્8‍.򾂈ݜ; ્8‍.򾂈ݜ; [B1, B5, B6, C2, P1, V5, V6]; xn--8-yke534n.xn--gpb79046m; ; xn--8-yke.xn--gpb79046m; [B1, B5, B6, P1, V5, V6] # ્8.ݜ
+્8‍.򾂈ݜ; ; [B1, B5, B6, C2, P1, V5, V6]; xn--8-yke534n.xn--gpb79046m; ; xn--8-yke.xn--gpb79046m; [B1, B5, B6, P1, V5, V6] # ્8.ݜ
+xn--8-yke.xn--gpb79046m; ્8.򾂈ݜ; [B1, B5, B6, V5, V6]; xn--8-yke.xn--gpb79046m; ; ; # ્8.ݜ
+xn--8-yke534n.xn--gpb79046m; ્8‍.򾂈ݜ; [B1, B5, B6, C2, V5, V6]; xn--8-yke534n.xn--gpb79046m; ; ; # ્8.ݜ
+򸷆ੰ≮򹓙.񞎧⁷󠯙ڶ; 򸷆ੰ≮򹓙.񞎧7󠯙ڶ; [B5, B6, P1, V6]; xn--ycc893jqh38rb6fa.xn--7-5uc53836ixt41c; ; ; # ੰ≮.7ڶ
+򸷆ੰ≮򹓙.񞎧⁷󠯙ڶ; 򸷆ੰ≮򹓙.񞎧7󠯙ڶ; [B5, B6, P1, V6]; xn--ycc893jqh38rb6fa.xn--7-5uc53836ixt41c; ; ; # ੰ≮.7ڶ
+򸷆ੰ≮򹓙.񞎧7󠯙ڶ; ; [B5, B6, P1, V6]; xn--ycc893jqh38rb6fa.xn--7-5uc53836ixt41c; ; ; # ੰ≮.7ڶ
+򸷆ੰ≮򹓙.񞎧7󠯙ڶ; 򸷆ੰ≮򹓙.񞎧7󠯙ڶ; [B5, B6, P1, V6]; xn--ycc893jqh38rb6fa.xn--7-5uc53836ixt41c; ; ; # ੰ≮.7ڶ
+xn--ycc893jqh38rb6fa.xn--7-5uc53836ixt41c; 򸷆ੰ≮򹓙.񞎧7󠯙ڶ; [B5, B6, V6]; xn--ycc893jqh38rb6fa.xn--7-5uc53836ixt41c; ; ; # ੰ≮.7ڶ
+𞤪.ς; ; ; xn--ie6h.xn--3xa; ; xn--ie6h.xn--4xa; # 𞤪.ς
+𞤈.Σ; 𞤪.σ; ; xn--ie6h.xn--4xa; ; ; # 𞤪.σ
+𞤪.σ; ; ; xn--ie6h.xn--4xa; ; ; # 𞤪.σ
+𞤈.σ; 𞤪.σ; ; xn--ie6h.xn--4xa; ; ; # 𞤪.σ
+xn--ie6h.xn--4xa; 𞤪.σ; ; xn--ie6h.xn--4xa; ; ; # 𞤪.σ
+𞤈.ς; 𞤪.ς; ; xn--ie6h.xn--3xa; ; xn--ie6h.xn--4xa; # 𞤪.ς
+xn--ie6h.xn--3xa; 𞤪.ς; ; xn--ie6h.xn--3xa; ; ; # 𞤪.ς
+𞤪.Σ; 𞤪.σ; ; xn--ie6h.xn--4xa; ; ; # 𞤪.σ
+‌Ⴚ。ς; ‌Ⴚ.ς; [C1, P1, V6]; xn--ynd759e.xn--3xa; ; xn--ynd.xn--4xa; [P1, V6] # Ⴚ.ς
+‌Ⴚ。ς; ‌Ⴚ.ς; [C1, P1, V6]; xn--ynd759e.xn--3xa; ; xn--ynd.xn--4xa; [P1, V6] # Ⴚ.ς
+‌ⴚ。ς; ‌ⴚ.ς; [C1]; xn--0ug262c.xn--3xa; ; xn--ilj.xn--4xa; [] # ⴚ.ς
+‌Ⴚ。Σ; ‌Ⴚ.σ; [C1, P1, V6]; xn--ynd759e.xn--4xa; ; xn--ynd.xn--4xa; [P1, V6] # Ⴚ.σ
+‌ⴚ。σ; ‌ⴚ.σ; [C1]; xn--0ug262c.xn--4xa; ; xn--ilj.xn--4xa; [] # ⴚ.σ
+xn--ilj.xn--4xa; ⴚ.σ; ; xn--ilj.xn--4xa; ; ; # ⴚ.σ
+ⴚ.σ; ; ; xn--ilj.xn--4xa; ; ; # ⴚ.σ
+Ⴚ.Σ; Ⴚ.σ; [P1, V6]; xn--ynd.xn--4xa; ; ; # Ⴚ.σ
+ⴚ.ς; ; ; xn--ilj.xn--3xa; ; xn--ilj.xn--4xa; # ⴚ.ς
+Ⴚ.ς; ; [P1, V6]; xn--ynd.xn--3xa; ; xn--ynd.xn--4xa; # Ⴚ.ς
+xn--ynd.xn--4xa; Ⴚ.σ; [V6]; xn--ynd.xn--4xa; ; ; # Ⴚ.σ
+xn--ynd.xn--3xa; Ⴚ.ς; [V6]; xn--ynd.xn--3xa; ; ; # Ⴚ.ς
+xn--ilj.xn--3xa; ⴚ.ς; ; xn--ilj.xn--3xa; ; ; # ⴚ.ς
+Ⴚ.σ; ; [P1, V6]; xn--ynd.xn--4xa; ; ; # Ⴚ.σ
+xn--0ug262c.xn--4xa; ‌ⴚ.σ; [C1]; xn--0ug262c.xn--4xa; ; ; # ⴚ.σ
+xn--ynd759e.xn--4xa; ‌Ⴚ.σ; [C1, V6]; xn--ynd759e.xn--4xa; ; ; # Ⴚ.σ
+xn--0ug262c.xn--3xa; ‌ⴚ.ς; [C1]; xn--0ug262c.xn--3xa; ; ; # ⴚ.ς
+xn--ynd759e.xn--3xa; ‌Ⴚ.ς; [C1, V6]; xn--ynd759e.xn--3xa; ; ; # Ⴚ.ς
+‌ⴚ。ς; ‌ⴚ.ς; [C1]; xn--0ug262c.xn--3xa; ; xn--ilj.xn--4xa; [] # ⴚ.ς
+‌Ⴚ。Σ; ‌Ⴚ.σ; [C1, P1, V6]; xn--ynd759e.xn--4xa; ; xn--ynd.xn--4xa; [P1, V6] # Ⴚ.σ
+‌ⴚ。σ; ‌ⴚ.σ; [C1]; xn--0ug262c.xn--4xa; ; xn--ilj.xn--4xa; [] # ⴚ.σ
+𞤃.𐹦; 𞤥.𐹦; [B1]; xn--de6h.xn--eo0d; ; ; # 𞤥.𐹦
+𞤃.𐹦; 𞤥.𐹦; [B1]; xn--de6h.xn--eo0d; ; ; # 𞤥.𐹦
+𞤥.𐹦; ; [B1]; xn--de6h.xn--eo0d; ; ; # 𞤥.𐹦
+xn--de6h.xn--eo0d; 𞤥.𐹦; [B1]; xn--de6h.xn--eo0d; ; ; # 𞤥.𐹦
+𞤥.𐹦; 𞤥.𐹦; [B1]; xn--de6h.xn--eo0d; ; ; # 𞤥.𐹦
+‍⾕。‌꥓̐ꡎ; ‍谷.‌꥓̐ꡎ; [C1, C2]; xn--1ug0273b.xn--0sa359l6n7g13a; ; xn--6g3a.xn--0sa8175flwa; [V5] # 谷.꥓̐ꡎ
+‍⾕。‌꥓̐ꡎ; ‍谷.‌꥓̐ꡎ; [C1, C2]; xn--1ug0273b.xn--0sa359l6n7g13a; ; xn--6g3a.xn--0sa8175flwa; [V5] # 谷.꥓̐ꡎ
+‍谷。‌꥓̐ꡎ; ‍谷.‌꥓̐ꡎ; [C1, C2]; xn--1ug0273b.xn--0sa359l6n7g13a; ; xn--6g3a.xn--0sa8175flwa; [V5] # 谷.꥓̐ꡎ
+xn--6g3a.xn--0sa8175flwa; 谷.꥓̐ꡎ; [V5]; xn--6g3a.xn--0sa8175flwa; ; ; # 谷.꥓̐ꡎ
+xn--1ug0273b.xn--0sa359l6n7g13a; ‍谷.‌꥓̐ꡎ; [C1, C2]; xn--1ug0273b.xn--0sa359l6n7g13a; ; ; # 谷.꥓̐ꡎ
+ڪ-뉔.𞤐‌; ڪ-뉔.𞤲‌; [B2, B3, C1]; xn----guc3592k.xn--0ug7611p; ; xn----guc3592k.xn--qe6h; [B2, B3] # ڪ-뉔.𞤲
+ڪ-뉔.𞤐‌; ڪ-뉔.𞤲‌; [B2, B3, C1]; xn----guc3592k.xn--0ug7611p; ; xn----guc3592k.xn--qe6h; [B2, B3] # ڪ-뉔.𞤲
+ڪ-뉔.𞤐‌; ڪ-뉔.𞤲‌; [B2, B3, C1]; xn----guc3592k.xn--0ug7611p; ; xn----guc3592k.xn--qe6h; [B2, B3] # ڪ-뉔.𞤲
+ڪ-뉔.𞤐‌; ڪ-뉔.𞤲‌; [B2, B3, C1]; xn----guc3592k.xn--0ug7611p; ; xn----guc3592k.xn--qe6h; [B2, B3] # ڪ-뉔.𞤲
+ڪ-뉔.𞤲‌; ڪ-뉔.𞤲‌; [B2, B3, C1]; xn----guc3592k.xn--0ug7611p; ; xn----guc3592k.xn--qe6h; [B2, B3] # ڪ-뉔.𞤲
+ڪ-뉔.𞤲‌; ; [B2, B3, C1]; xn----guc3592k.xn--0ug7611p; ; xn----guc3592k.xn--qe6h; [B2, B3] # ڪ-뉔.𞤲
+xn----guc3592k.xn--qe6h; ڪ-뉔.𞤲; [B2, B3]; xn----guc3592k.xn--qe6h; ; ; # ڪ-뉔.𞤲
+xn----guc3592k.xn--0ug7611p; ڪ-뉔.𞤲‌; [B2, B3, C1]; xn----guc3592k.xn--0ug7611p; ; ; # ڪ-뉔.𞤲
+ڪ-뉔.𞤲‌; ڪ-뉔.𞤲‌; [B2, B3, C1]; xn----guc3592k.xn--0ug7611p; ; xn----guc3592k.xn--qe6h; [B2, B3] # ڪ-뉔.𞤲
+ڪ-뉔.𞤲‌; ڪ-뉔.𞤲‌; [B2, B3, C1]; xn----guc3592k.xn--0ug7611p; ; xn----guc3592k.xn--qe6h; [B2, B3] # ڪ-뉔.𞤲
+񔲵5ᦛς.꣄ݻܸ᳒; 񔲵5ᦛς.꣄ݻܸ᳒; [B1, P1, V5, V6]; xn--5-ymb298ng603j.xn--fob7kk44dl41k; ; xn--5-0mb988ng603j.xn--fob7kk44dl41k; # 5ᦛς.꣄ݻܸ᳒
+񔲵5ᦛς.꣄ݻܸ᳒; 񔲵5ᦛς.꣄ݻܸ᳒; [B1, P1, V5, V6]; xn--5-ymb298ng603j.xn--fob7kk44dl41k; ; xn--5-0mb988ng603j.xn--fob7kk44dl41k; # 5ᦛς.꣄ݻܸ᳒
+񔲵5ᦛς.꣄ݻܸ᳒; ; [B1, P1, V5, V6]; xn--5-ymb298ng603j.xn--fob7kk44dl41k; ; xn--5-0mb988ng603j.xn--fob7kk44dl41k; # 5ᦛς.꣄ݻܸ᳒
+񔲵5ᦛΣ.꣄ݻܸ᳒; 񔲵5ᦛσ.꣄ݻܸ᳒; [B1, P1, V5, V6]; xn--5-0mb988ng603j.xn--fob7kk44dl41k; ; ; # 5ᦛσ.꣄ݻܸ᳒
+񔲵5ᦛσ.꣄ݻܸ᳒; ; [B1, P1, V5, V6]; xn--5-0mb988ng603j.xn--fob7kk44dl41k; ; ; # 5ᦛσ.꣄ݻܸ᳒
+xn--5-0mb988ng603j.xn--fob7kk44dl41k; 񔲵5ᦛσ.꣄ݻܸ᳒; [B1, V5, V6]; xn--5-0mb988ng603j.xn--fob7kk44dl41k; ; ; # 5ᦛσ.꣄ݻܸ᳒
+xn--5-ymb298ng603j.xn--fob7kk44dl41k; 񔲵5ᦛς.꣄ݻܸ᳒; [B1, V5, V6]; xn--5-ymb298ng603j.xn--fob7kk44dl41k; ; ; # 5ᦛς.꣄ݻܸ᳒
+񔲵5ᦛΣ.꣄ݻܸ᳒; 񔲵5ᦛσ.꣄ݻܸ᳒; [B1, P1, V5, V6]; xn--5-0mb988ng603j.xn--fob7kk44dl41k; ; ; # 5ᦛσ.꣄ݻܸ᳒
+񔲵5ᦛσ.꣄ݻܸ᳒; 񔲵5ᦛσ.꣄ݻܸ᳒; [B1, P1, V5, V6]; xn--5-0mb988ng603j.xn--fob7kk44dl41k; ; ; # 5ᦛσ.꣄ݻܸ᳒
+񔲵5ᦛΣ.꣄ݻܸ᳒; 񔲵5ᦛσ.꣄ݻܸ᳒; [B1, P1, V5, V6]; xn--5-0mb988ng603j.xn--fob7kk44dl41k; ; ; # 5ᦛσ.꣄ݻܸ᳒
+񔲵5ᦛσ.꣄ݻܸ᳒; 񔲵5ᦛσ.꣄ݻܸ᳒; [B1, P1, V5, V6]; xn--5-0mb988ng603j.xn--fob7kk44dl41k; ; ; # 5ᦛσ.꣄ݻܸ᳒
+淽。ᠾ; 淽.ᠾ; ; xn--34w.xn--x7e; ; ; # 淽.ᠾ
+xn--34w.xn--x7e; 淽.ᠾ; ; xn--34w.xn--x7e; ; ; # 淽.ᠾ
+淽.ᠾ; ; ; xn--34w.xn--x7e; ; ; # 淽.ᠾ
+𐹴𑘷。-; 𐹴𑘷.-; [B1, V3]; xn--so0do6k.-; ; ; # 𐹴𑘷.-
+xn--so0do6k.-; 𐹴𑘷.-; [B1, V3]; xn--so0do6k.-; ; ; # 𐹴𑘷.-
+򬨩Ⴓ❓。𑄨; 򬨩Ⴓ❓.𑄨; [P1, V5, V6]; xn--rnd896i0j14q.xn--k80d; ; ; # Ⴓ❓.𑄨
+򬨩Ⴓ❓。𑄨; 򬨩Ⴓ❓.𑄨; [P1, V5, V6]; xn--rnd896i0j14q.xn--k80d; ; ; # Ⴓ❓.𑄨
+򬨩ⴓ❓。𑄨; 򬨩ⴓ❓.𑄨; [P1, V5, V6]; xn--8di78qvw32y.xn--k80d; ; ; # ⴓ❓.𑄨
+xn--8di78qvw32y.xn--k80d; 򬨩ⴓ❓.𑄨; [V5, V6]; xn--8di78qvw32y.xn--k80d; ; ; # ⴓ❓.𑄨
+xn--rnd896i0j14q.xn--k80d; 򬨩Ⴓ❓.𑄨; [V5, V6]; xn--rnd896i0j14q.xn--k80d; ; ; # Ⴓ❓.𑄨
+򬨩ⴓ❓。𑄨; 򬨩ⴓ❓.𑄨; [P1, V5, V6]; xn--8di78qvw32y.xn--k80d; ; ; # ⴓ❓.𑄨
+‌𐹡𞤌Ⴇ。ßႣ; ‌𐹡𞤮Ⴇ.ßႣ; [B1, C1, P1, V6]; xn--fnd599eyj4pr50g.xn--zca681f; ; xn--fnd1201kegrf.xn--ss-fek; [B1, P1, V6] # 𐹡𞤮Ⴇ.ßႣ
+‌𐹡𞤌Ⴇ。ßႣ; ‌𐹡𞤮Ⴇ.ßႣ; [B1, C1, P1, V6]; xn--fnd599eyj4pr50g.xn--zca681f; ; xn--fnd1201kegrf.xn--ss-fek; [B1, P1, V6] # 𐹡𞤮Ⴇ.ßႣ
+‌𐹡𞤮ⴇ。ßⴃ; ‌𐹡𞤮ⴇ.ßⴃ; [B1, C1]; xn--0ug332c3q0pr56g.xn--zca417t; ; xn--ykj9323eegwf.xn--ss-151a; [B1] # 𐹡𞤮ⴇ.ßⴃ
+‌𐹡𞤌Ⴇ。SSႣ; ‌𐹡𞤮Ⴇ.ssႣ; [B1, C1, P1, V6]; xn--fnd599eyj4pr50g.xn--ss-fek; ; xn--fnd1201kegrf.xn--ss-fek; [B1, P1, V6] # 𐹡𞤮Ⴇ.ssႣ
+‌𐹡𞤮ⴇ。ssⴃ; ‌𐹡𞤮ⴇ.ssⴃ; [B1, C1]; xn--0ug332c3q0pr56g.xn--ss-151a; ; xn--ykj9323eegwf.xn--ss-151a; [B1] # 𐹡𞤮ⴇ.ssⴃ
+‌𐹡𞤌ⴇ。Ssⴃ; ‌𐹡𞤮ⴇ.ssⴃ; [B1, C1]; xn--0ug332c3q0pr56g.xn--ss-151a; ; xn--ykj9323eegwf.xn--ss-151a; [B1] # 𐹡𞤮ⴇ.ssⴃ
+xn--ykj9323eegwf.xn--ss-151a; 𐹡𞤮ⴇ.ssⴃ; [B1]; xn--ykj9323eegwf.xn--ss-151a; ; ; # 𐹡𞤮ⴇ.ssⴃ
+xn--0ug332c3q0pr56g.xn--ss-151a; ‌𐹡𞤮ⴇ.ssⴃ; [B1, C1]; xn--0ug332c3q0pr56g.xn--ss-151a; ; ; # 𐹡𞤮ⴇ.ssⴃ
+xn--fnd1201kegrf.xn--ss-fek; 𐹡𞤮Ⴇ.ssႣ; [B1, V6]; xn--fnd1201kegrf.xn--ss-fek; ; ; # 𐹡𞤮Ⴇ.ssႣ
+xn--fnd599eyj4pr50g.xn--ss-fek; ‌𐹡𞤮Ⴇ.ssႣ; [B1, C1, V6]; xn--fnd599eyj4pr50g.xn--ss-fek; ; ; # 𐹡𞤮Ⴇ.ssႣ
+xn--0ug332c3q0pr56g.xn--zca417t; ‌𐹡𞤮ⴇ.ßⴃ; [B1, C1]; xn--0ug332c3q0pr56g.xn--zca417t; ; ; # 𐹡𞤮ⴇ.ßⴃ
+xn--fnd599eyj4pr50g.xn--zca681f; ‌𐹡𞤮Ⴇ.ßႣ; [B1, C1, V6]; xn--fnd599eyj4pr50g.xn--zca681f; ; ; # 𐹡𞤮Ⴇ.ßႣ
+‌𐹡𞤮ⴇ。ßⴃ; ‌𐹡𞤮ⴇ.ßⴃ; [B1, C1]; xn--0ug332c3q0pr56g.xn--zca417t; ; xn--ykj9323eegwf.xn--ss-151a; [B1] # 𐹡𞤮ⴇ.ßⴃ
+‌𐹡𞤌Ⴇ。SSႣ; ‌𐹡𞤮Ⴇ.ssႣ; [B1, C1, P1, V6]; xn--fnd599eyj4pr50g.xn--ss-fek; ; xn--fnd1201kegrf.xn--ss-fek; [B1, P1, V6] # 𐹡𞤮Ⴇ.ssႣ
+‌𐹡𞤮ⴇ。ssⴃ; ‌𐹡𞤮ⴇ.ssⴃ; [B1, C1]; xn--0ug332c3q0pr56g.xn--ss-151a; ; xn--ykj9323eegwf.xn--ss-151a; [B1] # 𐹡𞤮ⴇ.ssⴃ
+‌𐹡𞤌ⴇ。Ssⴃ; ‌𐹡𞤮ⴇ.ssⴃ; [B1, C1]; xn--0ug332c3q0pr56g.xn--ss-151a; ; xn--ykj9323eegwf.xn--ss-151a; [B1] # 𐹡𞤮ⴇ.ssⴃ
+‌𐹡𞤌ⴇ。ßⴃ; ‌𐹡𞤮ⴇ.ßⴃ; [B1, C1]; xn--0ug332c3q0pr56g.xn--zca417t; ; xn--ykj9323eegwf.xn--ss-151a; [B1] # 𐹡𞤮ⴇ.ßⴃ
+‌𐹡𞤌ⴇ。ssⴃ; ‌𐹡𞤮ⴇ.ssⴃ; [B1, C1]; xn--0ug332c3q0pr56g.xn--ss-151a; ; xn--ykj9323eegwf.xn--ss-151a; [B1] # 𐹡𞤮ⴇ.ssⴃ
+‌𐹡𞤌Ⴇ。Ssⴃ; ‌𐹡𞤮Ⴇ.ssⴃ; [B1, C1, P1, V6]; xn--fnd599eyj4pr50g.xn--ss-151a; ; xn--fnd1201kegrf.xn--ss-151a; [B1, P1, V6] # 𐹡𞤮Ⴇ.ssⴃ
+xn--fnd1201kegrf.xn--ss-151a; 𐹡𞤮Ⴇ.ssⴃ; [B1, V6]; xn--fnd1201kegrf.xn--ss-151a; ; ; # 𐹡𞤮Ⴇ.ssⴃ
+xn--fnd599eyj4pr50g.xn--ss-151a; ‌𐹡𞤮Ⴇ.ssⴃ; [B1, C1, V6]; xn--fnd599eyj4pr50g.xn--ss-151a; ; ; # 𐹡𞤮Ⴇ.ssⴃ
+‌𐹡𞤌ⴇ。ßⴃ; ‌𐹡𞤮ⴇ.ßⴃ; [B1, C1]; xn--0ug332c3q0pr56g.xn--zca417t; ; xn--ykj9323eegwf.xn--ss-151a; [B1] # 𐹡𞤮ⴇ.ßⴃ
+‌𐹡𞤌ⴇ。ssⴃ; ‌𐹡𞤮ⴇ.ssⴃ; [B1, C1]; xn--0ug332c3q0pr56g.xn--ss-151a; ; xn--ykj9323eegwf.xn--ss-151a; [B1] # 𐹡𞤮ⴇ.ssⴃ
+‌𐹡𞤌Ⴇ。Ssⴃ; ‌𐹡𞤮Ⴇ.ssⴃ; [B1, C1, P1, V6]; xn--fnd599eyj4pr50g.xn--ss-151a; ; xn--fnd1201kegrf.xn--ss-151a; [B1, P1, V6] # 𐹡𞤮Ⴇ.ssⴃ
+៿。𞬳; ៿.𞬳; [P1, V6]; xn--45e.xn--et6h; ; ; # .
+៿。𞬳; ៿.𞬳; [P1, V6]; xn--45e.xn--et6h; ; ; # .
+xn--45e.xn--et6h; ៿.𞬳; [V6]; xn--45e.xn--et6h; ; ; # .
+ْ‍。್𑚳; ْ‍.್𑚳; [C2, V5]; xn--uhb882k.xn--8tc4527k; ; xn--uhb.xn--8tc4527k; [V5] # ْ.್𑚳
+ْ‍。್𑚳; ْ‍.್𑚳; [C2, V5]; xn--uhb882k.xn--8tc4527k; ; xn--uhb.xn--8tc4527k; [V5] # ْ.್𑚳
+xn--uhb.xn--8tc4527k; ْ.್𑚳; [V5]; xn--uhb.xn--8tc4527k; ; ; # ْ.್𑚳
+xn--uhb882k.xn--8tc4527k; ْ‍.್𑚳; [C2, V5]; xn--uhb882k.xn--8tc4527k; ; ; # ْ.್𑚳
+-≠ᠻ.ݭ𞥃≮󟷺; -≠ᠻ.ݭ𞥃≮󟷺; [B1, B2, B3, P1, V3, V6]; xn----g6j886c.xn--xpb049kk353abj99f; ; ; # -≠ᠻ.ݭ𞥃≮
+-≠ᠻ.ݭ𞥃≮󟷺; -≠ᠻ.ݭ𞥃≮󟷺; [B1, B2, B3, P1, V3, V6]; xn----g6j886c.xn--xpb049kk353abj99f; ; ; # -≠ᠻ.ݭ𞥃≮
+-≠ᠻ.ݭ𞥃≮󟷺; ; [B1, B2, B3, P1, V3, V6]; xn----g6j886c.xn--xpb049kk353abj99f; ; ; # -≠ᠻ.ݭ𞥃≮
+-≠ᠻ.ݭ𞥃≮󟷺; -≠ᠻ.ݭ𞥃≮󟷺; [B1, B2, B3, P1, V3, V6]; xn----g6j886c.xn--xpb049kk353abj99f; ; ; # -≠ᠻ.ݭ𞥃≮
+-≠ᠻ.ݭ𞤡≮󟷺; -≠ᠻ.ݭ𞥃≮󟷺; [B1, B2, B3, P1, V3, V6]; xn----g6j886c.xn--xpb049kk353abj99f; ; ; # -≠ᠻ.ݭ𞥃≮
+-≠ᠻ.ݭ𞤡≮󟷺; -≠ᠻ.ݭ𞥃≮󟷺; [B1, B2, B3, P1, V3, V6]; xn----g6j886c.xn--xpb049kk353abj99f; ; ; # -≠ᠻ.ݭ𞥃≮
+xn----g6j886c.xn--xpb049kk353abj99f; -≠ᠻ.ݭ𞥃≮󟷺; [B1, B2, B3, V3, V6]; xn----g6j886c.xn--xpb049kk353abj99f; ; ; # -≠ᠻ.ݭ𞥃≮
+-≠ᠻ.ݭ𞤡≮󟷺; -≠ᠻ.ݭ𞥃≮󟷺; [B1, B2, B3, P1, V3, V6]; xn----g6j886c.xn--xpb049kk353abj99f; ; ; # -≠ᠻ.ݭ𞥃≮
+-≠ᠻ.ݭ𞤡≮󟷺; -≠ᠻ.ݭ𞥃≮󟷺; [B1, B2, B3, P1, V3, V6]; xn----g6j886c.xn--xpb049kk353abj99f; ; ; # -≠ᠻ.ݭ𞥃≮
+󠰆≯޵𐻪.򊥕≮𑁆ࡌ; 󠰆≯޵𐻪.򊥕≮𑁆ࡌ; [B1, B5, B6, P1, V6]; xn--zrb797kdm1oes34i.xn--bwb394k8k2o25n6d; ; ; # ≯.≮𑁆ࡌ
+󠰆≯޵𐻪.򊥕≮𑁆ࡌ; 󠰆≯޵𐻪.򊥕≮𑁆ࡌ; [B1, B5, B6, P1, V6]; xn--zrb797kdm1oes34i.xn--bwb394k8k2o25n6d; ; ; # ≯.≮𑁆ࡌ
+󠰆≯޵𐻪.򊥕≮𑁆ࡌ; ; [B1, B5, B6, P1, V6]; xn--zrb797kdm1oes34i.xn--bwb394k8k2o25n6d; ; ; # ≯.≮𑁆ࡌ
+󠰆≯޵𐻪.򊥕≮𑁆ࡌ; 󠰆≯޵𐻪.򊥕≮𑁆ࡌ; [B1, B5, B6, P1, V6]; xn--zrb797kdm1oes34i.xn--bwb394k8k2o25n6d; ; ; # ≯.≮𑁆ࡌ
+xn--zrb797kdm1oes34i.xn--bwb394k8k2o25n6d; 󠰆≯޵𐻪.򊥕≮𑁆ࡌ; [B1, B5, B6, V6]; xn--zrb797kdm1oes34i.xn--bwb394k8k2o25n6d; ; ; # ≯.≮𑁆ࡌ
+≠󦋂.؀்-ڹ; ; [B1, P1, V6]; xn--1ch22084l.xn----qkc07co6n; ; ; # ≠.்-ڹ
+≠󦋂.؀்-ڹ; ≠󦋂.؀்-ڹ; [B1, P1, V6]; xn--1ch22084l.xn----qkc07co6n; ; ; # ≠.்-ڹ
+xn--1ch22084l.xn----qkc07co6n; ≠󦋂.؀்-ڹ; [B1, V6]; xn--1ch22084l.xn----qkc07co6n; ; ; # ≠.்-ڹ
+៝󠁣≠。𐹼𐋤; ៝󠁣≠.𐹼𐋤; [B1, P1, V5, V6]; xn--54e694cn389z.xn--787ct8r; ; ; # ៝≠.𐹼𐋤
+៝󠁣≠。𐹼𐋤; ៝󠁣≠.𐹼𐋤; [B1, P1, V5, V6]; xn--54e694cn389z.xn--787ct8r; ; ; # ៝≠.𐹼𐋤
+៝󠁣≠。𐹼𐋤; ៝󠁣≠.𐹼𐋤; [B1, P1, V5, V6]; xn--54e694cn389z.xn--787ct8r; ; ; # ៝≠.𐹼𐋤
+៝󠁣≠。𐹼𐋤; ៝󠁣≠.𐹼𐋤; [B1, P1, V5, V6]; xn--54e694cn389z.xn--787ct8r; ; ; # ៝≠.𐹼𐋤
+xn--54e694cn389z.xn--787ct8r; ៝󠁣≠.𐹼𐋤; [B1, V5, V6]; xn--54e694cn389z.xn--787ct8r; ; ; # ៝≠.𐹼𐋤
+ß𰀻񆬗。𝩨🕮ß; ß𰀻񆬗.𝩨🕮ß; [P1, V5, V6]; xn--zca20040bgrkh.xn--zca3653v86qa; ; xn--ss-jl59biy67d.xn--ss-4d11aw87d; # ß𰀻.𝩨🕮ß
+ß𰀻񆬗。𝩨🕮ß; ß𰀻񆬗.𝩨🕮ß; [P1, V5, V6]; xn--zca20040bgrkh.xn--zca3653v86qa; ; xn--ss-jl59biy67d.xn--ss-4d11aw87d; # ß𰀻.𝩨🕮ß
+SS𰀻񆬗。𝩨🕮SS; ss𰀻񆬗.𝩨🕮ss; [P1, V5, V6]; xn--ss-jl59biy67d.xn--ss-4d11aw87d; ; ; # ss𰀻.𝩨🕮ss
+ss𰀻񆬗。𝩨🕮ss; ss𰀻񆬗.𝩨🕮ss; [P1, V5, V6]; xn--ss-jl59biy67d.xn--ss-4d11aw87d; ; ; # ss𰀻.𝩨🕮ss
+Ss𰀻񆬗。𝩨🕮Ss; ss𰀻񆬗.𝩨🕮ss; [P1, V5, V6]; xn--ss-jl59biy67d.xn--ss-4d11aw87d; ; ; # ss𰀻.𝩨🕮ss
+xn--ss-jl59biy67d.xn--ss-4d11aw87d; ss𰀻񆬗.𝩨🕮ss; [V5, V6]; xn--ss-jl59biy67d.xn--ss-4d11aw87d; ; ; # ss𰀻.𝩨🕮ss
+xn--zca20040bgrkh.xn--zca3653v86qa; ß𰀻񆬗.𝩨🕮ß; [V5, V6]; xn--zca20040bgrkh.xn--zca3653v86qa; ; ; # ß𰀻.𝩨🕮ß
+SS𰀻񆬗。𝩨🕮SS; ss𰀻񆬗.𝩨🕮ss; [P1, V5, V6]; xn--ss-jl59biy67d.xn--ss-4d11aw87d; ; ; # ss𰀻.𝩨🕮ss
+ss𰀻񆬗。𝩨🕮ss; ss𰀻񆬗.𝩨🕮ss; [P1, V5, V6]; xn--ss-jl59biy67d.xn--ss-4d11aw87d; ; ; # ss𰀻.𝩨🕮ss
+Ss𰀻񆬗。𝩨🕮Ss; ss𰀻񆬗.𝩨🕮ss; [P1, V5, V6]; xn--ss-jl59biy67d.xn--ss-4d11aw87d; ; ; # ss𰀻.𝩨🕮ss
+‍。‌; ‍.‌; [C1, C2]; xn--1ug.xn--0ug; ; .; [A4_2] # .
+xn--1ug.xn--0ug; ‍.‌; [C1, C2]; xn--1ug.xn--0ug; ; ; # .
+҃𐭞‍.ឹ𞯌򟩚; ; [B1, C2, P1, V5, V6]; xn--m3a412lrr0o.xn--43e8670vmd79b; ; xn--m3a6965k.xn--43e8670vmd79b; [B1, P1, V5, V6] # ҃𐭞.ឹ
+xn--m3a6965k.xn--43e8670vmd79b; ҃𐭞.ឹ𞯌򟩚; [B1, V5, V6]; xn--m3a6965k.xn--43e8670vmd79b; ; ; # ҃𐭞.ឹ
+xn--m3a412lrr0o.xn--43e8670vmd79b; ҃𐭞‍.ឹ𞯌򟩚; [B1, C2, V5, V6]; xn--m3a412lrr0o.xn--43e8670vmd79b; ; ; # ҃𐭞.ឹ
+‌𐠨‌临。ꡢ򄷞ⶏ𐹣; ‌𐠨‌临.ꡢ򄷞ⶏ𐹣; [B1, B5, B6, C1, P1, V6]; xn--0uga2656aop9k.xn--uojv340bk71c99u9f; ; xn--miq9646b.xn--uojv340bk71c99u9f; [B2, B3, B5, B6, P1, V6] # 𐠨临.ꡢⶏ𐹣
+xn--miq9646b.xn--uojv340bk71c99u9f; 𐠨临.ꡢ򄷞ⶏ𐹣; [B2, B3, B5, B6, V6]; xn--miq9646b.xn--uojv340bk71c99u9f; ; ; # 𐠨临.ꡢⶏ𐹣
+xn--0uga2656aop9k.xn--uojv340bk71c99u9f; ‌𐠨‌临.ꡢ򄷞ⶏ𐹣; [B1, B5, B6, C1, V6]; xn--0uga2656aop9k.xn--uojv340bk71c99u9f; ; ; # 𐠨临.ꡢⶏ𐹣
+󠑘.󠄮; 󠑘.; [P1, V6]; xn--s136e.; ; ; # .
+󠑘.󠄮; 󠑘.; [P1, V6]; xn--s136e.; ; ; # .
+xn--s136e.; 󠑘.; [V6]; xn--s136e.; ; ; # .
+𐫄്.꫶; 𐫄്.꫶; [B1, B3, B6, V5]; xn--wxc7880k.xn--2v9a; ; ; # 𐫄്.꫶
+𐫄്.꫶; ; [B1, B3, B6, V5]; xn--wxc7880k.xn--2v9a; ; ; # 𐫄്.꫶
+xn--wxc7880k.xn--2v9a; 𐫄്.꫶; [B1, B3, B6, V5]; xn--wxc7880k.xn--2v9a; ; ; # 𐫄്.꫶
+ꦷ󝵙멹。⒛󠨇; ꦷ󝵙멹.⒛󠨇; [P1, V5, V6]; xn--ym9av13acp85w.xn--dth22121k; ; ; # ꦷ멹.⒛
+ꦷ󝵙멹。⒛󠨇; ꦷ󝵙멹.⒛󠨇; [P1, V5, V6]; xn--ym9av13acp85w.xn--dth22121k; ; ; # ꦷ멹.⒛
+ꦷ󝵙멹。20.󠨇; ꦷ󝵙멹.20.󠨇; [P1, V5, V6]; xn--ym9av13acp85w.20.xn--d846e; ; ; # ꦷ멹.20.
+ꦷ󝵙멹。20.󠨇; ꦷ󝵙멹.20.󠨇; [P1, V5, V6]; xn--ym9av13acp85w.20.xn--d846e; ; ; # ꦷ멹.20.
+xn--ym9av13acp85w.20.xn--d846e; ꦷ󝵙멹.20.󠨇; [V5, V6]; xn--ym9av13acp85w.20.xn--d846e; ; ; # ꦷ멹.20.
+xn--ym9av13acp85w.xn--dth22121k; ꦷ󝵙멹.⒛󠨇; [V5, V6]; xn--ym9av13acp85w.xn--dth22121k; ; ; # ꦷ멹.⒛
+Ⴅ󲬹릖󠶚.ݷ𐹳⒊; ; [B4, B6, P1, V6]; xn--dnd2167fnet0io02g.xn--7pb000mwm4n; ; ; # Ⴅ릖.ݷ𐹳⒊
+Ⴅ󲬹릖󠶚.ݷ𐹳⒊; Ⴅ󲬹릖󠶚.ݷ𐹳⒊; [B4, B6, P1, V6]; xn--dnd2167fnet0io02g.xn--7pb000mwm4n; ; ; # Ⴅ릖.ݷ𐹳⒊
+Ⴅ󲬹릖󠶚.ݷ𐹳3.; ; [B4, B6, P1, V6]; xn--dnd2167fnet0io02g.xn--3-55c6803r.; ; ; # Ⴅ릖.ݷ𐹳3.
+Ⴅ󲬹릖󠶚.ݷ𐹳3.; Ⴅ󲬹릖󠶚.ݷ𐹳3.; [B4, B6, P1, V6]; xn--dnd2167fnet0io02g.xn--3-55c6803r.; ; ; # Ⴅ릖.ݷ𐹳3.
+ⴅ󲬹릖󠶚.ݷ𐹳3.; ⴅ󲬹릖󠶚.ݷ𐹳3.; [B4, B6, P1, V6]; xn--wkj8016bne45io02g.xn--3-55c6803r.; ; ; # ⴅ릖.ݷ𐹳3.
+ⴅ󲬹릖󠶚.ݷ𐹳3.; ; [B4, B6, P1, V6]; xn--wkj8016bne45io02g.xn--3-55c6803r.; ; ; # ⴅ릖.ݷ𐹳3.
+xn--wkj8016bne45io02g.xn--3-55c6803r.; ⴅ󲬹릖󠶚.ݷ𐹳3.; [B4, B6, V6]; xn--wkj8016bne45io02g.xn--3-55c6803r.; ; ; # ⴅ릖.ݷ𐹳3.
+xn--dnd2167fnet0io02g.xn--3-55c6803r.; Ⴅ󲬹릖󠶚.ݷ𐹳3.; [B4, B6, V6]; xn--dnd2167fnet0io02g.xn--3-55c6803r.; ; ; # Ⴅ릖.ݷ𐹳3.
+ⴅ󲬹릖󠶚.ݷ𐹳⒊; ⴅ󲬹릖󠶚.ݷ𐹳⒊; [B4, B6, P1, V6]; xn--wkj8016bne45io02g.xn--7pb000mwm4n; ; ; # ⴅ릖.ݷ𐹳⒊
+ⴅ󲬹릖󠶚.ݷ𐹳⒊; ; [B4, B6, P1, V6]; xn--wkj8016bne45io02g.xn--7pb000mwm4n; ; ; # ⴅ릖.ݷ𐹳⒊
+xn--wkj8016bne45io02g.xn--7pb000mwm4n; ⴅ󲬹릖󠶚.ݷ𐹳⒊; [B4, B6, V6]; xn--wkj8016bne45io02g.xn--7pb000mwm4n; ; ; # ⴅ릖.ݷ𐹳⒊
+xn--dnd2167fnet0io02g.xn--7pb000mwm4n; Ⴅ󲬹릖󠶚.ݷ𐹳⒊; [B4, B6, V6]; xn--dnd2167fnet0io02g.xn--7pb000mwm4n; ; ; # Ⴅ릖.ݷ𐹳⒊
+‌。︒; ‌.︒; [C1, P1, V6]; xn--0ug.xn--y86c; ; .xn--y86c; [P1, V6, A4_2] # .︒
+‌。。; ‌..; [C1, X4_2]; xn--0ug..; [C1, A4_2]; ..; [A4_2] # ..
+..; ; [X4_2]; ; [A4_2]; ; # ..
+xn--0ug..; ‌..; [C1, X4_2]; xn--0ug..; [C1, A4_2]; ; # ..
+.xn--y86c; .︒; [V6, X4_2]; .xn--y86c; [V6, A4_2]; ; # .︒
+xn--0ug.xn--y86c; ‌.︒; [C1, V6]; xn--0ug.xn--y86c; ; ; # .︒
+≯ݭ.₄; ≯ݭ.4; [B1, P1, V6]; xn--xpb149k.4; ; ; # ≯ݭ.4
+≯ݭ.₄; ≯ݭ.4; [B1, P1, V6]; xn--xpb149k.4; ; ; # ≯ݭ.4
+≯ݭ.4; ; [B1, P1, V6]; xn--xpb149k.4; ; ; # ≯ݭ.4
+≯ݭ.4; ≯ݭ.4; [B1, P1, V6]; xn--xpb149k.4; ; ; # ≯ݭ.4
+xn--xpb149k.4; ≯ݭ.4; [B1, V6]; xn--xpb149k.4; ; ; # ≯ݭ.4
+ᡲ-𝟹.ß-‌-; ᡲ-3.ß-‌-; [C1, V3]; xn---3-p9o.xn-----fia9303a; ; xn---3-p9o.ss--; [V2, V3] # ᡲ-3.ß--
+ᡲ-3.ß-‌-; ; [C1, V3]; xn---3-p9o.xn-----fia9303a; ; xn---3-p9o.ss--; [V2, V3] # ᡲ-3.ß--
+ᡲ-3.SS-‌-; ᡲ-3.ss-‌-; [C1, V3]; xn---3-p9o.xn--ss---276a; ; xn---3-p9o.ss--; [V2, V3] # ᡲ-3.ss--
+ᡲ-3.ss-‌-; ; [C1, V3]; xn---3-p9o.xn--ss---276a; ; xn---3-p9o.ss--; [V2, V3] # ᡲ-3.ss--
+ᡲ-3.Ss-‌-; ᡲ-3.ss-‌-; [C1, V3]; xn---3-p9o.xn--ss---276a; ; xn---3-p9o.ss--; [V2, V3] # ᡲ-3.ss--
+xn---3-p9o.ss--; ᡲ-3.ss--; [V2, V3]; xn---3-p9o.ss--; ; ; # ᡲ-3.ss--
+xn---3-p9o.xn--ss---276a; ᡲ-3.ss-‌-; [C1, V3]; xn---3-p9o.xn--ss---276a; ; ; # ᡲ-3.ss--
+xn---3-p9o.xn-----fia9303a; ᡲ-3.ß-‌-; [C1, V3]; xn---3-p9o.xn-----fia9303a; ; ; # ᡲ-3.ß--
+ᡲ-𝟹.SS-‌-; ᡲ-3.ss-‌-; [C1, V3]; xn---3-p9o.xn--ss---276a; ; xn---3-p9o.ss--; [V2, V3] # ᡲ-3.ss--
+ᡲ-𝟹.ss-‌-; ᡲ-3.ss-‌-; [C1, V3]; xn---3-p9o.xn--ss---276a; ; xn---3-p9o.ss--; [V2, V3] # ᡲ-3.ss--
+ᡲ-𝟹.Ss-‌-; ᡲ-3.ss-‌-; [C1, V3]; xn---3-p9o.xn--ss---276a; ; xn---3-p9o.ss--; [V2, V3] # ᡲ-3.ss--
+ﴈ𝟦ه󎊯。Ӏ; ضي4ه󎊯.Ӏ; [B2, B3, P1, V6]; xn--4-tnc6ck183523b.xn--d5a; ; ; # ضي4ه.Ӏ
+ضي4ه󎊯。Ӏ; ضي4ه󎊯.Ӏ; [B2, B3, P1, V6]; xn--4-tnc6ck183523b.xn--d5a; ; ; # ضي4ه.Ӏ
+ضي4ه󎊯。ӏ; ضي4ه󎊯.ӏ; [B2, B3, P1, V6]; xn--4-tnc6ck183523b.xn--s5a; ; ; # ضي4ه.ӏ
+xn--4-tnc6ck183523b.xn--s5a; ضي4ه󎊯.ӏ; [B2, B3, V6]; xn--4-tnc6ck183523b.xn--s5a; ; ; # ضي4ه.ӏ
+xn--4-tnc6ck183523b.xn--d5a; ضي4ه󎊯.Ӏ; [B2, B3, V6]; xn--4-tnc6ck183523b.xn--d5a; ; ; # ضي4ه.Ӏ
+ﴈ𝟦ه󎊯。ӏ; ضي4ه󎊯.ӏ; [B2, B3, P1, V6]; xn--4-tnc6ck183523b.xn--s5a; ; ; # ضي4ه.ӏ
+-.؂آ𑆾🐹; ; [B1, P1, V3, V6]; -.xn--kfb8dy983hgl7g; ; ; # -.آ𑆾🐹
+-.؂آ𑆾🐹; -.؂آ𑆾🐹; [B1, P1, V3, V6]; -.xn--kfb8dy983hgl7g; ; ; # -.آ𑆾🐹
+-.xn--kfb8dy983hgl7g; -.؂آ𑆾🐹; [B1, V3, V6]; -.xn--kfb8dy983hgl7g; ; ; # -.آ𑆾🐹
+󙶜ᢘ。᩿⺢; 󙶜ᢘ.᩿⺢; [P1, V5, V6]; xn--ibf35138o.xn--fpfz94g; ; ; # ᢘ.᩿⺢
+xn--ibf35138o.xn--fpfz94g; 󙶜ᢘ.᩿⺢; [V5, V6]; xn--ibf35138o.xn--fpfz94g; ; ; # ᢘ.᩿⺢
+≠ႷᠤႫ。?͌س觴; ≠ႷᠤႫ.?͌س觴; [B1, P1, V6]; xn--jndx718cnnl.xn--?-7fb34t0u7s; ; ; # ≠ႷᠤႫ.?͌س觴
+≠ႷᠤႫ。?͌س觴; ≠ႷᠤႫ.?͌س觴; [B1, P1, V6]; xn--jndx718cnnl.xn--?-7fb34t0u7s; ; ; # ≠ႷᠤႫ.?͌س觴
+≠ႷᠤႫ。?͌س觴; ≠ႷᠤႫ.?͌س觴; [B1, P1, V6]; xn--jndx718cnnl.xn--?-7fb34t0u7s; ; ; # ≠ႷᠤႫ.?͌س觴
+≠ႷᠤႫ。?͌س觴; ≠ႷᠤႫ.?͌س觴; [B1, P1, V6]; xn--jndx718cnnl.xn--?-7fb34t0u7s; ; ; # ≠ႷᠤႫ.?͌س觴
+≠ⴗᠤⴋ。?͌س觴; ≠ⴗᠤⴋ.?͌س觴; [B1, P1, V6]; xn--66e353ce0ilb.xn--?-7fb34t0u7s; ; ; # ≠ⴗᠤⴋ.?͌س觴
+≠ⴗᠤⴋ。?͌س觴; ≠ⴗᠤⴋ.?͌س觴; [B1, P1, V6]; xn--66e353ce0ilb.xn--?-7fb34t0u7s; ; ; # ≠ⴗᠤⴋ.?͌س觴
+≠Ⴗᠤⴋ。?͌س觴; ≠Ⴗᠤⴋ.?͌س觴; [B1, P1, V6]; xn--vnd619as6ig6k.xn--?-7fb34t0u7s; ; ; # ≠Ⴗᠤⴋ.?͌س觴
+≠Ⴗᠤⴋ。?͌س觴; ≠Ⴗᠤⴋ.?͌س觴; [B1, P1, V6]; xn--vnd619as6ig6k.xn--?-7fb34t0u7s; ; ; # ≠Ⴗᠤⴋ.?͌س觴
+xn--vnd619as6ig6k.xn--?-7fb34t0u7s; ≠Ⴗᠤⴋ.?͌س觴; [B1, P1, V6]; xn--vnd619as6ig6k.xn--?-7fb34t0u7s; ; ; # ≠Ⴗᠤⴋ.?͌س觴
+xn--66e353ce0ilb.xn--?-7fb34t0u7s; ≠ⴗᠤⴋ.?͌س觴; [B1, P1, V6]; xn--66e353ce0ilb.xn--?-7fb34t0u7s; ; ; # ≠ⴗᠤⴋ.?͌س觴
+xn--jndx718cnnl.xn--?-7fb34t0u7s; ≠ႷᠤႫ.?͌س觴; [B1, P1, V6]; xn--jndx718cnnl.xn--?-7fb34t0u7s; ; ; # ≠ႷᠤႫ.?͌س觴
+≠ⴗᠤⴋ。?͌س觴; ≠ⴗᠤⴋ.?͌س觴; [B1, P1, V6]; xn--66e353ce0ilb.xn--?-7fb34t0u7s; ; ; # ≠ⴗᠤⴋ.?͌س觴
+≠ⴗᠤⴋ。?͌س觴; ≠ⴗᠤⴋ.?͌س觴; [B1, P1, V6]; xn--66e353ce0ilb.xn--?-7fb34t0u7s; ; ; # ≠ⴗᠤⴋ.?͌س觴
+≠Ⴗᠤⴋ。?͌س觴; ≠Ⴗᠤⴋ.?͌س觴; [B1, P1, V6]; xn--vnd619as6ig6k.xn--?-7fb34t0u7s; ; ; # ≠Ⴗᠤⴋ.?͌س觴
+≠Ⴗᠤⴋ。?͌س觴; ≠Ⴗᠤⴋ.?͌س觴; [B1, P1, V6]; xn--vnd619as6ig6k.xn--?-7fb34t0u7s; ; ; # ≠Ⴗᠤⴋ.?͌س觴
+xn--vnd619as6ig6k.?͌س觴; ≠Ⴗᠤⴋ.?͌س觴; [B1, P1, V6]; xn--vnd619as6ig6k.xn--?-7fb34t0u7s; ; ; # ≠Ⴗᠤⴋ.?͌س觴
+XN--VND619AS6IG6K.?͌س觴; ≠Ⴗᠤⴋ.?͌س觴; [B1, P1, V6]; xn--vnd619as6ig6k.xn--?-7fb34t0u7s; ; ; # ≠Ⴗᠤⴋ.?͌س觴
+Xn--Vnd619as6ig6k.?͌س觴; ≠Ⴗᠤⴋ.?͌س觴; [B1, P1, V6]; xn--vnd619as6ig6k.xn--?-7fb34t0u7s; ; ; # ≠Ⴗᠤⴋ.?͌س觴
+xn--66e353ce0ilb.?͌س觴; ≠ⴗᠤⴋ.?͌س觴; [B1, P1, V6]; xn--66e353ce0ilb.xn--?-7fb34t0u7s; ; ; # ≠ⴗᠤⴋ.?͌س觴
+XN--66E353CE0ILB.?͌س觴; ≠ⴗᠤⴋ.?͌س觴; [B1, P1, V6]; xn--66e353ce0ilb.xn--?-7fb34t0u7s; ; ; # ≠ⴗᠤⴋ.?͌س觴
+Xn--66e353ce0ilb.?͌س觴; ≠ⴗᠤⴋ.?͌س觴; [B1, P1, V6]; xn--66e353ce0ilb.xn--?-7fb34t0u7s; ; ; # ≠ⴗᠤⴋ.?͌س觴
+xn--jndx718cnnl.?͌س觴; ≠ႷᠤႫ.?͌س觴; [B1, P1, V6]; xn--jndx718cnnl.xn--?-7fb34t0u7s; ; ; # ≠ႷᠤႫ.?͌س觴
+XN--JNDX718CNNL.?͌س觴; ≠ႷᠤႫ.?͌س觴; [B1, P1, V6]; xn--jndx718cnnl.xn--?-7fb34t0u7s; ; ; # ≠ႷᠤႫ.?͌س觴
+Xn--Jndx718cnnl.?͌س觴; ≠ႷᠤႫ.?͌س觴; [B1, P1, V6]; xn--jndx718cnnl.xn--?-7fb34t0u7s; ; ; # ≠ႷᠤႫ.?͌س觴
+٧.𐥨; ; [B1, P1, V6]; xn--gib.xn--vm9c; ; ; # ٧.
+xn--gib.xn--vm9c; ٧.𐥨; [B1, V6]; xn--gib.xn--vm9c; ; ; # ٧.
+꧀𝟯。‍񼑥𐹪᯳; ꧀3.‍񼑥𐹪᯳; [B1, C2, P1, V5, V6]; xn--3-5z4e.xn--1zf96ony8ygd68c; ; xn--3-5z4e.xn--1zfz754hncv8b; [B5, P1, V5, V6] # ꧀3.𐹪᯳
+꧀3。‍񼑥𐹪᯳; ꧀3.‍񼑥𐹪᯳; [B1, C2, P1, V5, V6]; xn--3-5z4e.xn--1zf96ony8ygd68c; ; xn--3-5z4e.xn--1zfz754hncv8b; [B5, P1, V5, V6] # ꧀3.𐹪᯳
+xn--3-5z4e.xn--1zfz754hncv8b; ꧀3.񼑥𐹪᯳; [B5, V5, V6]; xn--3-5z4e.xn--1zfz754hncv8b; ; ; # ꧀3.𐹪᯳
+xn--3-5z4e.xn--1zf96ony8ygd68c; ꧀3.‍񼑥𐹪᯳; [B1, C2, V5, V6]; xn--3-5z4e.xn--1zf96ony8ygd68c; ; ; # ꧀3.𐹪᯳
+򣕄4񠖽.≯٤𑀾󠸌; ; [B1, P1, V6]; xn--4-fg85dl688i.xn--dib174li86ntdy0i; ; ; # 4.≯٤𑀾
+򣕄4񠖽.≯٤𑀾󠸌; 򣕄4񠖽.≯٤𑀾󠸌; [B1, P1, V6]; xn--4-fg85dl688i.xn--dib174li86ntdy0i; ; ; # 4.≯٤𑀾
+xn--4-fg85dl688i.xn--dib174li86ntdy0i; 򣕄4񠖽.≯٤𑀾󠸌; [B1, V6]; xn--4-fg85dl688i.xn--dib174li86ntdy0i; ; ; # 4.≯٤𑀾
+򗆧𝟯。⒈᩶𝟚򠘌; 򗆧3.⒈᩶2򠘌; [P1, V6]; xn--3-rj42h.xn--2-13k746cq465x; ; ; # 3.⒈᩶2
+򗆧3。1.᩶2򠘌; 򗆧3.1.᩶2򠘌; [P1, V5, V6]; xn--3-rj42h.1.xn--2-13k96240l; ; ; # 3.1.᩶2
+xn--3-rj42h.1.xn--2-13k96240l; 򗆧3.1.᩶2򠘌; [V5, V6]; xn--3-rj42h.1.xn--2-13k96240l; ; ; # 3.1.᩶2
+xn--3-rj42h.xn--2-13k746cq465x; 򗆧3.⒈᩶2򠘌; [V6]; xn--3-rj42h.xn--2-13k746cq465x; ; ; # 3.⒈᩶2
+‍₅⒈。≯𝟴‍; ‍5⒈.≯8‍; [C2, P1, V6]; xn--5-tgnz5r.xn--8-ugn00i; ; xn--5-ecp.xn--8-ogo; [P1, V6] # 5⒈.≯8
+‍₅⒈。≯𝟴‍; ‍5⒈.≯8‍; [C2, P1, V6]; xn--5-tgnz5r.xn--8-ugn00i; ; xn--5-ecp.xn--8-ogo; [P1, V6] # 5⒈.≯8
+‍51.。≯8‍; ‍51..≯8‍; [C2, P1, V6, X4_2]; xn--51-l1t..xn--8-ugn00i; [C2, P1, V6, A4_2]; 51..xn--8-ogo; [P1, V6, A4_2] # 51..≯8
+‍51.。≯8‍; ‍51..≯8‍; [C2, P1, V6, X4_2]; xn--51-l1t..xn--8-ugn00i; [C2, P1, V6, A4_2]; 51..xn--8-ogo; [P1, V6, A4_2] # 51..≯8
+51..xn--8-ogo; 51..≯8; [V6, X4_2]; 51..xn--8-ogo; [V6, A4_2]; ; # 51..≯8
+xn--51-l1t..xn--8-ugn00i; ‍51..≯8‍; [C2, V6, X4_2]; xn--51-l1t..xn--8-ugn00i; [C2, V6, A4_2]; ; # 51..≯8
+xn--5-ecp.xn--8-ogo; 5⒈.≯8; [V6]; xn--5-ecp.xn--8-ogo; ; ; # 5⒈.≯8
+xn--5-tgnz5r.xn--8-ugn00i; ‍5⒈.≯8‍; [C2, V6]; xn--5-tgnz5r.xn--8-ugn00i; ; ; # 5⒈.≯8
+ꡰڗႆ.򪘙ܯ≠‌; ꡰڗႆ.򪘙ܯ≠‌; [B5, B6, C1, P1, V6]; xn--tjb002cn51k.xn--5nb448jcubcz547b; ; xn--tjb002cn51k.xn--5nb630lbj91q; [B5, B6, P1, V6] # ꡰڗႆ.ܯ≠
+ꡰڗႆ.򪘙ܯ≠‌; ꡰڗႆ.򪘙ܯ≠‌; [B5, B6, C1, P1, V6]; xn--tjb002cn51k.xn--5nb448jcubcz547b; ; xn--tjb002cn51k.xn--5nb630lbj91q; [B5, B6, P1, V6] # ꡰڗႆ.ܯ≠
+ꡰڗႆ.򪘙ܯ≠‌; ; [B5, B6, C1, P1, V6]; xn--tjb002cn51k.xn--5nb448jcubcz547b; ; xn--tjb002cn51k.xn--5nb630lbj91q; [B5, B6, P1, V6] # ꡰڗႆ.ܯ≠
+ꡰڗႆ.򪘙ܯ≠‌; ꡰڗႆ.򪘙ܯ≠‌; [B5, B6, C1, P1, V6]; xn--tjb002cn51k.xn--5nb448jcubcz547b; ; xn--tjb002cn51k.xn--5nb630lbj91q; [B5, B6, P1, V6] # ꡰڗႆ.ܯ≠
+xn--tjb002cn51k.xn--5nb630lbj91q; ꡰڗႆ.򪘙ܯ≠; [B5, B6, V6]; xn--tjb002cn51k.xn--5nb630lbj91q; ; ; # ꡰڗႆ.ܯ≠
+xn--tjb002cn51k.xn--5nb448jcubcz547b; ꡰڗႆ.򪘙ܯ≠‌; [B5, B6, C1, V6]; xn--tjb002cn51k.xn--5nb448jcubcz547b; ; ; # ꡰڗႆ.ܯ≠
+𑄱。򪌿𐹵; 𑄱.򪌿𐹵; [B1, B3, B5, B6, P1, V5, V6]; xn--t80d.xn--to0d14792b; ; ; # 𑄱.𐹵
+𑄱。򪌿𐹵; 𑄱.򪌿𐹵; [B1, B3, B5, B6, P1, V5, V6]; xn--t80d.xn--to0d14792b; ; ; # 𑄱.𐹵
+xn--t80d.xn--to0d14792b; 𑄱.򪌿𐹵; [B1, B3, B5, B6, V5, V6]; xn--t80d.xn--to0d14792b; ; ; # 𑄱.𐹵
+𝟥؀。ܽ; 3؀.ܽ; [B1, B3, B6, P1, V5, V6]; xn--3-rkc.xn--kob; ; ; # 3.ܽ
+3؀。ܽ; 3؀.ܽ; [B1, B3, B6, P1, V5, V6]; xn--3-rkc.xn--kob; ; ; # 3.ܽ
+xn--3-rkc.xn--kob; 3؀.ܽ; [B1, B3, B6, V5, V6]; xn--3-rkc.xn--kob; ; ; # 3.ܽ
+ط𐹣٦.ݭ긷; ; [B2, B3]; xn--2gb8gu829f.xn--xpb0156f; ; ; # ط𐹣٦.ݭ긷
+ط𐹣٦.ݭ긷; ط𐹣٦.ݭ긷; [B2, B3]; xn--2gb8gu829f.xn--xpb0156f; ; ; # ط𐹣٦.ݭ긷
+xn--2gb8gu829f.xn--xpb0156f; ط𐹣٦.ݭ긷; [B2, B3]; xn--2gb8gu829f.xn--xpb0156f; ; ; # ط𐹣٦.ݭ긷
+︒Ↄⷧ򾀃.Ⴗ𐣞; ︒Ↄⷧ򾀃.Ⴗ𐣞; [B1, B5, B6, P1, V6]; xn--q5g000c056n0226g.xn--vnd8618j; ; ; # ︒Ↄⷧ.Ⴗ
+。Ↄⷧ򾀃.Ⴗ𐣞; .Ↄⷧ򾀃.Ⴗ𐣞; [B5, B6, P1, V6, X4_2]; .xn--q5g000cll06u.xn--vnd8618j; [B5, B6, P1, V6, A4_2]; ; # .Ↄⷧ.Ⴗ
+。ↄⷧ򾀃.ⴗ𐣞; .ↄⷧ򾀃.ⴗ𐣞; [B5, B6, P1, V6, X4_2]; .xn--r5gy00cll06u.xn--flj4541e; [B5, B6, P1, V6, A4_2]; ; # .ↄⷧ.ⴗ
+.xn--r5gy00cll06u.xn--flj4541e; .ↄⷧ򾀃.ⴗ𐣞; [B5, B6, V6, X4_2]; .xn--r5gy00cll06u.xn--flj4541e; [B5, B6, V6, A4_2]; ; # .ↄⷧ.ⴗ
+.xn--q5g000cll06u.xn--vnd8618j; .Ↄⷧ򾀃.Ⴗ𐣞; [B5, B6, V6, X4_2]; .xn--q5g000cll06u.xn--vnd8618j; [B5, B6, V6, A4_2]; ; # .Ↄⷧ.Ⴗ
+︒ↄⷧ򾀃.ⴗ𐣞; ︒ↄⷧ򾀃.ⴗ𐣞; [B1, B5, B6, P1, V6]; xn--r5gy00c056n0226g.xn--flj4541e; ; ; # ︒ↄⷧ.ⴗ
+xn--r5gy00c056n0226g.xn--flj4541e; ︒ↄⷧ򾀃.ⴗ𐣞; [B1, B5, B6, V6]; xn--r5gy00c056n0226g.xn--flj4541e; ; ; # ︒ↄⷧ.ⴗ
+xn--q5g000c056n0226g.xn--vnd8618j; ︒Ↄⷧ򾀃.Ⴗ𐣞; [B1, B5, B6, V6]; xn--q5g000c056n0226g.xn--vnd8618j; ; ; # ︒Ↄⷧ.Ⴗ
+؀.ֱ; ; [B1, B3, B6, P1, V5, V6]; xn--ifb.xn--8cb; ; ; # .ֱ
+xn--ifb.xn--8cb; ؀.ֱ; [B1, B3, B6, V5, V6]; xn--ifb.xn--8cb; ; ; # .ֱ
+ς≯。𐹽; ς≯.𐹽; [B1, B6, P1, V6]; xn--3xa028m.xn--1o0d; ; xn--4xa818m.xn--1o0d; # ς≯.𐹽
+ς≯。𐹽; ς≯.𐹽; [B1, B6, P1, V6]; xn--3xa028m.xn--1o0d; ; xn--4xa818m.xn--1o0d; # ς≯.𐹽
+ς≯。𐹽; ς≯.𐹽; [B1, B6, P1, V6]; xn--3xa028m.xn--1o0d; ; xn--4xa818m.xn--1o0d; # ς≯.𐹽
+ς≯。𐹽; ς≯.𐹽; [B1, B6, P1, V6]; xn--3xa028m.xn--1o0d; ; xn--4xa818m.xn--1o0d; # ς≯.𐹽
+Σ≯。𐹽; σ≯.𐹽; [B1, B6, P1, V6]; xn--4xa818m.xn--1o0d; ; ; # σ≯.𐹽
+Σ≯。𐹽; σ≯.𐹽; [B1, B6, P1, V6]; xn--4xa818m.xn--1o0d; ; ; # σ≯.𐹽
+σ≯。𐹽; σ≯.𐹽; [B1, B6, P1, V6]; xn--4xa818m.xn--1o0d; ; ; # σ≯.𐹽
+σ≯。𐹽; σ≯.𐹽; [B1, B6, P1, V6]; xn--4xa818m.xn--1o0d; ; ; # σ≯.𐹽
+xn--4xa818m.xn--1o0d; σ≯.𐹽; [B1, B6, V6]; xn--4xa818m.xn--1o0d; ; ; # σ≯.𐹽
+xn--3xa028m.xn--1o0d; ς≯.𐹽; [B1, B6, V6]; xn--3xa028m.xn--1o0d; ; ; # ς≯.𐹽
+Σ≯。𐹽; σ≯.𐹽; [B1, B6, P1, V6]; xn--4xa818m.xn--1o0d; ; ; # σ≯.𐹽
+Σ≯。𐹽; σ≯.𐹽; [B1, B6, P1, V6]; xn--4xa818m.xn--1o0d; ; ; # σ≯.𐹽
+σ≯。𐹽; σ≯.𐹽; [B1, B6, P1, V6]; xn--4xa818m.xn--1o0d; ; ; # σ≯.𐹽
+σ≯。𐹽; σ≯.𐹽; [B1, B6, P1, V6]; xn--4xa818m.xn--1o0d; ; ; # σ≯.𐹽
+្‍ݟ。𐹶; ្‍ݟ.𐹶; [B1, V5]; xn--jpb535fv9f.xn--uo0d; ; xn--jpb535f.xn--uo0d; # ្ݟ.𐹶
+xn--jpb535f.xn--uo0d; ្ݟ.𐹶; [B1, V5]; xn--jpb535f.xn--uo0d; ; ; # ្ݟ.𐹶
+xn--jpb535fv9f.xn--uo0d; ្‍ݟ.𐹶; [B1, V5]; xn--jpb535fv9f.xn--uo0d; ; ; # ្ݟ.𐹶
+𾷂ੂႪ񂂟.≮; ; [P1, V6]; xn--nbc493aro75ggskb.xn--gdh; ; ; # ੂႪ.≮
+𾷂ੂႪ񂂟.≮; 𾷂ੂႪ񂂟.≮; [P1, V6]; xn--nbc493aro75ggskb.xn--gdh; ; ; # ੂႪ.≮
+𾷂ੂⴊ񂂟.≮; 𾷂ੂⴊ񂂟.≮; [P1, V6]; xn--nbc229o4y27dgskb.xn--gdh; ; ; # ੂⴊ.≮
+𾷂ੂⴊ񂂟.≮; ; [P1, V6]; xn--nbc229o4y27dgskb.xn--gdh; ; ; # ੂⴊ.≮
+xn--nbc229o4y27dgskb.xn--gdh; 𾷂ੂⴊ񂂟.≮; [V6]; xn--nbc229o4y27dgskb.xn--gdh; ; ; # ੂⴊ.≮
+xn--nbc493aro75ggskb.xn--gdh; 𾷂ੂႪ񂂟.≮; [V6]; xn--nbc493aro75ggskb.xn--gdh; ; ; # ੂႪ.≮
+ꡠ.۲; ꡠ.۲; ; xn--5c9a.xn--fmb; ; ; # ꡠ.۲
+ꡠ.۲; ; ; xn--5c9a.xn--fmb; ; ; # ꡠ.۲
+xn--5c9a.xn--fmb; ꡠ.۲; ; xn--5c9a.xn--fmb; ; ; # ꡠ.۲
+𐹣񄷄。ꡬ🄄; 𐹣񄷄.ꡬ🄄; [B1, P1, V6]; xn--bo0d0203l.xn--id9a4443d; ; ; # 𐹣.ꡬ🄄
+𐹣񄷄。ꡬ3,; 𐹣񄷄.ꡬ3,; [B1, B6, P1, V6]; xn--bo0d0203l.xn--3,-yj9h; ; ; # 𐹣.ꡬ3,
+xn--bo0d0203l.xn--3,-yj9h; 𐹣񄷄.ꡬ3,; [B1, B6, P1, V6]; xn--bo0d0203l.xn--3,-yj9h; ; ; # 𐹣.ꡬ3,
+xn--bo0d0203l.xn--id9a4443d; 𐹣񄷄.ꡬ🄄; [B1, V6]; xn--bo0d0203l.xn--id9a4443d; ; ; # 𐹣.ꡬ🄄
+-్𞾀𑲓。‍്; -్𞾀𑲓.‍്; [B1, C2, P1, V3, V6]; xn----x6e0220sclug.xn--wxc317g; ; xn----x6e0220sclug.xn--wxc; [B1, B3, B6, P1, V3, V5, V6] # -్𑲓.്
+-్𞾀𑲓。‍്; -్𞾀𑲓.‍്; [B1, C2, P1, V3, V6]; xn----x6e0220sclug.xn--wxc317g; ; xn----x6e0220sclug.xn--wxc; [B1, B3, B6, P1, V3, V5, V6] # -్𑲓.്
+xn----x6e0220sclug.xn--wxc; -్𞾀𑲓.്; [B1, B3, B6, V3, V5, V6]; xn----x6e0220sclug.xn--wxc; ; ; # -్𑲓.്
+xn----x6e0220sclug.xn--wxc317g; -్𞾀𑲓.‍്; [B1, C2, V3, V6]; xn----x6e0220sclug.xn--wxc317g; ; ; # -్𑲓.്
+꙽‌霣🄆。‌𑁂ᬁ; ꙽‌霣🄆.‌𑁂ᬁ; [C1, P1, V5, V6]; xn--0ug4208b2vjuk63a.xn--4sf36u6u4w; ; xn--2q5a751a653w.xn--4sf0725i; [P1, V5, V6] # ꙽霣🄆.𑁂ᬁ
+꙽‌霣🄆。‌𑁂ᬁ; ꙽‌霣🄆.‌𑁂ᬁ; [C1, P1, V5, V6]; xn--0ug4208b2vjuk63a.xn--4sf36u6u4w; ; xn--2q5a751a653w.xn--4sf0725i; [P1, V5, V6] # ꙽霣🄆.𑁂ᬁ
+꙽‌霣5,。‌𑁂ᬁ; ꙽‌霣5,.‌𑁂ᬁ; [C1, P1, V5, V6]; xn--5,-i1tz135dnbqa.xn--4sf36u6u4w; ; xn--5,-op8g373c.xn--4sf0725i; [P1, V5, V6] # ꙽霣5,.𑁂ᬁ
+xn--5,-op8g373c.xn--4sf0725i; ꙽霣5,.𑁂ᬁ; [P1, V5, V6]; xn--5,-op8g373c.xn--4sf0725i; ; ; # ꙽霣5,.𑁂ᬁ
+xn--5,-i1tz135dnbqa.xn--4sf36u6u4w; ꙽‌霣5,.‌𑁂ᬁ; [C1, P1, V5, V6]; xn--5,-i1tz135dnbqa.xn--4sf36u6u4w; ; ; # ꙽霣5,.𑁂ᬁ
+xn--2q5a751a653w.xn--4sf0725i; ꙽霣🄆.𑁂ᬁ; [V5, V6]; xn--2q5a751a653w.xn--4sf0725i; ; ; # ꙽霣🄆.𑁂ᬁ
+xn--0ug4208b2vjuk63a.xn--4sf36u6u4w; ꙽‌霣🄆.‌𑁂ᬁ; [C1, V5, V6]; xn--0ug4208b2vjuk63a.xn--4sf36u6u4w; ; ; # ꙽霣🄆.𑁂ᬁ
+兎。ᠼ󠴜𑚶𑰿; 兎.ᠼ󠴜𑚶𑰿; [P1, V6]; xn--b5q.xn--v7e6041kqqd4m251b; ; ; # 兎.ᠼ𑚶𑰿
+兎。ᠼ󠴜𑚶𑰿; 兎.ᠼ󠴜𑚶𑰿; [P1, V6]; xn--b5q.xn--v7e6041kqqd4m251b; ; ; # 兎.ᠼ𑚶𑰿
+xn--b5q.xn--v7e6041kqqd4m251b; 兎.ᠼ󠴜𑚶𑰿; [V6]; xn--b5q.xn--v7e6041kqqd4m251b; ; ; # 兎.ᠼ𑚶𑰿
+𝟙。‍𝟸‍⁷; 1.‍2‍7; [C2]; 1.xn--27-l1tb; ; 1.27; [] # 1.27
+1。‍2‍7; 1.‍2‍7; [C2]; 1.xn--27-l1tb; ; 1.27; [] # 1.27
+1.27; ; ; ; ; ; # 1.27
+1.xn--27-l1tb; 1.‍2‍7; [C2]; 1.xn--27-l1tb; ; ; # 1.27
+ᡨ-。󠻋𝟷; ᡨ-.󠻋1; [P1, V3, V6]; xn----z8j.xn--1-5671m; ; ; # ᡨ-.1
+ᡨ-。󠻋1; ᡨ-.󠻋1; [P1, V3, V6]; xn----z8j.xn--1-5671m; ; ; # ᡨ-.1
+xn----z8j.xn--1-5671m; ᡨ-.󠻋1; [V3, V6]; xn----z8j.xn--1-5671m; ; ; # ᡨ-.1
+𑰻񵀐𐫚.٨⁹; 𑰻񵀐𐫚.٨9; [B1, P1, V5, V6]; xn--gx9cr01aul57i.xn--9-oqc; ; ; # 𑰻𐫚.٨9
+𑰻񵀐𐫚.٨9; ; [B1, P1, V5, V6]; xn--gx9cr01aul57i.xn--9-oqc; ; ; # 𑰻𐫚.٨9
+xn--gx9cr01aul57i.xn--9-oqc; 𑰻񵀐𐫚.٨9; [B1, V5, V6]; xn--gx9cr01aul57i.xn--9-oqc; ; ; # 𑰻𐫚.٨9
+Ⴜ򈷭ྀ⾇。Ⴏ♀‌‌; Ⴜ򈷭ྀ舛.Ⴏ♀‌‌; [C1, P1, V6]; xn--zed54dz10wo343g.xn--nnd089ea464d; ; xn--zed54dz10wo343g.xn--nnd651i; [P1, V6] # Ⴜྀ舛.Ⴏ♀
+Ⴜ򈷭ྀ舛。Ⴏ♀‌‌; Ⴜ򈷭ྀ舛.Ⴏ♀‌‌; [C1, P1, V6]; xn--zed54dz10wo343g.xn--nnd089ea464d; ; xn--zed54dz10wo343g.xn--nnd651i; [P1, V6] # Ⴜྀ舛.Ⴏ♀
+ⴜ򈷭ྀ舛。ⴏ♀‌‌; ⴜ򈷭ྀ舛.ⴏ♀‌‌; [C1, P1, V6]; xn--zed372mdj2do3v4h.xn--0uga678bgyh; ; xn--zed372mdj2do3v4h.xn--e5h11w; [P1, V6] # ⴜྀ舛.ⴏ♀
+xn--zed372mdj2do3v4h.xn--e5h11w; ⴜ򈷭ྀ舛.ⴏ♀; [V6]; xn--zed372mdj2do3v4h.xn--e5h11w; ; ; # ⴜྀ舛.ⴏ♀
+xn--zed372mdj2do3v4h.xn--0uga678bgyh; ⴜ򈷭ྀ舛.ⴏ♀‌‌; [C1, V6]; xn--zed372mdj2do3v4h.xn--0uga678bgyh; ; ; # ⴜྀ舛.ⴏ♀
+xn--zed54dz10wo343g.xn--nnd651i; Ⴜ򈷭ྀ舛.Ⴏ♀; [V6]; xn--zed54dz10wo343g.xn--nnd651i; ; ; # Ⴜྀ舛.Ⴏ♀
+xn--zed54dz10wo343g.xn--nnd089ea464d; Ⴜ򈷭ྀ舛.Ⴏ♀‌‌; [C1, V6]; xn--zed54dz10wo343g.xn--nnd089ea464d; ; ; # Ⴜྀ舛.Ⴏ♀
+ⴜ򈷭ྀ⾇。ⴏ♀‌‌; ⴜ򈷭ྀ舛.ⴏ♀‌‌; [C1, P1, V6]; xn--zed372mdj2do3v4h.xn--0uga678bgyh; ; xn--zed372mdj2do3v4h.xn--e5h11w; [P1, V6] # ⴜྀ舛.ⴏ♀
+𑁆𝟰.‍; 𑁆4.‍; [C2, V5]; xn--4-xu7i.xn--1ug; ; xn--4-xu7i.; [V5] # 𑁆4.
+𑁆4.‍; ; [C2, V5]; xn--4-xu7i.xn--1ug; ; xn--4-xu7i.; [V5] # 𑁆4.
+xn--4-xu7i.; 𑁆4.; [V5]; xn--4-xu7i.; ; ; # 𑁆4.
+xn--4-xu7i.xn--1ug; 𑁆4.‍; [C2, V5]; xn--4-xu7i.xn--1ug; ; ; # 𑁆4.
+񮴘Ⴞ癀。𑘿‍‌붼; 񮴘Ⴞ癀.𑘿‍‌붼; [C1, P1, V5, V6]; xn--2nd6803c7q37d.xn--0ugb6122js83c; ; xn--2nd6803c7q37d.xn--et3bn23n; [P1, V5, V6] # Ⴞ癀.𑘿붼
+񮴘Ⴞ癀。𑘿‍‌붼; 񮴘Ⴞ癀.𑘿‍‌붼; [C1, P1, V5, V6]; xn--2nd6803c7q37d.xn--0ugb6122js83c; ; xn--2nd6803c7q37d.xn--et3bn23n; [P1, V5, V6] # Ⴞ癀.𑘿붼
+񮴘Ⴞ癀。𑘿‍‌붼; 񮴘Ⴞ癀.𑘿‍‌붼; [C1, P1, V5, V6]; xn--2nd6803c7q37d.xn--0ugb6122js83c; ; xn--2nd6803c7q37d.xn--et3bn23n; [P1, V5, V6] # Ⴞ癀.𑘿붼
+񮴘Ⴞ癀。𑘿‍‌붼; 񮴘Ⴞ癀.𑘿‍‌붼; [C1, P1, V5, V6]; xn--2nd6803c7q37d.xn--0ugb6122js83c; ; xn--2nd6803c7q37d.xn--et3bn23n; [P1, V5, V6] # Ⴞ癀.𑘿붼
+񮴘ⴞ癀。𑘿‍‌붼; 񮴘ⴞ癀.𑘿‍‌붼; [C1, P1, V5, V6]; xn--mlju35u7qx2f.xn--0ugb6122js83c; ; xn--mlju35u7qx2f.xn--et3bn23n; [P1, V5, V6] # ⴞ癀.𑘿붼
+񮴘ⴞ癀。𑘿‍‌붼; 񮴘ⴞ癀.𑘿‍‌붼; [C1, P1, V5, V6]; xn--mlju35u7qx2f.xn--0ugb6122js83c; ; xn--mlju35u7qx2f.xn--et3bn23n; [P1, V5, V6] # ⴞ癀.𑘿붼
+xn--mlju35u7qx2f.xn--et3bn23n; 񮴘ⴞ癀.𑘿붼; [V5, V6]; xn--mlju35u7qx2f.xn--et3bn23n; ; ; # ⴞ癀.𑘿붼
+xn--mlju35u7qx2f.xn--0ugb6122js83c; 񮴘ⴞ癀.𑘿‍‌붼; [C1, V5, V6]; xn--mlju35u7qx2f.xn--0ugb6122js83c; ; ; # ⴞ癀.𑘿붼
+xn--2nd6803c7q37d.xn--et3bn23n; 񮴘Ⴞ癀.𑘿붼; [V5, V6]; xn--2nd6803c7q37d.xn--et3bn23n; ; ; # Ⴞ癀.𑘿붼
+xn--2nd6803c7q37d.xn--0ugb6122js83c; 񮴘Ⴞ癀.𑘿‍‌붼; [C1, V5, V6]; xn--2nd6803c7q37d.xn--0ugb6122js83c; ; ; # Ⴞ癀.𑘿붼
+񮴘ⴞ癀。𑘿‍‌붼; 񮴘ⴞ癀.𑘿‍‌붼; [C1, P1, V5, V6]; xn--mlju35u7qx2f.xn--0ugb6122js83c; ; xn--mlju35u7qx2f.xn--et3bn23n; [P1, V5, V6] # ⴞ癀.𑘿붼
+񮴘ⴞ癀。𑘿‍‌붼; 񮴘ⴞ癀.𑘿‍‌붼; [C1, P1, V5, V6]; xn--mlju35u7qx2f.xn--0ugb6122js83c; ; xn--mlju35u7qx2f.xn--et3bn23n; [P1, V5, V6] # ⴞ癀.𑘿붼
+󚀅-்。ڹ; 󚀅-்.ڹ; [B6, P1, V6]; xn----mze84808x.xn--skb; ; ; # -்.ڹ
+xn----mze84808x.xn--skb; 󚀅-்.ڹ; [B6, V6]; xn----mze84808x.xn--skb; ; ; # -்.ڹ
+ᡃ𝟧≯ᠣ.氁񨏱ꁫ; ᡃ5≯ᠣ.氁񨏱ꁫ; [P1, V6]; xn--5-24jyf768b.xn--lqw213ime95g; ; ; # ᡃ5≯ᠣ.氁ꁫ
+ᡃ𝟧≯ᠣ.氁񨏱ꁫ; ᡃ5≯ᠣ.氁񨏱ꁫ; [P1, V6]; xn--5-24jyf768b.xn--lqw213ime95g; ; ; # ᡃ5≯ᠣ.氁ꁫ
+ᡃ5≯ᠣ.氁񨏱ꁫ; ; [P1, V6]; xn--5-24jyf768b.xn--lqw213ime95g; ; ; # ᡃ5≯ᠣ.氁ꁫ
+ᡃ5≯ᠣ.氁񨏱ꁫ; ᡃ5≯ᠣ.氁񨏱ꁫ; [P1, V6]; xn--5-24jyf768b.xn--lqw213ime95g; ; ; # ᡃ5≯ᠣ.氁ꁫ
+xn--5-24jyf768b.xn--lqw213ime95g; ᡃ5≯ᠣ.氁񨏱ꁫ; [V6]; xn--5-24jyf768b.xn--lqw213ime95g; ; ; # ᡃ5≯ᠣ.氁ꁫ
+𐹬𝩇.ྲྀ; 𐹬𝩇.ྲྀ; [B1, B3, B6, V5]; xn--ko0d8295a.xn--zed3h; ; ; # 𐹬𝩇.ྲྀ
+𐹬𝩇.ྲྀ; 𐹬𝩇.ྲྀ; [B1, B3, B6, V5]; xn--ko0d8295a.xn--zed3h; ; ; # 𐹬𝩇.ྲྀ
+𐹬𝩇.ྲྀ; ; [B1, B3, B6, V5]; xn--ko0d8295a.xn--zed3h; ; ; # 𐹬𝩇.ྲྀ
+xn--ko0d8295a.xn--zed3h; 𐹬𝩇.ྲྀ; [B1, B3, B6, V5]; xn--ko0d8295a.xn--zed3h; ; ; # 𐹬𝩇.ྲྀ
+-𑈶⒏.⒎𰛢󠎭; -𑈶⒏.⒎𰛢󠎭; [P1, V3, V6]; xn----scp6252h.xn--zshy411yzpx2d; ; ; # -𑈶⒏.⒎𰛢
+-𑈶8..7.𰛢󠎭; ; [P1, V3, V6, X4_2]; xn---8-bv5o..7.xn--c35nf1622b; [P1, V3, V6, A4_2]; ; # -𑈶8..7.𰛢
+xn---8-bv5o..7.xn--c35nf1622b; -𑈶8..7.𰛢󠎭; [V3, V6, X4_2]; xn---8-bv5o..7.xn--c35nf1622b; [V3, V6, A4_2]; ; # -𑈶8..7.𰛢
+xn----scp6252h.xn--zshy411yzpx2d; -𑈶⒏.⒎𰛢󠎭; [V3, V6]; xn----scp6252h.xn--zshy411yzpx2d; ; ; # -𑈶⒏.⒎𰛢
+‌Ⴁ畝‍.≮; ‌Ⴁ畝‍.≮; [C1, C2, P1, V6]; xn--8md700fea3748f.xn--gdh; ; xn--8md0962c.xn--gdh; [P1, V6] # Ⴁ畝.≮
+‌Ⴁ畝‍.≮; ‌Ⴁ畝‍.≮; [C1, C2, P1, V6]; xn--8md700fea3748f.xn--gdh; ; xn--8md0962c.xn--gdh; [P1, V6] # Ⴁ畝.≮
+‌Ⴁ畝‍.≮; ; [C1, C2, P1, V6]; xn--8md700fea3748f.xn--gdh; ; xn--8md0962c.xn--gdh; [P1, V6] # Ⴁ畝.≮
+‌Ⴁ畝‍.≮; ‌Ⴁ畝‍.≮; [C1, C2, P1, V6]; xn--8md700fea3748f.xn--gdh; ; xn--8md0962c.xn--gdh; [P1, V6] # Ⴁ畝.≮
+‌ⴁ畝‍.≮; ‌ⴁ畝‍.≮; [C1, C2, P1, V6]; xn--0ugc160hb36e.xn--gdh; ; xn--skjy82u.xn--gdh; [P1, V6] # ⴁ畝.≮
+‌ⴁ畝‍.≮; ; [C1, C2, P1, V6]; xn--0ugc160hb36e.xn--gdh; ; xn--skjy82u.xn--gdh; [P1, V6] # ⴁ畝.≮
+xn--skjy82u.xn--gdh; ⴁ畝.≮; [V6]; xn--skjy82u.xn--gdh; ; ; # ⴁ畝.≮
+xn--0ugc160hb36e.xn--gdh; ‌ⴁ畝‍.≮; [C1, C2, V6]; xn--0ugc160hb36e.xn--gdh; ; ; # ⴁ畝.≮
+xn--8md0962c.xn--gdh; Ⴁ畝.≮; [V6]; xn--8md0962c.xn--gdh; ; ; # Ⴁ畝.≮
+xn--8md700fea3748f.xn--gdh; ‌Ⴁ畝‍.≮; [C1, C2, V6]; xn--8md700fea3748f.xn--gdh; ; ; # Ⴁ畝.≮
+‌ⴁ畝‍.≮; ‌ⴁ畝‍.≮; [C1, C2, P1, V6]; xn--0ugc160hb36e.xn--gdh; ; xn--skjy82u.xn--gdh; [P1, V6] # ⴁ畝.≮
+‌ⴁ畝‍.≮; ‌ⴁ畝‍.≮; [C1, C2, P1, V6]; xn--0ugc160hb36e.xn--gdh; ; xn--skjy82u.xn--gdh; [P1, V6] # ⴁ畝.≮
+歷。𐹻≯󳛽‍; 歷.𐹻≯󳛽‍; [B1, C2, P1, V6]; xn--nmw.xn--1ugx6gs128a1134j; ; xn--nmw.xn--hdh7804gdms2h; [B1, P1, V6] # 歷.𐹻≯
+歷。𐹻≯󳛽‍; 歷.𐹻≯󳛽‍; [B1, C2, P1, V6]; xn--nmw.xn--1ugx6gs128a1134j; ; xn--nmw.xn--hdh7804gdms2h; [B1, P1, V6] # 歷.𐹻≯
+歷。𐹻≯󳛽‍; 歷.𐹻≯󳛽‍; [B1, C2, P1, V6]; xn--nmw.xn--1ugx6gs128a1134j; ; xn--nmw.xn--hdh7804gdms2h; [B1, P1, V6] # 歷.𐹻≯
+歷。𐹻≯󳛽‍; 歷.𐹻≯󳛽‍; [B1, C2, P1, V6]; xn--nmw.xn--1ugx6gs128a1134j; ; xn--nmw.xn--hdh7804gdms2h; [B1, P1, V6] # 歷.𐹻≯
+xn--nmw.xn--hdh7804gdms2h; 歷.𐹻≯󳛽; [B1, V6]; xn--nmw.xn--hdh7804gdms2h; ; ; # 歷.𐹻≯
+xn--nmw.xn--1ugx6gs128a1134j; 歷.𐹻≯󳛽‍; [B1, C2, V6]; xn--nmw.xn--1ugx6gs128a1134j; ; ; # 歷.𐹻≯
+໋‍.鎁󠰑; ໋‍.鎁󠰑; [C2, P1, V5, V6]; xn--t8c059f.xn--iz4a43209d; ; xn--t8c.xn--iz4a43209d; [P1, V5, V6] # ໋.鎁
+໋‍.鎁󠰑; ; [C2, P1, V5, V6]; xn--t8c059f.xn--iz4a43209d; ; xn--t8c.xn--iz4a43209d; [P1, V5, V6] # ໋.鎁
+xn--t8c.xn--iz4a43209d; ໋.鎁󠰑; [V5, V6]; xn--t8c.xn--iz4a43209d; ; ; # ໋.鎁
+xn--t8c059f.xn--iz4a43209d; ໋‍.鎁󠰑; [C2, V5, V6]; xn--t8c059f.xn--iz4a43209d; ; ; # ໋.鎁
+‍‌𞤀。𱘅𐶃; ‍‌𞤢.𱘅𐶃; [B1, B5, B6, C1, C2, P1, V6]; xn--0ugb45126a.xn--wh0dj799f; ; xn--9d6h.xn--wh0dj799f; [B5, B6, P1, V6] # 𞤢.
+‍‌𞤀。𱘅𐶃; ‍‌𞤢.𱘅𐶃; [B1, B5, B6, C1, C2, P1, V6]; xn--0ugb45126a.xn--wh0dj799f; ; xn--9d6h.xn--wh0dj799f; [B5, B6, P1, V6] # 𞤢.
+‍‌𞤢。𱘅𐶃; ‍‌𞤢.𱘅𐶃; [B1, B5, B6, C1, C2, P1, V6]; xn--0ugb45126a.xn--wh0dj799f; ; xn--9d6h.xn--wh0dj799f; [B5, B6, P1, V6] # 𞤢.
+xn--9d6h.xn--wh0dj799f; 𞤢.𱘅𐶃; [B5, B6, V6]; xn--9d6h.xn--wh0dj799f; ; ; # 𞤢.
+xn--0ugb45126a.xn--wh0dj799f; ‍‌𞤢.𱘅𐶃; [B1, B5, B6, C1, C2, V6]; xn--0ugb45126a.xn--wh0dj799f; ; ; # 𞤢.
+‍‌𞤢。𱘅𐶃; ‍‌𞤢.𱘅𐶃; [B1, B5, B6, C1, C2, P1, V6]; xn--0ugb45126a.xn--wh0dj799f; ; xn--9d6h.xn--wh0dj799f; [B5, B6, P1, V6] # 𞤢.
+ب≠𝟫-.ς⒍𐹦≠; ب≠9-.ς⒍𐹦≠; [B3, B5, B6, P1, V3, V6]; xn--9--etd0100a.xn--3xa097mzpbzz04b; ; xn--9--etd0100a.xn--4xa887mzpbzz04b; # ب≠9-.ς⒍𐹦≠
+ب≠𝟫-.ς⒍𐹦≠; ب≠9-.ς⒍𐹦≠; [B3, B5, B6, P1, V3, V6]; xn--9--etd0100a.xn--3xa097mzpbzz04b; ; xn--9--etd0100a.xn--4xa887mzpbzz04b; # ب≠9-.ς⒍𐹦≠
+ب≠9-.ς6.𐹦≠; ; [B1, B3, P1, V3, V6]; xn--9--etd0100a.xn--6-xmb.xn--1ch8704g; ; xn--9--etd0100a.xn--6-zmb.xn--1ch8704g; # ب≠9-.ς6.𐹦≠
+ب≠9-.ς6.𐹦≠; ب≠9-.ς6.𐹦≠; [B1, B3, P1, V3, V6]; xn--9--etd0100a.xn--6-xmb.xn--1ch8704g; ; xn--9--etd0100a.xn--6-zmb.xn--1ch8704g; # ب≠9-.ς6.𐹦≠
+ب≠9-.Σ6.𐹦≠; ب≠9-.σ6.𐹦≠; [B1, B3, P1, V3, V6]; xn--9--etd0100a.xn--6-zmb.xn--1ch8704g; ; ; # ب≠9-.σ6.𐹦≠
+ب≠9-.Σ6.𐹦≠; ب≠9-.σ6.𐹦≠; [B1, B3, P1, V3, V6]; xn--9--etd0100a.xn--6-zmb.xn--1ch8704g; ; ; # ب≠9-.σ6.𐹦≠
+ب≠9-.σ6.𐹦≠; ; [B1, B3, P1, V3, V6]; xn--9--etd0100a.xn--6-zmb.xn--1ch8704g; ; ; # ب≠9-.σ6.𐹦≠
+ب≠9-.σ6.𐹦≠; ب≠9-.σ6.𐹦≠; [B1, B3, P1, V3, V6]; xn--9--etd0100a.xn--6-zmb.xn--1ch8704g; ; ; # ب≠9-.σ6.𐹦≠
+xn--9--etd0100a.xn--6-zmb.xn--1ch8704g; ب≠9-.σ6.𐹦≠; [B1, B3, V3, V6]; xn--9--etd0100a.xn--6-zmb.xn--1ch8704g; ; ; # ب≠9-.σ6.𐹦≠
+xn--9--etd0100a.xn--6-xmb.xn--1ch8704g; ب≠9-.ς6.𐹦≠; [B1, B3, V3, V6]; xn--9--etd0100a.xn--6-xmb.xn--1ch8704g; ; ; # ب≠9-.ς6.𐹦≠
+ب≠𝟫-.Σ⒍𐹦≠; ب≠9-.σ⒍𐹦≠; [B3, B5, B6, P1, V3, V6]; xn--9--etd0100a.xn--4xa887mzpbzz04b; ; ; # ب≠9-.σ⒍𐹦≠
+ب≠𝟫-.Σ⒍𐹦≠; ب≠9-.σ⒍𐹦≠; [B3, B5, B6, P1, V3, V6]; xn--9--etd0100a.xn--4xa887mzpbzz04b; ; ; # ب≠9-.σ⒍𐹦≠
+ب≠𝟫-.σ⒍𐹦≠; ب≠9-.σ⒍𐹦≠; [B3, B5, B6, P1, V3, V6]; xn--9--etd0100a.xn--4xa887mzpbzz04b; ; ; # ب≠9-.σ⒍𐹦≠
+ب≠𝟫-.σ⒍𐹦≠; ب≠9-.σ⒍𐹦≠; [B3, B5, B6, P1, V3, V6]; xn--9--etd0100a.xn--4xa887mzpbzz04b; ; ; # ب≠9-.σ⒍𐹦≠
+xn--9--etd0100a.xn--4xa887mzpbzz04b; ب≠9-.σ⒍𐹦≠; [B3, B5, B6, V3, V6]; xn--9--etd0100a.xn--4xa887mzpbzz04b; ; ; # ب≠9-.σ⒍𐹦≠
+xn--9--etd0100a.xn--3xa097mzpbzz04b; ب≠9-.ς⒍𐹦≠; [B3, B5, B6, V3, V6]; xn--9--etd0100a.xn--3xa097mzpbzz04b; ; ; # ب≠9-.ς⒍𐹦≠
+򉛴.-ᡢ֒𝨠; ; [P1, V3, V6]; xn--ep37b.xn----hec165lho83b; ; ; # .-ᡢ֒𝨠
+xn--ep37b.xn----hec165lho83b; 򉛴.-ᡢ֒𝨠; [V3, V6]; xn--ep37b.xn----hec165lho83b; ; ; # .-ᡢ֒𝨠
+ۋ⒈ß󠄽。񷋍-; ۋ⒈ß.񷋍-; [B2, B3, B6, P1, V3, V6]; xn--zca541ato3a.xn----q001f; ; xn--ss-d7d6651a.xn----q001f; # ۋ⒈ß.-
+ۋ1.ß󠄽。񷋍-; ۋ1.ß.񷋍-; [B6, P1, V3, V6]; xn--1-cwc.xn--zca.xn----q001f; ; xn--1-cwc.ss.xn----q001f; # ۋ1.ß.-
+ۋ1.SS󠄽。񷋍-; ۋ1.ss.񷋍-; [B6, P1, V3, V6]; xn--1-cwc.ss.xn----q001f; ; ; # ۋ1.ss.-
+ۋ1.ss󠄽。񷋍-; ۋ1.ss.񷋍-; [B6, P1, V3, V6]; xn--1-cwc.ss.xn----q001f; ; ; # ۋ1.ss.-
+ۋ1.Ss󠄽。񷋍-; ۋ1.ss.񷋍-; [B6, P1, V3, V6]; xn--1-cwc.ss.xn----q001f; ; ; # ۋ1.ss.-
+xn--1-cwc.ss.xn----q001f; ۋ1.ss.񷋍-; [B6, V3, V6]; xn--1-cwc.ss.xn----q001f; ; ; # ۋ1.ss.-
+xn--1-cwc.xn--zca.xn----q001f; ۋ1.ß.񷋍-; [B6, V3, V6]; xn--1-cwc.xn--zca.xn----q001f; ; ; # ۋ1.ß.-
+ۋ⒈SS󠄽。񷋍-; ۋ⒈ss.񷋍-; [B2, B3, B6, P1, V3, V6]; xn--ss-d7d6651a.xn----q001f; ; ; # ۋ⒈ss.-
+ۋ⒈ss󠄽。񷋍-; ۋ⒈ss.񷋍-; [B2, B3, B6, P1, V3, V6]; xn--ss-d7d6651a.xn----q001f; ; ; # ۋ⒈ss.-
+ۋ⒈Ss󠄽。񷋍-; ۋ⒈ss.񷋍-; [B2, B3, B6, P1, V3, V6]; xn--ss-d7d6651a.xn----q001f; ; ; # ۋ⒈ss.-
+xn--ss-d7d6651a.xn----q001f; ۋ⒈ss.񷋍-; [B2, B3, B6, V3, V6]; xn--ss-d7d6651a.xn----q001f; ; ; # ۋ⒈ss.-
+xn--zca541ato3a.xn----q001f; ۋ⒈ß.񷋍-; [B2, B3, B6, V3, V6]; xn--zca541ato3a.xn----q001f; ; ; # ۋ⒈ß.-
+𿀫.᮪ςႦ‍; 𿀫.᮪ςႦ‍; [C2, P1, V5, V6]; xn--nu4s.xn--3xa417dxriome; ; xn--nu4s.xn--4xa217dxri; [P1, V5, V6] # .᮪ςႦ
+𿀫.᮪ςႦ‍; ; [C2, P1, V5, V6]; xn--nu4s.xn--3xa417dxriome; ; xn--nu4s.xn--4xa217dxri; [P1, V5, V6] # .᮪ςႦ
+𿀫.᮪ςⴆ‍; ; [C2, P1, V5, V6]; xn--nu4s.xn--3xa353jk8cs1q; ; xn--nu4s.xn--4xa153j7im; [P1, V5, V6] # .᮪ςⴆ
+𿀫.᮪ΣႦ‍; 𿀫.᮪σႦ‍; [C2, P1, V5, V6]; xn--nu4s.xn--4xa217dxriome; ; xn--nu4s.xn--4xa217dxri; [P1, V5, V6] # .᮪σႦ
+𿀫.᮪σⴆ‍; ; [C2, P1, V5, V6]; xn--nu4s.xn--4xa153jk8cs1q; ; xn--nu4s.xn--4xa153j7im; [P1, V5, V6] # .᮪σⴆ
+𿀫.᮪Σⴆ‍; 𿀫.᮪σⴆ‍; [C2, P1, V5, V6]; xn--nu4s.xn--4xa153jk8cs1q; ; xn--nu4s.xn--4xa153j7im; [P1, V5, V6] # .᮪σⴆ
+xn--nu4s.xn--4xa153j7im; 𿀫.᮪σⴆ; [V5, V6]; xn--nu4s.xn--4xa153j7im; ; ; # .᮪σⴆ
+xn--nu4s.xn--4xa153jk8cs1q; 𿀫.᮪σⴆ‍; [C2, V5, V6]; xn--nu4s.xn--4xa153jk8cs1q; ; ; # .᮪σⴆ
+xn--nu4s.xn--4xa217dxri; 𿀫.᮪σႦ; [V5, V6]; xn--nu4s.xn--4xa217dxri; ; ; # .᮪σႦ
+xn--nu4s.xn--4xa217dxriome; 𿀫.᮪σႦ‍; [C2, V5, V6]; xn--nu4s.xn--4xa217dxriome; ; ; # .᮪σႦ
+xn--nu4s.xn--3xa353jk8cs1q; 𿀫.᮪ςⴆ‍; [C2, V5, V6]; xn--nu4s.xn--3xa353jk8cs1q; ; ; # .᮪ςⴆ
+xn--nu4s.xn--3xa417dxriome; 𿀫.᮪ςႦ‍; [C2, V5, V6]; xn--nu4s.xn--3xa417dxriome; ; ; # .᮪ςႦ
+𿀫.᮪ςⴆ‍; 𿀫.᮪ςⴆ‍; [C2, P1, V5, V6]; xn--nu4s.xn--3xa353jk8cs1q; ; xn--nu4s.xn--4xa153j7im; [P1, V5, V6] # .᮪ςⴆ
+𿀫.᮪ΣႦ‍; 𿀫.᮪σႦ‍; [C2, P1, V5, V6]; xn--nu4s.xn--4xa217dxriome; ; xn--nu4s.xn--4xa217dxri; [P1, V5, V6] # .᮪σႦ
+𿀫.᮪σⴆ‍; 𿀫.᮪σⴆ‍; [C2, P1, V5, V6]; xn--nu4s.xn--4xa153jk8cs1q; ; xn--nu4s.xn--4xa153j7im; [P1, V5, V6] # .᮪σⴆ
+𿀫.᮪Σⴆ‍; 𿀫.᮪σⴆ‍; [C2, P1, V5, V6]; xn--nu4s.xn--4xa153jk8cs1q; ; xn--nu4s.xn--4xa153j7im; [P1, V5, V6] # .᮪σⴆ
+⾆࣢.𝈴; 舌࣢.𝈴; [B1, B5, B6, P1, V6]; xn--l0b9413d.xn--kl1h; ; ; # 舌.𝈴
+舌࣢.𝈴; ; [B1, B5, B6, P1, V6]; xn--l0b9413d.xn--kl1h; ; ; # 舌.𝈴
+xn--l0b9413d.xn--kl1h; 舌࣢.𝈴; [B1, B5, B6, V6]; xn--l0b9413d.xn--kl1h; ; ; # 舌.𝈴
+⫞𐹶𖫴。⭠⒈; ⫞𐹶𖫴.⭠⒈; [B1, P1, V6]; xn--53ix188et88b.xn--tsh52w; ; ; # ⫞𐹶𖫴.⭠⒈
+⫞𐹶𖫴。⭠1.; ⫞𐹶𖫴.⭠1.; [B1]; xn--53ix188et88b.xn--1-h6r.; ; ; # ⫞𐹶𖫴.⭠1.
+xn--53ix188et88b.xn--1-h6r.; ⫞𐹶𖫴.⭠1.; [B1]; xn--53ix188et88b.xn--1-h6r.; ; ; # ⫞𐹶𖫴.⭠1.
+xn--53ix188et88b.xn--tsh52w; ⫞𐹶𖫴.⭠⒈; [B1, V6]; xn--53ix188et88b.xn--tsh52w; ; ; # ⫞𐹶𖫴.⭠⒈
+⒈‌ꫬ︒.્; ⒈‌ꫬ︒.્; [C1, P1, V5, V6]; xn--0ug78o720myr1c.xn--mfc; ; xn--tsh0720cse8b.xn--mfc; [P1, V5, V6] # ⒈ꫬ︒.્
+1.‌ꫬ。.્; 1.‌ꫬ..્; [C1, V5, X4_2]; 1.xn--0ug7185c..xn--mfc; [C1, V5, A4_2]; 1.xn--sv9a..xn--mfc; [V5, A4_2] # 1.ꫬ..્
+1.xn--sv9a..xn--mfc; 1.ꫬ..્; [V5, X4_2]; 1.xn--sv9a..xn--mfc; [V5, A4_2]; ; # 1.ꫬ..્
+1.xn--0ug7185c..xn--mfc; 1.‌ꫬ..્; [C1, V5, X4_2]; 1.xn--0ug7185c..xn--mfc; [C1, V5, A4_2]; ; # 1.ꫬ..્
+xn--tsh0720cse8b.xn--mfc; ⒈ꫬ︒.્; [V5, V6]; xn--tsh0720cse8b.xn--mfc; ; ; # ⒈ꫬ︒.્
+xn--0ug78o720myr1c.xn--mfc; ⒈‌ꫬ︒.્; [C1, V5, V6]; xn--0ug78o720myr1c.xn--mfc; ; ; # ⒈ꫬ︒.્
+ె。䰀٨𞭅󠅼; ె.䰀٨𞭅; [B1, B3, B5, B6, P1, V5, V6]; xn--eqc.xn--hib5476aim6t; ; ; # ె.䰀٨
+xn--eqc.xn--hib5476aim6t; ె.䰀٨𞭅; [B1, B3, B5, B6, V5, V6]; xn--eqc.xn--hib5476aim6t; ; ; # ె.䰀٨
+ß‍.᯲񄾼; ; [C2, P1, V5, V6]; xn--zca870n.xn--0zf22107b; ; ss.xn--0zf22107b; [P1, V5, V6] # ß.᯲
+SS‍.᯲񄾼; ss‍.᯲񄾼; [C2, P1, V5, V6]; xn--ss-n1t.xn--0zf22107b; ; ss.xn--0zf22107b; [P1, V5, V6] # ss.᯲
+ss‍.᯲񄾼; ; [C2, P1, V5, V6]; xn--ss-n1t.xn--0zf22107b; ; ss.xn--0zf22107b; [P1, V5, V6] # ss.᯲
+Ss‍.᯲񄾼; ss‍.᯲񄾼; [C2, P1, V5, V6]; xn--ss-n1t.xn--0zf22107b; ; ss.xn--0zf22107b; [P1, V5, V6] # ss.᯲
+ss.xn--0zf22107b; ss.᯲񄾼; [V5, V6]; ss.xn--0zf22107b; ; ; # ss.᯲
+xn--ss-n1t.xn--0zf22107b; ss‍.᯲񄾼; [C2, V5, V6]; xn--ss-n1t.xn--0zf22107b; ; ; # ss.᯲
+xn--zca870n.xn--0zf22107b; ß‍.᯲񄾼; [C2, V5, V6]; xn--zca870n.xn--0zf22107b; ; ; # ß.᯲
+𑓂‌≮.≮; ; [P1, V5, V6]; xn--0ugy6glz29a.xn--gdh; ; xn--gdhz656g.xn--gdh; # 𑓂≮.≮
+𑓂‌≮.≮; 𑓂‌≮.≮; [P1, V5, V6]; xn--0ugy6glz29a.xn--gdh; ; xn--gdhz656g.xn--gdh; # 𑓂≮.≮
+xn--gdhz656g.xn--gdh; 𑓂≮.≮; [V5, V6]; xn--gdhz656g.xn--gdh; ; ; # 𑓂≮.≮
+xn--0ugy6glz29a.xn--gdh; 𑓂‌≮.≮; [V5, V6]; xn--0ugy6glz29a.xn--gdh; ; ; # 𑓂≮.≮
+🕼.ᅠ; 🕼.ᅠ; [P1, V6]; xn--my8h.xn--cl7c; ; ; # 🕼.
+🕼.ᅠ; ; [P1, V6]; xn--my8h.xn--psd; ; ; # 🕼.
+xn--my8h.xn--psd; 🕼.ᅠ; [V6]; xn--my8h.xn--psd; ; ; # 🕼.
+xn--my8h.xn--cl7c; 🕼.ᅠ; [V6]; xn--my8h.xn--cl7c; ; ; # 🕼.
+ᡔﶂ。񷘎; ᡔلحى.񷘎; [B5, B6, P1, V6]; xn--sgb9bq785p.xn--bc31b; ; ; # ᡔلحى.
+ᡔلحى。񷘎; ᡔلحى.񷘎; [B5, B6, P1, V6]; xn--sgb9bq785p.xn--bc31b; ; ; # ᡔلحى.
+xn--sgb9bq785p.xn--bc31b; ᡔلحى.񷘎; [B5, B6, V6]; xn--sgb9bq785p.xn--bc31b; ; ; # ᡔلحى.
+爕򳙑.𝟰気; 爕򳙑.4気; [P1, V6]; xn--1zxq3199c.xn--4-678b; ; ; # 爕.4気
+爕򳙑.4気; ; [P1, V6]; xn--1zxq3199c.xn--4-678b; ; ; # 爕.4気
+xn--1zxq3199c.xn--4-678b; 爕򳙑.4気; [V6]; xn--1zxq3199c.xn--4-678b; ; ; # 爕.4気
+⒋𑍍Ⴝ-.𞬪්ֵ; ⒋𑍍Ⴝ-.𞬪්ֵ; [B1, P1, V3, V6]; xn----t1g323mnk9t.xn--ddb152b7y23b; ; ; # ⒋𑍍Ⴝ-.්ֵ
+4.𑍍Ⴝ-.𞬪්ֵ; ; [B1, B6, P1, V3, V5, V6]; 4.xn----t1g9869q.xn--ddb152b7y23b; ; ; # 4.𑍍Ⴝ-.්ֵ
+4.𑍍ⴝ-.𞬪්ֵ; ; [B1, B6, P1, V3, V5, V6]; 4.xn----wwsx259f.xn--ddb152b7y23b; ; ; # 4.𑍍ⴝ-.්ֵ
+4.xn----wwsx259f.xn--ddb152b7y23b; 4.𑍍ⴝ-.𞬪්ֵ; [B1, B6, V3, V5, V6]; 4.xn----wwsx259f.xn--ddb152b7y23b; ; ; # 4.𑍍ⴝ-.්ֵ
+4.xn----t1g9869q.xn--ddb152b7y23b; 4.𑍍Ⴝ-.𞬪්ֵ; [B1, B6, V3, V5, V6]; 4.xn----t1g9869q.xn--ddb152b7y23b; ; ; # 4.𑍍Ⴝ-.්ֵ
+⒋𑍍ⴝ-.𞬪්ֵ; ⒋𑍍ⴝ-.𞬪්ֵ; [B1, P1, V3, V6]; xn----jcp487avl3w.xn--ddb152b7y23b; ; ; # ⒋𑍍ⴝ-.්ֵ
+xn----jcp487avl3w.xn--ddb152b7y23b; ⒋𑍍ⴝ-.𞬪්ֵ; [B1, V3, V6]; xn----jcp487avl3w.xn--ddb152b7y23b; ; ; # ⒋𑍍ⴝ-.්ֵ
+xn----t1g323mnk9t.xn--ddb152b7y23b; ⒋𑍍Ⴝ-.𞬪්ֵ; [B1, V3, V6]; xn----t1g323mnk9t.xn--ddb152b7y23b; ; ; # ⒋𑍍Ⴝ-.්ֵ
+󞝃。򑆃񉢗--; 󞝃.򑆃񉢗--; [P1, V2, V3, V6]; xn--2y75e.xn-----1l15eer88n; ; ; # .--
+xn--2y75e.xn-----1l15eer88n; 󞝃.򑆃񉢗--; [V2, V3, V6]; xn--2y75e.xn-----1l15eer88n; ; ; # .--
+‍ߟ。‌꯭; ‍ߟ.‌꯭; [B1, C1, C2]; xn--6sb394j.xn--0ug1126c; ; xn--6sb.xn--429a; [B1, B3, B6, V5] # ߟ.꯭
+‍ߟ。‌꯭; ‍ߟ.‌꯭; [B1, C1, C2]; xn--6sb394j.xn--0ug1126c; ; xn--6sb.xn--429a; [B1, B3, B6, V5] # ߟ.꯭
+xn--6sb.xn--429a; ߟ.꯭; [B1, B3, B6, V5]; xn--6sb.xn--429a; ; ; # ߟ.꯭
+xn--6sb394j.xn--0ug1126c; ‍ߟ.‌꯭; [B1, C1, C2]; xn--6sb394j.xn--0ug1126c; ; ; # ߟ.꯭
+𞮽߿ࡎ。ᢍ򝹁𐫘; 𞮽߿ࡎ.ᢍ򝹁𐫘; [B5, B6, P1, V6]; xn--3tb2nz468k.xn--69e8615j5rn5d; ; ; # ߿ࡎ.ᢍ𐫘
+𞮽߿ࡎ。ᢍ򝹁𐫘; 𞮽߿ࡎ.ᢍ򝹁𐫘; [B5, B6, P1, V6]; xn--3tb2nz468k.xn--69e8615j5rn5d; ; ; # ߿ࡎ.ᢍ𐫘
+xn--3tb2nz468k.xn--69e8615j5rn5d; 𞮽߿ࡎ.ᢍ򝹁𐫘; [B5, B6, V6]; xn--3tb2nz468k.xn--69e8615j5rn5d; ; ; # ߿ࡎ.ᢍ𐫘
+ۭ𞺌𑄚᜔.ꡞࢷ; ۭم𑄚᜔.ꡞࢷ; [B1, B5, B6, V5]; xn--hhb94ag41b739u.xn--dzb5582f; ; ; # ۭم𑄚᜔.ꡞࢷ
+ۭم𑄚᜔.ꡞࢷ; ; [B1, B5, B6, V5]; xn--hhb94ag41b739u.xn--dzb5582f; ; ; # ۭم𑄚᜔.ꡞࢷ
+xn--hhb94ag41b739u.xn--dzb5582f; ۭم𑄚᜔.ꡞࢷ; [B1, B5, B6, V5]; xn--hhb94ag41b739u.xn--dzb5582f; ; ; # ۭم𑄚᜔.ꡞࢷ
+񻂵킃𑘶ߜ。ςؼς; 񻂵킃𑘶ߜ.ςؼς; [B5, B6, P1, V6]; xn--3sb7483hoyvbbe76g.xn--3xaa51q; ; xn--3sb7483hoyvbbe76g.xn--4xaa21q; # 킃𑘶ߜ.ςؼς
+񻂵킃𑘶ߜ。ςؼς; 񻂵킃𑘶ߜ.ςؼς; [B5, B6, P1, V6]; xn--3sb7483hoyvbbe76g.xn--3xaa51q; ; xn--3sb7483hoyvbbe76g.xn--4xaa21q; # 킃𑘶ߜ.ςؼς
+񻂵킃𑘶ߜ。ςؼς; 񻂵킃𑘶ߜ.ςؼς; [B5, B6, P1, V6]; xn--3sb7483hoyvbbe76g.xn--3xaa51q; ; xn--3sb7483hoyvbbe76g.xn--4xaa21q; # 킃𑘶ߜ.ςؼς
+񻂵킃𑘶ߜ。ςؼς; 񻂵킃𑘶ߜ.ςؼς; [B5, B6, P1, V6]; xn--3sb7483hoyvbbe76g.xn--3xaa51q; ; xn--3sb7483hoyvbbe76g.xn--4xaa21q; # 킃𑘶ߜ.ςؼς
+񻂵킃𑘶ߜ。ΣؼΣ; 񻂵킃𑘶ߜ.σؼσ; [B5, B6, P1, V6]; xn--3sb7483hoyvbbe76g.xn--4xaa21q; ; ; # 킃𑘶ߜ.σؼσ
+񻂵킃𑘶ߜ。ΣؼΣ; 񻂵킃𑘶ߜ.σؼσ; [B5, B6, P1, V6]; xn--3sb7483hoyvbbe76g.xn--4xaa21q; ; ; # 킃𑘶ߜ.σؼσ
+񻂵킃𑘶ߜ。σؼσ; 񻂵킃𑘶ߜ.σؼσ; [B5, B6, P1, V6]; xn--3sb7483hoyvbbe76g.xn--4xaa21q; ; ; # 킃𑘶ߜ.σؼσ
+񻂵킃𑘶ߜ。σؼσ; 񻂵킃𑘶ߜ.σؼσ; [B5, B6, P1, V6]; xn--3sb7483hoyvbbe76g.xn--4xaa21q; ; ; # 킃𑘶ߜ.σؼσ
+񻂵킃𑘶ߜ。Σؼσ; 񻂵킃𑘶ߜ.σؼσ; [B5, B6, P1, V6]; xn--3sb7483hoyvbbe76g.xn--4xaa21q; ; ; # 킃𑘶ߜ.σؼσ
+񻂵킃𑘶ߜ。Σؼσ; 񻂵킃𑘶ߜ.σؼσ; [B5, B6, P1, V6]; xn--3sb7483hoyvbbe76g.xn--4xaa21q; ; ; # 킃𑘶ߜ.σؼσ
+xn--3sb7483hoyvbbe76g.xn--4xaa21q; 񻂵킃𑘶ߜ.σؼσ; [B5, B6, V6]; xn--3sb7483hoyvbbe76g.xn--4xaa21q; ; ; # 킃𑘶ߜ.σؼσ
+񻂵킃𑘶ߜ。Σؼς; 񻂵킃𑘶ߜ.σؼς; [B5, B6, P1, V6]; xn--3sb7483hoyvbbe76g.xn--3xab31q; ; xn--3sb7483hoyvbbe76g.xn--4xaa21q; # 킃𑘶ߜ.σؼς
+񻂵킃𑘶ߜ。Σؼς; 񻂵킃𑘶ߜ.σؼς; [B5, B6, P1, V6]; xn--3sb7483hoyvbbe76g.xn--3xab31q; ; xn--3sb7483hoyvbbe76g.xn--4xaa21q; # 킃𑘶ߜ.σؼς
+񻂵킃𑘶ߜ。σؼς; 񻂵킃𑘶ߜ.σؼς; [B5, B6, P1, V6]; xn--3sb7483hoyvbbe76g.xn--3xab31q; ; xn--3sb7483hoyvbbe76g.xn--4xaa21q; # 킃𑘶ߜ.σؼς
+񻂵킃𑘶ߜ。σؼς; 񻂵킃𑘶ߜ.σؼς; [B5, B6, P1, V6]; xn--3sb7483hoyvbbe76g.xn--3xab31q; ; xn--3sb7483hoyvbbe76g.xn--4xaa21q; # 킃𑘶ߜ.σؼς
+xn--3sb7483hoyvbbe76g.xn--3xab31q; 񻂵킃𑘶ߜ.σؼς; [B5, B6, V6]; xn--3sb7483hoyvbbe76g.xn--3xab31q; ; ; # 킃𑘶ߜ.σؼς
+xn--3sb7483hoyvbbe76g.xn--3xaa51q; 񻂵킃𑘶ߜ.ςؼς; [B5, B6, V6]; xn--3sb7483hoyvbbe76g.xn--3xaa51q; ; ; # 킃𑘶ߜ.ςؼς
+񻂵킃𑘶ߜ。ΣؼΣ; 񻂵킃𑘶ߜ.σؼσ; [B5, B6, P1, V6]; xn--3sb7483hoyvbbe76g.xn--4xaa21q; ; ; # 킃𑘶ߜ.σؼσ
+񻂵킃𑘶ߜ。ΣؼΣ; 񻂵킃𑘶ߜ.σؼσ; [B5, B6, P1, V6]; xn--3sb7483hoyvbbe76g.xn--4xaa21q; ; ; # 킃𑘶ߜ.σؼσ
+񻂵킃𑘶ߜ。σؼσ; 񻂵킃𑘶ߜ.σؼσ; [B5, B6, P1, V6]; xn--3sb7483hoyvbbe76g.xn--4xaa21q; ; ; # 킃𑘶ߜ.σؼσ
+񻂵킃𑘶ߜ。σؼσ; 񻂵킃𑘶ߜ.σؼσ; [B5, B6, P1, V6]; xn--3sb7483hoyvbbe76g.xn--4xaa21q; ; ; # 킃𑘶ߜ.σؼσ
+񻂵킃𑘶ߜ。Σؼσ; 񻂵킃𑘶ߜ.σؼσ; [B5, B6, P1, V6]; xn--3sb7483hoyvbbe76g.xn--4xaa21q; ; ; # 킃𑘶ߜ.σؼσ
+񻂵킃𑘶ߜ。Σؼσ; 񻂵킃𑘶ߜ.σؼσ; [B5, B6, P1, V6]; xn--3sb7483hoyvbbe76g.xn--4xaa21q; ; ; # 킃𑘶ߜ.σؼσ
+񻂵킃𑘶ߜ。Σؼς; 񻂵킃𑘶ߜ.σؼς; [B5, B6, P1, V6]; xn--3sb7483hoyvbbe76g.xn--3xab31q; ; xn--3sb7483hoyvbbe76g.xn--4xaa21q; # 킃𑘶ߜ.σؼς
+񻂵킃𑘶ߜ。Σؼς; 񻂵킃𑘶ߜ.σؼς; [B5, B6, P1, V6]; xn--3sb7483hoyvbbe76g.xn--3xab31q; ; xn--3sb7483hoyvbbe76g.xn--4xaa21q; # 킃𑘶ߜ.σؼς
+񻂵킃𑘶ߜ。σؼς; 񻂵킃𑘶ߜ.σؼς; [B5, B6, P1, V6]; xn--3sb7483hoyvbbe76g.xn--3xab31q; ; xn--3sb7483hoyvbbe76g.xn--4xaa21q; # 킃𑘶ߜ.σؼς
+񻂵킃𑘶ߜ。σؼς; 񻂵킃𑘶ߜ.σؼς; [B5, B6, P1, V6]; xn--3sb7483hoyvbbe76g.xn--3xab31q; ; xn--3sb7483hoyvbbe76g.xn--4xaa21q; # 킃𑘶ߜ.σؼς
+蔰。󠁹ࣝ-𑈵; 蔰.󠁹ࣝ-𑈵; [P1, V6]; xn--sz1a.xn----mrd9984r3dl0i; ; ; # 蔰.ࣝ-𑈵
+xn--sz1a.xn----mrd9984r3dl0i; 蔰.󠁹ࣝ-𑈵; [V6]; xn--sz1a.xn----mrd9984r3dl0i; ; ; # 蔰.ࣝ-𑈵
+ςჅ。ݚ; ςჅ.ݚ; [P1, V6]; xn--3xa677d.xn--epb; ; xn--4xa477d.xn--epb; # ςჅ.ݚ
+ςⴥ。ݚ; ςⴥ.ݚ; ; xn--3xa403s.xn--epb; ; xn--4xa203s.xn--epb; # ςⴥ.ݚ
+ΣჅ。ݚ; σჅ.ݚ; [P1, V6]; xn--4xa477d.xn--epb; ; ; # σჅ.ݚ
+σⴥ。ݚ; σⴥ.ݚ; ; xn--4xa203s.xn--epb; ; ; # σⴥ.ݚ
+Σⴥ。ݚ; σⴥ.ݚ; ; xn--4xa203s.xn--epb; ; ; # σⴥ.ݚ
+xn--4xa203s.xn--epb; σⴥ.ݚ; ; xn--4xa203s.xn--epb; ; ; # σⴥ.ݚ
+σⴥ.ݚ; ; ; xn--4xa203s.xn--epb; ; ; # σⴥ.ݚ
+ΣჅ.ݚ; σჅ.ݚ; [P1, V6]; xn--4xa477d.xn--epb; ; ; # σჅ.ݚ
+Σⴥ.ݚ; σⴥ.ݚ; ; xn--4xa203s.xn--epb; ; ; # σⴥ.ݚ
+xn--4xa477d.xn--epb; σჅ.ݚ; [V6]; xn--4xa477d.xn--epb; ; ; # σჅ.ݚ
+xn--3xa403s.xn--epb; ςⴥ.ݚ; ; xn--3xa403s.xn--epb; ; ; # ςⴥ.ݚ
+ςⴥ.ݚ; ; ; xn--3xa403s.xn--epb; ; xn--4xa203s.xn--epb; # ςⴥ.ݚ
+xn--3xa677d.xn--epb; ςჅ.ݚ; [V6]; xn--3xa677d.xn--epb; ; ; # ςჅ.ݚ
+్Ⴉ𞰓.᭲; ్Ⴉ𞰓.᭲; [B1, B3, B6, P1, V5, V6]; xn--lqc64t7t26c.xn--dwf; ; ; # ్Ⴉ.᭲
+్Ⴉ𞰓.᭲; ; [B1, B3, B6, P1, V5, V6]; xn--lqc64t7t26c.xn--dwf; ; ; # ్Ⴉ.᭲
+్ⴉ𞰓.᭲; ; [B1, B3, B6, P1, V5, V6]; xn--lqc478nlr02a.xn--dwf; ; ; # ్ⴉ.᭲
+xn--lqc478nlr02a.xn--dwf; ్ⴉ𞰓.᭲; [B1, B3, B6, V5, V6]; xn--lqc478nlr02a.xn--dwf; ; ; # ్ⴉ.᭲
+xn--lqc64t7t26c.xn--dwf; ్Ⴉ𞰓.᭲; [B1, B3, B6, V5, V6]; xn--lqc64t7t26c.xn--dwf; ; ; # ్Ⴉ.᭲
+్ⴉ𞰓.᭲; ్ⴉ𞰓.᭲; [B1, B3, B6, P1, V5, V6]; xn--lqc478nlr02a.xn--dwf; ; ; # ్ⴉ.᭲
+⮷≮񎈴󠄟。𐠄; ⮷≮񎈴.𐠄; [B1, P1, V6]; xn--gdh877a3513h.xn--pc9c; ; ; # ⮷≮.𐠄
+⮷≮񎈴󠄟。𐠄; ⮷≮񎈴.𐠄; [B1, P1, V6]; xn--gdh877a3513h.xn--pc9c; ; ; # ⮷≮.𐠄
+xn--gdh877a3513h.xn--pc9c; ⮷≮񎈴.𐠄; [B1, V6]; xn--gdh877a3513h.xn--pc9c; ; ; # ⮷≮.𐠄
+ڼ。‍ẏ‌ᡤ; ڼ.‍ẏ‌ᡤ; [B1, C1, C2]; xn--vkb.xn--08e172ax6aca; ; xn--vkb.xn--08e172a; [] # ڼ.ẏᡤ
+ڼ。‍ẏ‌ᡤ; ڼ.‍ẏ‌ᡤ; [B1, C1, C2]; xn--vkb.xn--08e172ax6aca; ; xn--vkb.xn--08e172a; [] # ڼ.ẏᡤ
+ڼ。‍ẏ‌ᡤ; ڼ.‍ẏ‌ᡤ; [B1, C1, C2]; xn--vkb.xn--08e172ax6aca; ; xn--vkb.xn--08e172a; [] # ڼ.ẏᡤ
+ڼ。‍ẏ‌ᡤ; ڼ.‍ẏ‌ᡤ; [B1, C1, C2]; xn--vkb.xn--08e172ax6aca; ; xn--vkb.xn--08e172a; [] # ڼ.ẏᡤ
+ڼ。‍Ẏ‌ᡤ; ڼ.‍ẏ‌ᡤ; [B1, C1, C2]; xn--vkb.xn--08e172ax6aca; ; xn--vkb.xn--08e172a; [] # ڼ.ẏᡤ
+ڼ。‍Ẏ‌ᡤ; ڼ.‍ẏ‌ᡤ; [B1, C1, C2]; xn--vkb.xn--08e172ax6aca; ; xn--vkb.xn--08e172a; [] # ڼ.ẏᡤ
+xn--vkb.xn--08e172a; ڼ.ẏᡤ; ; xn--vkb.xn--08e172a; ; ; # ڼ.ẏᡤ
+ڼ.ẏᡤ; ; ; xn--vkb.xn--08e172a; ; ; # ڼ.ẏᡤ
+ڼ.ẏᡤ; ڼ.ẏᡤ; ; xn--vkb.xn--08e172a; ; ; # ڼ.ẏᡤ
+ڼ.Ẏᡤ; ڼ.ẏᡤ; ; xn--vkb.xn--08e172a; ; ; # ڼ.ẏᡤ
+ڼ.Ẏᡤ; ڼ.ẏᡤ; ; xn--vkb.xn--08e172a; ; ; # ڼ.ẏᡤ
+xn--vkb.xn--08e172ax6aca; ڼ.‍ẏ‌ᡤ; [B1, C1, C2]; xn--vkb.xn--08e172ax6aca; ; ; # ڼ.ẏᡤ
+ڼ。‍Ẏ‌ᡤ; ڼ.‍ẏ‌ᡤ; [B1, C1, C2]; xn--vkb.xn--08e172ax6aca; ; xn--vkb.xn--08e172a; [] # ڼ.ẏᡤ
+ڼ。‍Ẏ‌ᡤ; ڼ.‍ẏ‌ᡤ; [B1, C1, C2]; xn--vkb.xn--08e172ax6aca; ; xn--vkb.xn--08e172a; [] # ڼ.ẏᡤ
+𐹹𑲛。񑂐්; 𐹹𑲛.񑂐්; [B1, P1, V6]; xn--xo0dg5v.xn--h1c39876d; ; ; # 𐹹𑲛.්
+xn--xo0dg5v.xn--h1c39876d; 𐹹𑲛.񑂐්; [B1, V6]; xn--xo0dg5v.xn--h1c39876d; ; ; # 𐹹𑲛.්
+-≠𑈵。嵕ﻱ۴꥓; -≠𑈵.嵕ي۴꥓; [B1, B5, P1, V3, V6]; xn----ufo4749h.xn--mhb45a235sns3c; ; ; # -≠𑈵.嵕ي۴꥓
+-≠𑈵。嵕ﻱ۴꥓; -≠𑈵.嵕ي۴꥓; [B1, B5, P1, V3, V6]; xn----ufo4749h.xn--mhb45a235sns3c; ; ; # -≠𑈵.嵕ي۴꥓
+-≠𑈵。嵕ي۴꥓; -≠𑈵.嵕ي۴꥓; [B1, B5, P1, V3, V6]; xn----ufo4749h.xn--mhb45a235sns3c; ; ; # -≠𑈵.嵕ي۴꥓
+-≠𑈵。嵕ي۴꥓; -≠𑈵.嵕ي۴꥓; [B1, B5, P1, V3, V6]; xn----ufo4749h.xn--mhb45a235sns3c; ; ; # -≠𑈵.嵕ي۴꥓
+xn----ufo4749h.xn--mhb45a235sns3c; -≠𑈵.嵕ي۴꥓; [B1, B5, V3, V6]; xn----ufo4749h.xn--mhb45a235sns3c; ; ; # -≠𑈵.嵕ي۴꥓
+‌񍸰𐹶ݮ.ہ‍≯‍; ‌񍸰𐹶ݮ.ہ‍≯‍; [B1, B3, C1, C2, P1, V6]; xn--ypb717jrx2o7v94a.xn--0kb660ka35v; ; xn--ypb5875khz9y.xn--0kb682l; [B3, B5, B6, P1, V6] # 𐹶ݮ.ہ≯
+‌񍸰𐹶ݮ.ہ‍≯‍; ‌񍸰𐹶ݮ.ہ‍≯‍; [B1, B3, C1, C2, P1, V6]; xn--ypb717jrx2o7v94a.xn--0kb660ka35v; ; xn--ypb5875khz9y.xn--0kb682l; [B3, B5, B6, P1, V6] # 𐹶ݮ.ہ≯
+‌񍸰𐹶ݮ.ہ‍≯‍; ; [B1, B3, C1, C2, P1, V6]; xn--ypb717jrx2o7v94a.xn--0kb660ka35v; ; xn--ypb5875khz9y.xn--0kb682l; [B3, B5, B6, P1, V6] # 𐹶ݮ.ہ≯
+‌񍸰𐹶ݮ.ہ‍≯‍; ‌񍸰𐹶ݮ.ہ‍≯‍; [B1, B3, C1, C2, P1, V6]; xn--ypb717jrx2o7v94a.xn--0kb660ka35v; ; xn--ypb5875khz9y.xn--0kb682l; [B3, B5, B6, P1, V6] # 𐹶ݮ.ہ≯
+xn--ypb5875khz9y.xn--0kb682l; 񍸰𐹶ݮ.ہ≯; [B3, B5, B6, V6]; xn--ypb5875khz9y.xn--0kb682l; ; ; # 𐹶ݮ.ہ≯
+xn--ypb717jrx2o7v94a.xn--0kb660ka35v; ‌񍸰𐹶ݮ.ہ‍≯‍; [B1, B3, C1, C2, V6]; xn--ypb717jrx2o7v94a.xn--0kb660ka35v; ; ; # 𐹶ݮ.ہ≯
+≮.឵ࡕ𐫔; ≮.឵ࡕ𐫔; [B1, P1, V5, V6]; xn--gdh.xn--kwb589e217p; ; ; # ≮.ࡕ𐫔
+≮.឵ࡕ𐫔; ≮.឵ࡕ𐫔; [B1, P1, V5, V6]; xn--gdh.xn--kwb589e217p; ; ; # ≮.ࡕ𐫔
+≮.឵ࡕ𐫔; ; [B1, P1, V5, V6]; xn--gdh.xn--kwb589e217p; ; ; # ≮.ࡕ𐫔
+≮.឵ࡕ𐫔; ≮.឵ࡕ𐫔; [B1, P1, V5, V6]; xn--gdh.xn--kwb589e217p; ; ; # ≮.ࡕ𐫔
+xn--gdh.xn--kwb589e217p; ≮.឵ࡕ𐫔; [B1, V5, V6]; xn--gdh.xn--kwb589e217p; ; ; # ≮.ࡕ𐫔
+𐩗‍。ႩႵ; 𐩗‍.ႩႵ; [B3, C2, P1, V6]; xn--1ug4933g.xn--hndy; ; xn--pt9c.xn--hndy; [P1, V6] # 𐩗.ႩႵ
+𐩗‍。ႩႵ; 𐩗‍.ႩႵ; [B3, C2, P1, V6]; xn--1ug4933g.xn--hndy; ; xn--pt9c.xn--hndy; [P1, V6] # 𐩗.ႩႵ
+𐩗‍。ⴉⴕ; 𐩗‍.ⴉⴕ; [B3, C2]; xn--1ug4933g.xn--0kjya; ; xn--pt9c.xn--0kjya; [] # 𐩗.ⴉⴕ
+𐩗‍。Ⴉⴕ; 𐩗‍.Ⴉⴕ; [B3, C2, P1, V6]; xn--1ug4933g.xn--hnd666l; ; xn--pt9c.xn--hnd666l; [P1, V6] # 𐩗.Ⴉⴕ
+xn--pt9c.xn--hnd666l; 𐩗.Ⴉⴕ; [V6]; xn--pt9c.xn--hnd666l; ; ; # 𐩗.Ⴉⴕ
+xn--1ug4933g.xn--hnd666l; 𐩗‍.Ⴉⴕ; [B3, C2, V6]; xn--1ug4933g.xn--hnd666l; ; ; # 𐩗.Ⴉⴕ
+xn--pt9c.xn--0kjya; 𐩗.ⴉⴕ; ; xn--pt9c.xn--0kjya; ; ; # 𐩗.ⴉⴕ
+𐩗.ⴉⴕ; ; ; xn--pt9c.xn--0kjya; ; ; # 𐩗.ⴉⴕ
+𐩗.ႩႵ; ; [P1, V6]; xn--pt9c.xn--hndy; ; ; # 𐩗.ႩႵ
+𐩗.Ⴉⴕ; ; [P1, V6]; xn--pt9c.xn--hnd666l; ; ; # 𐩗.Ⴉⴕ
+xn--pt9c.xn--hndy; 𐩗.ႩႵ; [V6]; xn--pt9c.xn--hndy; ; ; # 𐩗.ႩႵ
+xn--1ug4933g.xn--0kjya; 𐩗‍.ⴉⴕ; [B3, C2]; xn--1ug4933g.xn--0kjya; ; ; # 𐩗.ⴉⴕ
+xn--1ug4933g.xn--hndy; 𐩗‍.ႩႵ; [B3, C2, V6]; xn--1ug4933g.xn--hndy; ; ; # 𐩗.ႩႵ
+𐩗‍。ⴉⴕ; 𐩗‍.ⴉⴕ; [B3, C2]; xn--1ug4933g.xn--0kjya; ; xn--pt9c.xn--0kjya; [] # 𐩗.ⴉⴕ
+𐩗‍。Ⴉⴕ; 𐩗‍.Ⴉⴕ; [B3, C2, P1, V6]; xn--1ug4933g.xn--hnd666l; ; xn--pt9c.xn--hnd666l; [P1, V6] # 𐩗.Ⴉⴕ
+‌‌ㄤ.̮󕨑ূ; ‌‌ㄤ.̮󕨑ূ; [C1, P1, V5, V6]; xn--0uga242k.xn--vta284a9o563a; ; xn--1fk.xn--vta284a9o563a; [P1, V5, V6] # ㄤ.̮ূ
+‌‌ㄤ.̮󕨑ূ; ; [C1, P1, V5, V6]; xn--0uga242k.xn--vta284a9o563a; ; xn--1fk.xn--vta284a9o563a; [P1, V5, V6] # ㄤ.̮ূ
+xn--1fk.xn--vta284a9o563a; ㄤ.̮󕨑ূ; [V5, V6]; xn--1fk.xn--vta284a9o563a; ; ; # ㄤ.̮ূ
+xn--0uga242k.xn--vta284a9o563a; ‌‌ㄤ.̮󕨑ূ; [C1, V5, V6]; xn--0uga242k.xn--vta284a9o563a; ; ; # ㄤ.̮ূ
+𐋻。-‌𐫄Ⴗ; 𐋻.-‌𐫄Ⴗ; [B1, C1, P1, V3, V6]; xn--v97c.xn----i1g888ih12u; ; xn--v97c.xn----i1g2513q; [B1, P1, V3, V6] # 𐋻.-𐫄Ⴗ
+𐋻。-‌𐫄Ⴗ; 𐋻.-‌𐫄Ⴗ; [B1, C1, P1, V3, V6]; xn--v97c.xn----i1g888ih12u; ; xn--v97c.xn----i1g2513q; [B1, P1, V3, V6] # 𐋻.-𐫄Ⴗ
+𐋻。-‌𐫄ⴗ; 𐋻.-‌𐫄ⴗ; [B1, C1, V3]; xn--v97c.xn----sgnv20du99s; ; xn--v97c.xn----lws0526f; [B1, V3] # 𐋻.-𐫄ⴗ
+xn--v97c.xn----lws0526f; 𐋻.-𐫄ⴗ; [B1, V3]; xn--v97c.xn----lws0526f; ; ; # 𐋻.-𐫄ⴗ
+xn--v97c.xn----sgnv20du99s; 𐋻.-‌𐫄ⴗ; [B1, C1, V3]; xn--v97c.xn----sgnv20du99s; ; ; # 𐋻.-𐫄ⴗ
+xn--v97c.xn----i1g2513q; 𐋻.-𐫄Ⴗ; [B1, V3, V6]; xn--v97c.xn----i1g2513q; ; ; # 𐋻.-𐫄Ⴗ
+xn--v97c.xn----i1g888ih12u; 𐋻.-‌𐫄Ⴗ; [B1, C1, V3, V6]; xn--v97c.xn----i1g888ih12u; ; ; # 𐋻.-𐫄Ⴗ
+𐋻。-‌𐫄ⴗ; 𐋻.-‌𐫄ⴗ; [B1, C1, V3]; xn--v97c.xn----sgnv20du99s; ; xn--v97c.xn----lws0526f; [B1, V3] # 𐋻.-𐫄ⴗ
+🙑𐷺.≠‌; 🙑𐷺.≠‌; [B1, C1, P1, V6]; xn--bl0dh970b.xn--0ug83g; ; xn--bl0dh970b.xn--1ch; [B1, P1, V6] # 🙑.≠
+🙑𐷺.≠‌; 🙑𐷺.≠‌; [B1, C1, P1, V6]; xn--bl0dh970b.xn--0ug83g; ; xn--bl0dh970b.xn--1ch; [B1, P1, V6] # 🙑.≠
+🙑𐷺.≠‌; ; [B1, C1, P1, V6]; xn--bl0dh970b.xn--0ug83g; ; xn--bl0dh970b.xn--1ch; [B1, P1, V6] # 🙑.≠
+🙑𐷺.≠‌; 🙑𐷺.≠‌; [B1, C1, P1, V6]; xn--bl0dh970b.xn--0ug83g; ; xn--bl0dh970b.xn--1ch; [B1, P1, V6] # 🙑.≠
+xn--bl0dh970b.xn--1ch; 🙑𐷺.≠; [B1, V6]; xn--bl0dh970b.xn--1ch; ; ; # 🙑.≠
+xn--bl0dh970b.xn--0ug83g; 🙑𐷺.≠‌; [B1, C1, V6]; xn--bl0dh970b.xn--0ug83g; ; ; # 🙑.≠
+ٌ᳒。𞮞⵿⧎; ٌ᳒.𞮞⵿⧎; [B1, B3, B6, P1, V5, V6]; xn--ohb646i.xn--ewi38jf765c; ; ; # ٌ᳒.⵿⧎
+ٌ᳒。𞮞⵿⧎; ٌ᳒.𞮞⵿⧎; [B1, B3, B6, P1, V5, V6]; xn--ohb646i.xn--ewi38jf765c; ; ; # ٌ᳒.⵿⧎
+xn--ohb646i.xn--ewi38jf765c; ٌ᳒.𞮞⵿⧎; [B1, B3, B6, V5, V6]; xn--ohb646i.xn--ewi38jf765c; ; ; # ٌ᳒.⵿⧎
+Ⴔ𝨨₃󠁦.𝟳𑂹ஂ; Ⴔ𝨨3󠁦.7𑂹ஂ; [P1, V6]; xn--3-b1g83426a35t0g.xn--7-cve6271r; ; ; # Ⴔ𝨨3.7𑂹ஂ
+Ⴔ𝨨3󠁦.7𑂹ஂ; ; [P1, V6]; xn--3-b1g83426a35t0g.xn--7-cve6271r; ; ; # Ⴔ𝨨3.7𑂹ஂ
+ⴔ𝨨3󠁦.7𑂹ஂ; ; [P1, V6]; xn--3-ews6985n35s3g.xn--7-cve6271r; ; ; # ⴔ𝨨3.7𑂹ஂ
+xn--3-ews6985n35s3g.xn--7-cve6271r; ⴔ𝨨3󠁦.7𑂹ஂ; [V6]; xn--3-ews6985n35s3g.xn--7-cve6271r; ; ; # ⴔ𝨨3.7𑂹ஂ
+xn--3-b1g83426a35t0g.xn--7-cve6271r; Ⴔ𝨨3󠁦.7𑂹ஂ; [V6]; xn--3-b1g83426a35t0g.xn--7-cve6271r; ; ; # Ⴔ𝨨3.7𑂹ஂ
+ⴔ𝨨₃󠁦.𝟳𑂹ஂ; ⴔ𝨨3󠁦.7𑂹ஂ; [P1, V6]; xn--3-ews6985n35s3g.xn--7-cve6271r; ; ; # ⴔ𝨨3.7𑂹ஂ
+䏈‌。‌⒈񱢕; 䏈‌.‌⒈񱢕; [C1, P1, V6]; xn--0ug491l.xn--0ug88oot66q; ; xn--eco.xn--tsh21126d; [P1, V6] # 䏈.⒈
+䏈‌。‌1.񱢕; 䏈‌.‌1.񱢕; [C1, P1, V6]; xn--0ug491l.xn--1-rgn.xn--ms39a; ; xn--eco.1.xn--ms39a; [P1, V6] # 䏈.1.
+xn--eco.1.xn--ms39a; 䏈.1.񱢕; [V6]; xn--eco.1.xn--ms39a; ; ; # 䏈.1.
+xn--0ug491l.xn--1-rgn.xn--ms39a; 䏈‌.‌1.񱢕; [C1, V6]; xn--0ug491l.xn--1-rgn.xn--ms39a; ; ; # 䏈.1.
+xn--eco.xn--tsh21126d; 䏈.⒈񱢕; [V6]; xn--eco.xn--tsh21126d; ; ; # 䏈.⒈
+xn--0ug491l.xn--0ug88oot66q; 䏈‌.‌⒈񱢕; [C1, V6]; xn--0ug491l.xn--0ug88oot66q; ; ; # 䏈.⒈
+1꫶ß𑲥。ᷘ; 1꫶ß𑲥.ᷘ; [V5]; xn--1-qfa2471kdb0d.xn--weg; ; xn--1ss-ir6ln166b.xn--weg; # 1꫶ß𑲥.ᷘ
+1꫶ß𑲥。ᷘ; 1꫶ß𑲥.ᷘ; [V5]; xn--1-qfa2471kdb0d.xn--weg; ; xn--1ss-ir6ln166b.xn--weg; # 1꫶ß𑲥.ᷘ
+1꫶SS𑲥。ᷘ; 1꫶ss𑲥.ᷘ; [V5]; xn--1ss-ir6ln166b.xn--weg; ; ; # 1꫶ss𑲥.ᷘ
+1꫶ss𑲥。ᷘ; 1꫶ss𑲥.ᷘ; [V5]; xn--1ss-ir6ln166b.xn--weg; ; ; # 1꫶ss𑲥.ᷘ
+xn--1ss-ir6ln166b.xn--weg; 1꫶ss𑲥.ᷘ; [V5]; xn--1ss-ir6ln166b.xn--weg; ; ; # 1꫶ss𑲥.ᷘ
+xn--1-qfa2471kdb0d.xn--weg; 1꫶ß𑲥.ᷘ; [V5]; xn--1-qfa2471kdb0d.xn--weg; ; ; # 1꫶ß𑲥.ᷘ
+1꫶SS𑲥。ᷘ; 1꫶ss𑲥.ᷘ; [V5]; xn--1ss-ir6ln166b.xn--weg; ; ; # 1꫶ss𑲥.ᷘ
+1꫶ss𑲥。ᷘ; 1꫶ss𑲥.ᷘ; [V5]; xn--1ss-ir6ln166b.xn--weg; ; ; # 1꫶ss𑲥.ᷘ
+1꫶Ss𑲥。ᷘ; 1꫶ss𑲥.ᷘ; [V5]; xn--1ss-ir6ln166b.xn--weg; ; ; # 1꫶ss𑲥.ᷘ
+1꫶Ss𑲥。ᷘ; 1꫶ss𑲥.ᷘ; [V5]; xn--1ss-ir6ln166b.xn--weg; ; ; # 1꫶ss𑲥.ᷘ
+‍񫶩𞪯್。ݼ⒈; ‍񫶩𞪯್.ݼ⒈; [B1, C2, P1, V6]; xn--8tc969gzn94a4lm8a.xn--dqb689l; ; xn--8tc9875v5is1a.xn--dqb689l; [B5, B6, P1, V6] # ್.ݼ⒈
+‍񫶩𞪯್。ݼ1.; ‍񫶩𞪯್.ݼ1.; [B1, C2, P1, V6]; xn--8tc969gzn94a4lm8a.xn--1-g6c.; ; xn--8tc9875v5is1a.xn--1-g6c.; [B5, B6, P1, V6] # ್.ݼ1.
+xn--8tc9875v5is1a.xn--1-g6c.; 񫶩𞪯್.ݼ1.; [B5, B6, V6]; xn--8tc9875v5is1a.xn--1-g6c.; ; ; # ್.ݼ1.
+xn--8tc969gzn94a4lm8a.xn--1-g6c.; ‍񫶩𞪯್.ݼ1.; [B1, C2, V6]; xn--8tc969gzn94a4lm8a.xn--1-g6c.; ; ; # ್.ݼ1.
+xn--8tc9875v5is1a.xn--dqb689l; 񫶩𞪯್.ݼ⒈; [B5, B6, V6]; xn--8tc9875v5is1a.xn--dqb689l; ; ; # ್.ݼ⒈
+xn--8tc969gzn94a4lm8a.xn--dqb689l; ‍񫶩𞪯್.ݼ⒈; [B1, C2, V6]; xn--8tc969gzn94a4lm8a.xn--dqb689l; ; ; # ್.ݼ⒈
+᪶.𞤳򓢖򻉒ߗ; ᪶.𞤳򓢖򻉒ߗ; [B1, B2, B3, B6, P1, V5, V6]; xn--zqf.xn--ysb9657vuiz5bj0ep; ; ; # ᪶.𞤳ߗ
+᪶.𞤳򓢖򻉒ߗ; ; [B1, B2, B3, B6, P1, V5, V6]; xn--zqf.xn--ysb9657vuiz5bj0ep; ; ; # ᪶.𞤳ߗ
+᪶.𞤑򓢖򻉒ߗ; ᪶.𞤳򓢖򻉒ߗ; [B1, B2, B3, B6, P1, V5, V6]; xn--zqf.xn--ysb9657vuiz5bj0ep; ; ; # ᪶.𞤳ߗ
+xn--zqf.xn--ysb9657vuiz5bj0ep; ᪶.𞤳򓢖򻉒ߗ; [B1, B2, B3, B6, V5, V6]; xn--zqf.xn--ysb9657vuiz5bj0ep; ; ; # ᪶.𞤳ߗ
+᪶.𞤑򓢖򻉒ߗ; ᪶.𞤳򓢖򻉒ߗ; [B1, B2, B3, B6, P1, V5, V6]; xn--zqf.xn--ysb9657vuiz5bj0ep; ; ; # ᪶.𞤳ߗ
+ࡂ𞩚⒈.󠬌8򏳏ݰ; ࡂ𞩚⒈.󠬌8򏳏ݰ; [B1, P1, V6]; xn--0vb095ldg52a.xn--8-s5c22427ox454a; ; ; # ࡂ⒈.8ݰ
+ࡂ𞩚1..󠬌8򏳏ݰ; ; [B1, P1, V6, X4_2]; xn--1-rid26318a..xn--8-s5c22427ox454a; [B1, P1, V6, A4_2]; ; # ࡂ1..8ݰ
+xn--1-rid26318a..xn--8-s5c22427ox454a; ࡂ𞩚1..󠬌8򏳏ݰ; [B1, V6, X4_2]; xn--1-rid26318a..xn--8-s5c22427ox454a; [B1, V6, A4_2]; ; # ࡂ1..8ݰ
+xn--0vb095ldg52a.xn--8-s5c22427ox454a; ࡂ𞩚⒈.󠬌8򏳏ݰ; [B1, V6]; xn--0vb095ldg52a.xn--8-s5c22427ox454a; ; ; # ࡂ⒈.8ݰ
+͡𐫫ͩᡷ。-󠰛鞰; ͡𐫫ͩᡷ.-󠰛鞰; [B1, P1, V3, V5, V6]; xn--cvaq482npv5t.xn----yg7dt1332g; ; ; # ͡𐫫ͩᡷ.-鞰
+xn--cvaq482npv5t.xn----yg7dt1332g; ͡𐫫ͩᡷ.-󠰛鞰; [B1, V3, V5, V6]; xn--cvaq482npv5t.xn----yg7dt1332g; ; ; # ͡𐫫ͩᡷ.-鞰
+-.્剘ß𐫃; ; [B1, V3, V5]; -.xn--zca791c493duf8i; ; -.xn--ss-bqg4734erywk; # -.્剘ß𐫃
+-.્剘SS𐫃; -.્剘ss𐫃; [B1, V3, V5]; -.xn--ss-bqg4734erywk; ; ; # -.્剘ss𐫃
+-.્剘ss𐫃; ; [B1, V3, V5]; -.xn--ss-bqg4734erywk; ; ; # -.્剘ss𐫃
+-.્剘Ss𐫃; -.્剘ss𐫃; [B1, V3, V5]; -.xn--ss-bqg4734erywk; ; ; # -.્剘ss𐫃
+-.xn--ss-bqg4734erywk; -.્剘ss𐫃; [B1, V3, V5]; -.xn--ss-bqg4734erywk; ; ; # -.્剘ss𐫃
+-.xn--zca791c493duf8i; -.્剘ß𐫃; [B1, V3, V5]; -.xn--zca791c493duf8i; ; ; # -.્剘ß𐫃
+ࣻ𞵸。-; ࣻ𞵸.-; [B1, P1, V3, V5, V6]; xn--b1b2719v.-; ; ; # ࣻ.-
+ࣻ𞵸。-; ࣻ𞵸.-; [B1, P1, V3, V5, V6]; xn--b1b2719v.-; ; ; # ࣻ.-
+xn--b1b2719v.-; ࣻ𞵸.-; [B1, V3, V5, V6]; xn--b1b2719v.-; ; ; # ࣻ.-
+⒈󠈻𐹲。≠؃𐹽; ⒈󠈻𐹲.≠؃𐹽; [B1, P1, V6]; xn--tshw766f1153g.xn--lfb536lb35n; ; ; # ⒈𐹲.≠𐹽
+⒈󠈻𐹲。≠؃𐹽; ⒈󠈻𐹲.≠؃𐹽; [B1, P1, V6]; xn--tshw766f1153g.xn--lfb536lb35n; ; ; # ⒈𐹲.≠𐹽
+1.󠈻𐹲。≠؃𐹽; 1.󠈻𐹲.≠؃𐹽; [B1, P1, V6]; 1.xn--qo0dl3077c.xn--lfb536lb35n; ; ; # 1.𐹲.≠𐹽
+1.󠈻𐹲。≠؃𐹽; 1.󠈻𐹲.≠؃𐹽; [B1, P1, V6]; 1.xn--qo0dl3077c.xn--lfb536lb35n; ; ; # 1.𐹲.≠𐹽
+1.xn--qo0dl3077c.xn--lfb536lb35n; 1.󠈻𐹲.≠؃𐹽; [B1, V6]; 1.xn--qo0dl3077c.xn--lfb536lb35n; ; ; # 1.𐹲.≠𐹽
+xn--tshw766f1153g.xn--lfb536lb35n; ⒈󠈻𐹲.≠؃𐹽; [B1, V6]; xn--tshw766f1153g.xn--lfb536lb35n; ; ; # ⒈𐹲.≠𐹽
+𐹢󠈚Ⴎ‌.㖾𐹡; ; [B1, B5, B6, C1, P1, V6]; xn--mnd289ezj4pqxp0i.xn--pelu572d; ; xn--mnd9001km0o0g.xn--pelu572d; [B1, B5, B6, P1, V6] # 𐹢Ⴎ.㖾𐹡
+𐹢󠈚ⴎ‌.㖾𐹡; ; [B1, B5, B6, C1, P1, V6]; xn--0ug342clq0pqxv4i.xn--pelu572d; ; xn--5kjx323em053g.xn--pelu572d; [B1, B5, B6, P1, V6] # 𐹢ⴎ.㖾𐹡
+xn--5kjx323em053g.xn--pelu572d; 𐹢󠈚ⴎ.㖾𐹡; [B1, B5, B6, V6]; xn--5kjx323em053g.xn--pelu572d; ; ; # 𐹢ⴎ.㖾𐹡
+xn--0ug342clq0pqxv4i.xn--pelu572d; 𐹢󠈚ⴎ‌.㖾𐹡; [B1, B5, B6, C1, V6]; xn--0ug342clq0pqxv4i.xn--pelu572d; ; ; # 𐹢ⴎ.㖾𐹡
+xn--mnd9001km0o0g.xn--pelu572d; 𐹢󠈚Ⴎ.㖾𐹡; [B1, B5, B6, V6]; xn--mnd9001km0o0g.xn--pelu572d; ; ; # 𐹢Ⴎ.㖾𐹡
+xn--mnd289ezj4pqxp0i.xn--pelu572d; 𐹢󠈚Ⴎ‌.㖾𐹡; [B1, B5, B6, C1, V6]; xn--mnd289ezj4pqxp0i.xn--pelu572d; ; ; # 𐹢Ⴎ.㖾𐹡
+򩼗.߇ᡖႳႧ; 򩼗.߇ᡖႳႧ; [B2, B3, P1, V6]; xn--te28c.xn--isb856b9a631d; ; ; # .߇ᡖႳႧ
+򩼗.߇ᡖႳႧ; ; [B2, B3, P1, V6]; xn--te28c.xn--isb856b9a631d; ; ; # .߇ᡖႳႧ
+򩼗.߇ᡖⴓⴇ; ; [B2, B3, P1, V6]; xn--te28c.xn--isb295fbtpmb; ; ; # .߇ᡖⴓⴇ
+xn--te28c.xn--isb295fbtpmb; 򩼗.߇ᡖⴓⴇ; [B2, B3, V6]; xn--te28c.xn--isb295fbtpmb; ; ; # .߇ᡖⴓⴇ
+xn--te28c.xn--isb856b9a631d; 򩼗.߇ᡖႳႧ; [B2, B3, V6]; xn--te28c.xn--isb856b9a631d; ; ; # .߇ᡖႳႧ
+򩼗.߇ᡖⴓⴇ; 򩼗.߇ᡖⴓⴇ; [B2, B3, P1, V6]; xn--te28c.xn--isb295fbtpmb; ; ; # .߇ᡖⴓⴇ
+򩼗.߇ᡖႳⴇ; ; [B2, B3, P1, V6]; xn--te28c.xn--isb286btrgo7w; ; ; # .߇ᡖႳⴇ
+xn--te28c.xn--isb286btrgo7w; 򩼗.߇ᡖႳⴇ; [B2, B3, V6]; xn--te28c.xn--isb286btrgo7w; ; ; # .߇ᡖႳⴇ
+򩼗.߇ᡖႳⴇ; 򩼗.߇ᡖႳⴇ; [B2, B3, P1, V6]; xn--te28c.xn--isb286btrgo7w; ; ; # .߇ᡖႳⴇ
+‍􅍉.ڳݵ; ; [B1, C2, P1, V6]; xn--1ug39444n.xn--mkb20b; ; xn--3j78f.xn--mkb20b; [P1, V6] # .ڳݵ
+xn--3j78f.xn--mkb20b; 􅍉.ڳݵ; [V6]; xn--3j78f.xn--mkb20b; ; ; # .ڳݵ
+xn--1ug39444n.xn--mkb20b; ‍􅍉.ڳݵ; [B1, C2, V6]; xn--1ug39444n.xn--mkb20b; ; ; # .ڳݵ
+𲤱⒛⾳.ꡦ⒈; 𲤱⒛音.ꡦ⒈; [P1, V6]; xn--dth6033bzbvx.xn--tsh9439b; ; ; # ⒛音.ꡦ⒈
+𲤱20.音.ꡦ1.; ; [P1, V6]; xn--20-9802c.xn--0w5a.xn--1-eg4e.; ; ; # 20.音.ꡦ1.
+xn--20-9802c.xn--0w5a.xn--1-eg4e.; 𲤱20.音.ꡦ1.; [V6]; xn--20-9802c.xn--0w5a.xn--1-eg4e.; ; ; # 20.音.ꡦ1.
+xn--dth6033bzbvx.xn--tsh9439b; 𲤱⒛音.ꡦ⒈; [V6]; xn--dth6033bzbvx.xn--tsh9439b; ; ; # ⒛音.ꡦ⒈
+ߜ8񳦓-。򞲙𑁿𐩥্; ߜ8񳦓-.򞲙𑁿𐩥্; [B2, B3, B5, B6, P1, V3, V6]; xn--8--rve13079p.xn--b7b9842k42df776x; ; ; # ߜ8-.𑁿𐩥্
+ߜ8񳦓-。򞲙𑁿𐩥্; ߜ8񳦓-.򞲙𑁿𐩥্; [B2, B3, B5, B6, P1, V3, V6]; xn--8--rve13079p.xn--b7b9842k42df776x; ; ; # ߜ8-.𑁿𐩥্
+xn--8--rve13079p.xn--b7b9842k42df776x; ߜ8񳦓-.򞲙𑁿𐩥্; [B2, B3, B5, B6, V3, V6]; xn--8--rve13079p.xn--b7b9842k42df776x; ; ; # ߜ8-.𑁿𐩥্
+Ⴕ。۰≮ß݅; Ⴕ.۰≮ß݅; [P1, V6]; xn--tnd.xn--zca912alh227g; ; xn--tnd.xn--ss-jbe65aw27i; # Ⴕ.۰≮ß݅
+Ⴕ。۰≮ß݅; Ⴕ.۰≮ß݅; [P1, V6]; xn--tnd.xn--zca912alh227g; ; xn--tnd.xn--ss-jbe65aw27i; # Ⴕ.۰≮ß݅
+ⴕ。۰≮ß݅; ⴕ.۰≮ß݅; [P1, V6]; xn--dlj.xn--zca912alh227g; ; xn--dlj.xn--ss-jbe65aw27i; # ⴕ.۰≮ß݅
+ⴕ。۰≮ß݅; ⴕ.۰≮ß݅; [P1, V6]; xn--dlj.xn--zca912alh227g; ; xn--dlj.xn--ss-jbe65aw27i; # ⴕ.۰≮ß݅
+Ⴕ。۰≮SS݅; Ⴕ.۰≮ss݅; [P1, V6]; xn--tnd.xn--ss-jbe65aw27i; ; ; # Ⴕ.۰≮ss݅
+Ⴕ。۰≮SS݅; Ⴕ.۰≮ss݅; [P1, V6]; xn--tnd.xn--ss-jbe65aw27i; ; ; # Ⴕ.۰≮ss݅
+ⴕ。۰≮ss݅; ⴕ.۰≮ss݅; [P1, V6]; xn--dlj.xn--ss-jbe65aw27i; ; ; # ⴕ.۰≮ss݅
+ⴕ。۰≮ss݅; ⴕ.۰≮ss݅; [P1, V6]; xn--dlj.xn--ss-jbe65aw27i; ; ; # ⴕ.۰≮ss݅
+Ⴕ。۰≮Ss݅; Ⴕ.۰≮ss݅; [P1, V6]; xn--tnd.xn--ss-jbe65aw27i; ; ; # Ⴕ.۰≮ss݅
+Ⴕ。۰≮Ss݅; Ⴕ.۰≮ss݅; [P1, V6]; xn--tnd.xn--ss-jbe65aw27i; ; ; # Ⴕ.۰≮ss݅
+xn--tnd.xn--ss-jbe65aw27i; Ⴕ.۰≮ss݅; [V6]; xn--tnd.xn--ss-jbe65aw27i; ; ; # Ⴕ.۰≮ss݅
+xn--dlj.xn--ss-jbe65aw27i; ⴕ.۰≮ss݅; [V6]; xn--dlj.xn--ss-jbe65aw27i; ; ; # ⴕ.۰≮ss݅
+xn--dlj.xn--zca912alh227g; ⴕ.۰≮ß݅; [V6]; xn--dlj.xn--zca912alh227g; ; ; # ⴕ.۰≮ß݅
+xn--tnd.xn--zca912alh227g; Ⴕ.۰≮ß݅; [V6]; xn--tnd.xn--zca912alh227g; ; ; # Ⴕ.۰≮ß݅
+ߩ-.𝨗꒱᭲; ; [B1, B3, V3, V5]; xn----odd.xn--dwf8994dc8wj; ; ; # ߩ-.𝨗꒱᭲
+xn----odd.xn--dwf8994dc8wj; ߩ-.𝨗꒱᭲; [B1, B3, V3, V5]; xn----odd.xn--dwf8994dc8wj; ; ; # ߩ-.𝨗꒱᭲
+𞼸‌.≯䕵⫧; ; [B1, B3, C1, P1, V6]; xn--0ugx453p.xn--hdh754ax6w; ; xn--sn7h.xn--hdh754ax6w; [B1, P1, V6] # .≯䕵⫧
+𞼸‌.≯䕵⫧; 𞼸‌.≯䕵⫧; [B1, B3, C1, P1, V6]; xn--0ugx453p.xn--hdh754ax6w; ; xn--sn7h.xn--hdh754ax6w; [B1, P1, V6] # .≯䕵⫧
+xn--sn7h.xn--hdh754ax6w; 𞼸.≯䕵⫧; [B1, V6]; xn--sn7h.xn--hdh754ax6w; ; ; # .≯䕵⫧
+xn--0ugx453p.xn--hdh754ax6w; 𞼸‌.≯䕵⫧; [B1, B3, C1, V6]; xn--0ugx453p.xn--hdh754ax6w; ; ; # .≯䕵⫧
+𐨅ßﱗ.ڬ۳︒; 𐨅ßيخ.ڬ۳︒; [B1, B3, P1, V5, V6]; xn--zca23yncs877j.xn--fkb6lp314e; ; xn--ss-ytd5i7765l.xn--fkb6lp314e; # 𐨅ßيخ.ڬ۳︒
+𐨅ßيخ.ڬ۳。; 𐨅ßيخ.ڬ۳.; [B1, V5]; xn--zca23yncs877j.xn--fkb6l.; ; xn--ss-ytd5i7765l.xn--fkb6l.; # 𐨅ßيخ.ڬ۳.
+𐨅SSيخ.ڬ۳。; 𐨅ssيخ.ڬ۳.; [B1, V5]; xn--ss-ytd5i7765l.xn--fkb6l.; ; ; # 𐨅ssيخ.ڬ۳.
+𐨅ssيخ.ڬ۳。; 𐨅ssيخ.ڬ۳.; [B1, V5]; xn--ss-ytd5i7765l.xn--fkb6l.; ; ; # 𐨅ssيخ.ڬ۳.
+𐨅Ssيخ.ڬ۳。; 𐨅ssيخ.ڬ۳.; [B1, V5]; xn--ss-ytd5i7765l.xn--fkb6l.; ; ; # 𐨅ssيخ.ڬ۳.
+xn--ss-ytd5i7765l.xn--fkb6l.; 𐨅ssيخ.ڬ۳.; [B1, V5]; xn--ss-ytd5i7765l.xn--fkb6l.; ; ; # 𐨅ssيخ.ڬ۳.
+xn--zca23yncs877j.xn--fkb6l.; 𐨅ßيخ.ڬ۳.; [B1, V5]; xn--zca23yncs877j.xn--fkb6l.; ; ; # 𐨅ßيخ.ڬ۳.
+𐨅SSﱗ.ڬ۳︒; 𐨅ssيخ.ڬ۳︒; [B1, B3, P1, V5, V6]; xn--ss-ytd5i7765l.xn--fkb6lp314e; ; ; # 𐨅ssيخ.ڬ۳︒
+𐨅ssﱗ.ڬ۳︒; 𐨅ssيخ.ڬ۳︒; [B1, B3, P1, V5, V6]; xn--ss-ytd5i7765l.xn--fkb6lp314e; ; ; # 𐨅ssيخ.ڬ۳︒
+𐨅Ssﱗ.ڬ۳︒; 𐨅ssيخ.ڬ۳︒; [B1, B3, P1, V5, V6]; xn--ss-ytd5i7765l.xn--fkb6lp314e; ; ; # 𐨅ssيخ.ڬ۳︒
+xn--ss-ytd5i7765l.xn--fkb6lp314e; 𐨅ssيخ.ڬ۳︒; [B1, B3, V5, V6]; xn--ss-ytd5i7765l.xn--fkb6lp314e; ; ; # 𐨅ssيخ.ڬ۳︒
+xn--zca23yncs877j.xn--fkb6lp314e; 𐨅ßيخ.ڬ۳︒; [B1, B3, V5, V6]; xn--zca23yncs877j.xn--fkb6lp314e; ; ; # 𐨅ßيخ.ڬ۳︒
+-≮🡒᳭.񏿾Ⴁܔ; ; [B1, P1, V3, V6]; xn----44l04zxt68c.xn--enb300c1597h; ; ; # -≮🡒᳭.Ⴁܔ
+-≮🡒᳭.񏿾Ⴁܔ; -≮🡒᳭.񏿾Ⴁܔ; [B1, P1, V3, V6]; xn----44l04zxt68c.xn--enb300c1597h; ; ; # -≮🡒᳭.Ⴁܔ
+-≮🡒᳭.񏿾ⴁܔ; -≮🡒᳭.񏿾ⴁܔ; [B1, P1, V3, V6]; xn----44l04zxt68c.xn--enb135qf106f; ; ; # -≮🡒᳭.ⴁܔ
+-≮🡒᳭.񏿾ⴁܔ; ; [B1, P1, V3, V6]; xn----44l04zxt68c.xn--enb135qf106f; ; ; # -≮🡒᳭.ⴁܔ
+xn----44l04zxt68c.xn--enb135qf106f; -≮🡒᳭.񏿾ⴁܔ; [B1, V3, V6]; xn----44l04zxt68c.xn--enb135qf106f; ; ; # -≮🡒᳭.ⴁܔ
+xn----44l04zxt68c.xn--enb300c1597h; -≮🡒᳭.񏿾Ⴁܔ; [B1, V3, V6]; xn----44l04zxt68c.xn--enb300c1597h; ; ; # -≮🡒᳭.Ⴁܔ
+𞤨。ꡏ‍‌; 𞤨.ꡏ‍‌; [B6, C1, C2]; xn--ge6h.xn--0ugb9575h; ; xn--ge6h.xn--oc9a; [] # 𞤨.ꡏ
+𞤨。ꡏ‍‌; 𞤨.ꡏ‍‌; [B6, C1, C2]; xn--ge6h.xn--0ugb9575h; ; xn--ge6h.xn--oc9a; [] # 𞤨.ꡏ
+𞤆。ꡏ‍‌; 𞤨.ꡏ‍‌; [B6, C1, C2]; xn--ge6h.xn--0ugb9575h; ; xn--ge6h.xn--oc9a; [] # 𞤨.ꡏ
+xn--ge6h.xn--oc9a; 𞤨.ꡏ; ; xn--ge6h.xn--oc9a; ; ; # 𞤨.ꡏ
+𞤨.ꡏ; ; ; xn--ge6h.xn--oc9a; ; ; # 𞤨.ꡏ
+𞤆.ꡏ; 𞤨.ꡏ; ; xn--ge6h.xn--oc9a; ; ; # 𞤨.ꡏ
+xn--ge6h.xn--0ugb9575h; 𞤨.ꡏ‍‌; [B6, C1, C2]; xn--ge6h.xn--0ugb9575h; ; ; # 𞤨.ꡏ
+𞤆。ꡏ‍‌; 𞤨.ꡏ‍‌; [B6, C1, C2]; xn--ge6h.xn--0ugb9575h; ; xn--ge6h.xn--oc9a; [] # 𞤨.ꡏ
+󠅹𑂶.ᢌ𑂹٩; 𑂶.ᢌ𑂹٩; [B1, B3, B5, B6, V5]; xn--b50d.xn--iib993gyp5p; ; ; # 𑂶.ᢌ𑂹٩
+󠅹𑂶.ᢌ𑂹٩; 𑂶.ᢌ𑂹٩; [B1, B3, B5, B6, V5]; xn--b50d.xn--iib993gyp5p; ; ; # 𑂶.ᢌ𑂹٩
+xn--b50d.xn--iib993gyp5p; 𑂶.ᢌ𑂹٩; [B1, B3, B5, B6, V5]; xn--b50d.xn--iib993gyp5p; ; ; # 𑂶.ᢌ𑂹٩
+Ⅎ󠅺񝵒。≯⾑; Ⅎ񝵒.≯襾; [P1, V6]; xn--f3g73398c.xn--hdhz171b; ; ; # Ⅎ.≯襾
+Ⅎ󠅺񝵒。≯⾑; Ⅎ񝵒.≯襾; [P1, V6]; xn--f3g73398c.xn--hdhz171b; ; ; # Ⅎ.≯襾
+Ⅎ󠅺񝵒。≯襾; Ⅎ񝵒.≯襾; [P1, V6]; xn--f3g73398c.xn--hdhz171b; ; ; # Ⅎ.≯襾
+Ⅎ󠅺񝵒。≯襾; Ⅎ񝵒.≯襾; [P1, V6]; xn--f3g73398c.xn--hdhz171b; ; ; # Ⅎ.≯襾
+ⅎ󠅺񝵒。≯襾; ⅎ񝵒.≯襾; [P1, V6]; xn--73g39298c.xn--hdhz171b; ; ; # ⅎ.≯襾
+ⅎ󠅺񝵒。≯襾; ⅎ񝵒.≯襾; [P1, V6]; xn--73g39298c.xn--hdhz171b; ; ; # ⅎ.≯襾
+xn--73g39298c.xn--hdhz171b; ⅎ񝵒.≯襾; [V6]; xn--73g39298c.xn--hdhz171b; ; ; # ⅎ.≯襾
+xn--f3g73398c.xn--hdhz171b; Ⅎ񝵒.≯襾; [V6]; xn--f3g73398c.xn--hdhz171b; ; ; # Ⅎ.≯襾
+ⅎ󠅺񝵒。≯⾑; ⅎ񝵒.≯襾; [P1, V6]; xn--73g39298c.xn--hdhz171b; ; ; # ⅎ.≯襾
+ⅎ󠅺񝵒。≯⾑; ⅎ񝵒.≯襾; [P1, V6]; xn--73g39298c.xn--hdhz171b; ; ; # ⅎ.≯襾
+ς‍ු٠。-; ς‍ු٠.-; [B1, B5, B6, C2, V3]; xn--3xa45ks2jenu.-; ; xn--4xa25ks2j.-; [B1, B5, B6, V3] # ςු٠.-
+ς‍ු٠。-; ς‍ු٠.-; [B1, B5, B6, C2, V3]; xn--3xa45ks2jenu.-; ; xn--4xa25ks2j.-; [B1, B5, B6, V3] # ςු٠.-
+Σ‍ු٠。-; σ‍ු٠.-; [B1, B5, B6, C2, V3]; xn--4xa25ks2jenu.-; ; xn--4xa25ks2j.-; [B1, B5, B6, V3] # σු٠.-
+σ‍ු٠。-; σ‍ු٠.-; [B1, B5, B6, C2, V3]; xn--4xa25ks2jenu.-; ; xn--4xa25ks2j.-; [B1, B5, B6, V3] # σු٠.-
+xn--4xa25ks2j.-; σු٠.-; [B1, B5, B6, V3]; xn--4xa25ks2j.-; ; ; # σු٠.-
+xn--4xa25ks2jenu.-; σ‍ු٠.-; [B1, B5, B6, C2, V3]; xn--4xa25ks2jenu.-; ; ; # σු٠.-
+xn--3xa45ks2jenu.-; ς‍ු٠.-; [B1, B5, B6, C2, V3]; xn--3xa45ks2jenu.-; ; ; # ςු٠.-
+Σ‍ු٠。-; σ‍ු٠.-; [B1, B5, B6, C2, V3]; xn--4xa25ks2jenu.-; ; xn--4xa25ks2j.-; [B1, B5, B6, V3] # σු٠.-
+σ‍ු٠。-; σ‍ු٠.-; [B1, B5, B6, C2, V3]; xn--4xa25ks2jenu.-; ; xn--4xa25ks2j.-; [B1, B5, B6, V3] # σු٠.-
+‌.ßႩ-; ; [C1, P1, V3, V6]; xn--0ug.xn----pfa042j; ; .xn--ss--4rn; [P1, V3, V6, A4_2] # .ßႩ-
+‌.ßⴉ-; ; [C1, V3]; xn--0ug.xn----pfa2305a; ; .xn--ss--bi1b; [V3, A4_2] # .ßⴉ-
+‌.SSႩ-; ‌.ssႩ-; [C1, P1, V3, V6]; xn--0ug.xn--ss--4rn; ; .xn--ss--4rn; [P1, V3, V6, A4_2] # .ssႩ-
+‌.ssⴉ-; ; [C1, V3]; xn--0ug.xn--ss--bi1b; ; .xn--ss--bi1b; [V3, A4_2] # .ssⴉ-
+‌.Ssⴉ-; ‌.ssⴉ-; [C1, V3]; xn--0ug.xn--ss--bi1b; ; .xn--ss--bi1b; [V3, A4_2] # .ssⴉ-
+.xn--ss--bi1b; .ssⴉ-; [V3, X4_2]; .xn--ss--bi1b; [V3, A4_2]; ; # .ssⴉ-
+xn--0ug.xn--ss--bi1b; ‌.ssⴉ-; [C1, V3]; xn--0ug.xn--ss--bi1b; ; ; # .ssⴉ-
+.xn--ss--4rn; .ssႩ-; [V3, V6, X4_2]; .xn--ss--4rn; [V3, V6, A4_2]; ; # .ssႩ-
+xn--0ug.xn--ss--4rn; ‌.ssႩ-; [C1, V3, V6]; xn--0ug.xn--ss--4rn; ; ; # .ssႩ-
+xn--0ug.xn----pfa2305a; ‌.ßⴉ-; [C1, V3]; xn--0ug.xn----pfa2305a; ; ; # .ßⴉ-
+xn--0ug.xn----pfa042j; ‌.ßႩ-; [C1, V3, V6]; xn--0ug.xn----pfa042j; ; ; # .ßႩ-
+󍭲𐫍㓱。⾑; 󍭲𐫍㓱.襾; [B5, P1, V6]; xn--u7kt691dlj09f.xn--9v2a; ; ; # 𐫍㓱.襾
+󍭲𐫍㓱。襾; 󍭲𐫍㓱.襾; [B5, P1, V6]; xn--u7kt691dlj09f.xn--9v2a; ; ; # 𐫍㓱.襾
+xn--u7kt691dlj09f.xn--9v2a; 󍭲𐫍㓱.襾; [B5, V6]; xn--u7kt691dlj09f.xn--9v2a; ; ; # 𐫍㓱.襾
+ڠ𐮋𐹰≮。≯󠦗‍; ڠ𐮋𐹰≮.≯󠦗‍; [B1, B3, C2, P1, V6]; xn--2jb053lf13nyoc.xn--1ugx6gc8096c; ; xn--2jb053lf13nyoc.xn--hdh08821l; [B1, B3, P1, V6] # ڠ𐮋𐹰≮.≯
+ڠ𐮋𐹰≮。≯󠦗‍; ڠ𐮋𐹰≮.≯󠦗‍; [B1, B3, C2, P1, V6]; xn--2jb053lf13nyoc.xn--1ugx6gc8096c; ; xn--2jb053lf13nyoc.xn--hdh08821l; [B1, B3, P1, V6] # ڠ𐮋𐹰≮.≯
+xn--2jb053lf13nyoc.xn--hdh08821l; ڠ𐮋𐹰≮.≯󠦗; [B1, B3, V6]; xn--2jb053lf13nyoc.xn--hdh08821l; ; ; # ڠ𐮋𐹰≮.≯
+xn--2jb053lf13nyoc.xn--1ugx6gc8096c; ڠ𐮋𐹰≮.≯󠦗‍; [B1, B3, C2, V6]; xn--2jb053lf13nyoc.xn--1ugx6gc8096c; ; ; # ڠ𐮋𐹰≮.≯
+𝟞。񃰶ݷࢰ⩋; 6.񃰶ݷࢰ⩋; [B1, B5, B6, P1, V6]; 6.xn--7pb04do15eq748f; ; ; # 6.ݷࢰ⩋
+6。񃰶ݷࢰ⩋; 6.񃰶ݷࢰ⩋; [B1, B5, B6, P1, V6]; 6.xn--7pb04do15eq748f; ; ; # 6.ݷࢰ⩋
+6.xn--7pb04do15eq748f; 6.񃰶ݷࢰ⩋; [B1, B5, B6, V6]; 6.xn--7pb04do15eq748f; ; ; # 6.ݷࢰ⩋
+-ﳽ。𑇀𑍴; -شى.𑇀𑍴; [B1, V3, V5]; xn----qnc7d.xn--wd1d62a; ; ; # -شى.𑇀𑍴
+-ﳽ。𑇀𑍴; -شى.𑇀𑍴; [B1, V3, V5]; xn----qnc7d.xn--wd1d62a; ; ; # -شى.𑇀𑍴
+-شى。𑇀𑍴; -شى.𑇀𑍴; [B1, V3, V5]; xn----qnc7d.xn--wd1d62a; ; ; # -شى.𑇀𑍴
+xn----qnc7d.xn--wd1d62a; -شى.𑇀𑍴; [B1, V3, V5]; xn----qnc7d.xn--wd1d62a; ; ; # -شى.𑇀𑍴
+‌󠊶𝟏.ൃ򪥐𐹬󊓶; ‌󠊶1.ൃ򪥐𐹬󊓶; [B1, C1, P1, V5, V6]; xn--1-rgnu0071n.xn--mxc0872kcu37dnmem; ; xn--1-f521m.xn--mxc0872kcu37dnmem; [B1, P1, V5, V6] # 1.ൃ𐹬
+‌󠊶1.ൃ򪥐𐹬󊓶; ; [B1, C1, P1, V5, V6]; xn--1-rgnu0071n.xn--mxc0872kcu37dnmem; ; xn--1-f521m.xn--mxc0872kcu37dnmem; [B1, P1, V5, V6] # 1.ൃ𐹬
+xn--1-f521m.xn--mxc0872kcu37dnmem; 󠊶1.ൃ򪥐𐹬󊓶; [B1, V5, V6]; xn--1-f521m.xn--mxc0872kcu37dnmem; ; ; # 1.ൃ𐹬
+xn--1-rgnu0071n.xn--mxc0872kcu37dnmem; ‌󠊶1.ൃ򪥐𐹬󊓶; [B1, C1, V5, V6]; xn--1-rgnu0071n.xn--mxc0872kcu37dnmem; ; ; # 1.ൃ𐹬
+齙--𝟰.ß; 齙--4.ß; ; xn----4-p16k.xn--zca; ; xn----4-p16k.ss; # 齙--4.ß
+齙--4.ß; ; ; xn----4-p16k.xn--zca; ; xn----4-p16k.ss; # 齙--4.ß
+齙--4.SS; 齙--4.ss; ; xn----4-p16k.ss; ; ; # 齙--4.ss
+齙--4.ss; ; ; xn----4-p16k.ss; ; ; # 齙--4.ss
+齙--4.Ss; 齙--4.ss; ; xn----4-p16k.ss; ; ; # 齙--4.ss
+xn----4-p16k.ss; 齙--4.ss; ; xn----4-p16k.ss; ; ; # 齙--4.ss
+xn----4-p16k.xn--zca; 齙--4.ß; ; xn----4-p16k.xn--zca; ; ; # 齙--4.ß
+齙--𝟰.SS; 齙--4.ss; ; xn----4-p16k.ss; ; ; # 齙--4.ss
+齙--𝟰.ss; 齙--4.ss; ; xn----4-p16k.ss; ; ; # 齙--4.ss
+齙--𝟰.Ss; 齙--4.ss; ; xn----4-p16k.ss; ; ; # 齙--4.ss
+᯲.𐹢𞀖‌; ; [B1, C1, V5]; xn--0zf.xn--0ug9894grqqf; ; xn--0zf.xn--9n0d2296a; [B1, V5] # ᯲.𐹢𞀖
+xn--0zf.xn--9n0d2296a; ᯲.𐹢𞀖; [B1, V5]; xn--0zf.xn--9n0d2296a; ; ; # ᯲.𐹢𞀖
+xn--0zf.xn--0ug9894grqqf; ᯲.𐹢𞀖‌; [B1, C1, V5]; xn--0zf.xn--0ug9894grqqf; ; ; # ᯲.𐹢𞀖
+󃲙󠋘。?-‍; 󃲙󠋘.?-‍; [C2, P1, V6]; xn--ct86d8w51a.xn--?--n1t; ; xn--ct86d8w51a.?-; [P1, V3, V6] # .?-
+󃲙󠋘。?-‍; 󃲙󠋘.?-‍; [C2, P1, V6]; xn--ct86d8w51a.xn--?--n1t; ; xn--ct86d8w51a.?-; [P1, V3, V6] # .?-
+xn--ct86d8w51a.?-; 󃲙󠋘.?-; [P1, V3, V6]; xn--ct86d8w51a.?-; ; ; # .?-
+xn--ct86d8w51a.xn--?--n1t; 󃲙󠋘.?-‍; [C2, P1, V6]; xn--ct86d8w51a.xn--?--n1t; ; ; # .?-
+xn--ct86d8w51a.?-‍; 󃲙󠋘.?-‍; [C2, P1, V6]; xn--ct86d8w51a.xn--?--n1t; ; xn--ct86d8w51a.?-; [P1, V3, V6] # .?-
+XN--CT86D8W51A.?-‍; 󃲙󠋘.?-‍; [C2, P1, V6]; xn--ct86d8w51a.xn--?--n1t; ; xn--ct86d8w51a.?-; [P1, V3, V6] # .?-
+Xn--Ct86d8w51a.?-‍; 󃲙󠋘.?-‍; [C2, P1, V6]; xn--ct86d8w51a.xn--?--n1t; ; xn--ct86d8w51a.?-; [P1, V3, V6] # .?-
+᩠.𞵷-𝪩悎; ᩠.𞵷-𝪩悎; [B1, B2, B3, B6, P1, V5, V6]; xn--jof.xn----gf4bq282iezpa; ; ; # ᩠.-𝪩悎
+᩠.𞵷-𝪩悎; ; [B1, B2, B3, B6, P1, V5, V6]; xn--jof.xn----gf4bq282iezpa; ; ; # ᩠.-𝪩悎
+xn--jof.xn----gf4bq282iezpa; ᩠.𞵷-𝪩悎; [B1, B2, B3, B6, V5, V6]; xn--jof.xn----gf4bq282iezpa; ; ; # ᩠.-𝪩悎
+𛜯󠊛.𞤳񏥾; 𛜯󠊛.𞤳񏥾; [B2, B3, B6, P1, V6]; xn--xx5gy2741c.xn--re6hw266j; ; ; # .𞤳
+𛜯󠊛.𞤳񏥾; ; [B2, B3, B6, P1, V6]; xn--xx5gy2741c.xn--re6hw266j; ; ; # .𞤳
+𛜯󠊛.𞤑񏥾; 𛜯󠊛.𞤳񏥾; [B2, B3, B6, P1, V6]; xn--xx5gy2741c.xn--re6hw266j; ; ; # .𞤳
+xn--xx5gy2741c.xn--re6hw266j; 𛜯󠊛.𞤳񏥾; [B2, B3, B6, V6]; xn--xx5gy2741c.xn--re6hw266j; ; ; # .𞤳
+𛜯󠊛.𞤑񏥾; 𛜯󠊛.𞤳񏥾; [B2, B3, B6, P1, V6]; xn--xx5gy2741c.xn--re6hw266j; ; ; # .𞤳
+ܜ𐫒خ.𐋲; ; [B1]; xn--tgb98b8643d.xn--m97c; ; ; # ܜ𐫒خ.𐋲
+xn--tgb98b8643d.xn--m97c; ܜ𐫒خ.𐋲; [B1]; xn--tgb98b8643d.xn--m97c; ; ; # ܜ𐫒خ.𐋲
+𐼑𞤓ط࣢.?; 𐼑𞤵ط࣢.?; [B1, P1, V6]; xn--2gb08k9w69agm0g.?; ; ; # 𐼑𞤵ط.?
+𐼑𞤵ط࣢.?; ; [B1, P1, V6]; xn--2gb08k9w69agm0g.?; ; ; # 𐼑𞤵ط.?
+xn--2gb08k9w69agm0g.?; 𐼑𞤵ط࣢.?; [B1, P1, V6]; xn--2gb08k9w69agm0g.?; ; ; # 𐼑𞤵ط.?
+Ↄ。᳔੍𞷣; Ↄ.᳔੍𞷣; [B1, P1, V5, V6]; xn--q5g.xn--ybc995g0835a; ; ; # Ↄ.᳔੍
+Ↄ。᳔੍𞷣; Ↄ.᳔੍𞷣; [B1, P1, V5, V6]; xn--q5g.xn--ybc995g0835a; ; ; # Ↄ.᳔੍
+ↄ。᳔੍𞷣; ↄ.᳔੍𞷣; [B1, P1, V5, V6]; xn--r5g.xn--ybc995g0835a; ; ; # ↄ.᳔੍
+xn--r5g.xn--ybc995g0835a; ↄ.᳔੍𞷣; [B1, V5, V6]; xn--r5g.xn--ybc995g0835a; ; ; # ↄ.᳔੍
+xn--q5g.xn--ybc995g0835a; Ↄ.᳔੍𞷣; [B1, V5, V6]; xn--q5g.xn--ybc995g0835a; ; ; # Ↄ.᳔੍
+ↄ。᳔੍𞷣; ↄ.᳔੍𞷣; [B1, P1, V5, V6]; xn--r5g.xn--ybc995g0835a; ; ; # ↄ.᳔੍
+󠪢-。򛂏≮𑜫; 󠪢-.򛂏≮𑜫; [P1, V3, V6]; xn----bh61m.xn--gdhz157g0em1d; ; ; # -.≮𑜫
+󠪢-。򛂏≮𑜫; 󠪢-.򛂏≮𑜫; [P1, V3, V6]; xn----bh61m.xn--gdhz157g0em1d; ; ; # -.≮𑜫
+xn----bh61m.xn--gdhz157g0em1d; 󠪢-.򛂏≮𑜫; [V3, V6]; xn----bh61m.xn--gdhz157g0em1d; ; ; # -.≮𑜫
+‌󠉹‍。򌿧≮Ⴉ; ‌󠉹‍.򌿧≮Ⴉ; [C1, C2, P1, V6]; xn--0ugc90904y.xn--hnd112gpz83n; ; xn--3n36e.xn--hnd112gpz83n; [P1, V6] # .≮Ⴉ
+‌󠉹‍。򌿧≮Ⴉ; ‌󠉹‍.򌿧≮Ⴉ; [C1, C2, P1, V6]; xn--0ugc90904y.xn--hnd112gpz83n; ; xn--3n36e.xn--hnd112gpz83n; [P1, V6] # .≮Ⴉ
+‌󠉹‍。򌿧≮ⴉ; ‌󠉹‍.򌿧≮ⴉ; [C1, C2, P1, V6]; xn--0ugc90904y.xn--gdh992byu01p; ; xn--3n36e.xn--gdh992byu01p; [P1, V6] # .≮ⴉ
+‌󠉹‍。򌿧≮ⴉ; ‌󠉹‍.򌿧≮ⴉ; [C1, C2, P1, V6]; xn--0ugc90904y.xn--gdh992byu01p; ; xn--3n36e.xn--gdh992byu01p; [P1, V6] # .≮ⴉ
+xn--3n36e.xn--gdh992byu01p; 󠉹.򌿧≮ⴉ; [V6]; xn--3n36e.xn--gdh992byu01p; ; ; # .≮ⴉ
+xn--0ugc90904y.xn--gdh992byu01p; ‌󠉹‍.򌿧≮ⴉ; [C1, C2, V6]; xn--0ugc90904y.xn--gdh992byu01p; ; ; # .≮ⴉ
+xn--3n36e.xn--hnd112gpz83n; 󠉹.򌿧≮Ⴉ; [V6]; xn--3n36e.xn--hnd112gpz83n; ; ; # .≮Ⴉ
+xn--0ugc90904y.xn--hnd112gpz83n; ‌󠉹‍.򌿧≮Ⴉ; [C1, C2, V6]; xn--0ugc90904y.xn--hnd112gpz83n; ; ; # .≮Ⴉ
+𐹯-𑄴ࢼ。︒䖐⾆; 𐹯-𑄴ࢼ.︒䖐舌; [B1, P1, V6]; xn----rpd7902rclc.xn--fpo216mn07e; ; ; # 𐹯-𑄴ࢼ.︒䖐舌
+𐹯-𑄴ࢼ。。䖐舌; 𐹯-𑄴ࢼ..䖐舌; [B1, X4_2]; xn----rpd7902rclc..xn--fpo216m; [B1, A4_2]; ; # 𐹯-𑄴ࢼ..䖐舌
+xn----rpd7902rclc..xn--fpo216m; 𐹯-𑄴ࢼ..䖐舌; [B1, X4_2]; xn----rpd7902rclc..xn--fpo216m; [B1, A4_2]; ; # 𐹯-𑄴ࢼ..䖐舌
+xn----rpd7902rclc.xn--fpo216mn07e; 𐹯-𑄴ࢼ.︒䖐舌; [B1, V6]; xn----rpd7902rclc.xn--fpo216mn07e; ; ; # 𐹯-𑄴ࢼ.︒䖐舌
+𝪞Ⴐ。쪡; 𝪞Ⴐ.쪡; [P1, V5, V6]; xn--ond3755u.xn--pi6b; ; ; # 𝪞Ⴐ.쪡
+𝪞Ⴐ。쪡; 𝪞Ⴐ.쪡; [P1, V5, V6]; xn--ond3755u.xn--pi6b; ; ; # 𝪞Ⴐ.쪡
+𝪞Ⴐ。쪡; 𝪞Ⴐ.쪡; [P1, V5, V6]; xn--ond3755u.xn--pi6b; ; ; # 𝪞Ⴐ.쪡
+𝪞Ⴐ。쪡; 𝪞Ⴐ.쪡; [P1, V5, V6]; xn--ond3755u.xn--pi6b; ; ; # 𝪞Ⴐ.쪡
+𝪞ⴐ。쪡; 𝪞ⴐ.쪡; [V5]; xn--7kj1858k.xn--pi6b; ; ; # 𝪞ⴐ.쪡
+𝪞ⴐ。쪡; 𝪞ⴐ.쪡; [V5]; xn--7kj1858k.xn--pi6b; ; ; # 𝪞ⴐ.쪡
+xn--7kj1858k.xn--pi6b; 𝪞ⴐ.쪡; [V5]; xn--7kj1858k.xn--pi6b; ; ; # 𝪞ⴐ.쪡
+xn--ond3755u.xn--pi6b; 𝪞Ⴐ.쪡; [V5, V6]; xn--ond3755u.xn--pi6b; ; ; # 𝪞Ⴐ.쪡
+𝪞ⴐ。쪡; 𝪞ⴐ.쪡; [V5]; xn--7kj1858k.xn--pi6b; ; ; # 𝪞ⴐ.쪡
+𝪞ⴐ。쪡; 𝪞ⴐ.쪡; [V5]; xn--7kj1858k.xn--pi6b; ; ; # 𝪞ⴐ.쪡
+ฺ쩁𐹬.􋉳; ; [B1, P1, V5, V6]; xn--o4c4837g2zvb.xn--5f70g; ; ; # ฺ쩁𐹬.
+ฺ쩁𐹬.􋉳; ฺ쩁𐹬.􋉳; [B1, P1, V5, V6]; xn--o4c4837g2zvb.xn--5f70g; ; ; # ฺ쩁𐹬.
+xn--o4c4837g2zvb.xn--5f70g; ฺ쩁𐹬.􋉳; [B1, V5, V6]; xn--o4c4837g2zvb.xn--5f70g; ; ; # ฺ쩁𐹬.
+ᡅ0‌。⎢󤨄; ᡅ0‌.⎢󤨄; [C1, P1, V6]; xn--0-z6jy93b.xn--8lh28773l; ; xn--0-z6j.xn--8lh28773l; [P1, V6] # ᡅ0.⎢
+ᡅ0‌。⎢󤨄; ᡅ0‌.⎢󤨄; [C1, P1, V6]; xn--0-z6jy93b.xn--8lh28773l; ; xn--0-z6j.xn--8lh28773l; [P1, V6] # ᡅ0.⎢
+xn--0-z6j.xn--8lh28773l; ᡅ0.⎢󤨄; [V6]; xn--0-z6j.xn--8lh28773l; ; ; # ᡅ0.⎢
+xn--0-z6jy93b.xn--8lh28773l; ᡅ0‌.⎢󤨄; [C1, V6]; xn--0-z6jy93b.xn--8lh28773l; ; ; # ᡅ0.⎢
+𲮚9ꍩ៓.‍ß; 𲮚9ꍩ៓.‍ß; [C2, P1, V6]; xn--9-i0j5967eg3qz.xn--zca770n; ; xn--9-i0j5967eg3qz.ss; [P1, V6] # 9ꍩ៓.ß
+𲮚9ꍩ៓.‍ß; ; [C2, P1, V6]; xn--9-i0j5967eg3qz.xn--zca770n; ; xn--9-i0j5967eg3qz.ss; [P1, V6] # 9ꍩ៓.ß
+𲮚9ꍩ៓.‍SS; 𲮚9ꍩ៓.‍ss; [C2, P1, V6]; xn--9-i0j5967eg3qz.xn--ss-l1t; ; xn--9-i0j5967eg3qz.ss; [P1, V6] # 9ꍩ៓.ss
+𲮚9ꍩ៓.‍ss; ; [C2, P1, V6]; xn--9-i0j5967eg3qz.xn--ss-l1t; ; xn--9-i0j5967eg3qz.ss; [P1, V6] # 9ꍩ៓.ss
+xn--9-i0j5967eg3qz.ss; 𲮚9ꍩ៓.ss; [V6]; xn--9-i0j5967eg3qz.ss; ; ; # 9ꍩ៓.ss
+xn--9-i0j5967eg3qz.xn--ss-l1t; 𲮚9ꍩ៓.‍ss; [C2, V6]; xn--9-i0j5967eg3qz.xn--ss-l1t; ; ; # 9ꍩ៓.ss
+xn--9-i0j5967eg3qz.xn--zca770n; 𲮚9ꍩ៓.‍ß; [C2, V6]; xn--9-i0j5967eg3qz.xn--zca770n; ; ; # 9ꍩ៓.ß
+𲮚9ꍩ៓.‍SS; 𲮚9ꍩ៓.‍ss; [C2, P1, V6]; xn--9-i0j5967eg3qz.xn--ss-l1t; ; xn--9-i0j5967eg3qz.ss; [P1, V6] # 9ꍩ៓.ss
+𲮚9ꍩ៓.‍ss; 𲮚9ꍩ៓.‍ss; [C2, P1, V6]; xn--9-i0j5967eg3qz.xn--ss-l1t; ; xn--9-i0j5967eg3qz.ss; [P1, V6] # 9ꍩ៓.ss
+𲮚9ꍩ៓.‍Ss; 𲮚9ꍩ៓.‍ss; [C2, P1, V6]; xn--9-i0j5967eg3qz.xn--ss-l1t; ; xn--9-i0j5967eg3qz.ss; [P1, V6] # 9ꍩ៓.ss
+𲮚9ꍩ៓.‍Ss; 𲮚9ꍩ៓.‍ss; [C2, P1, V6]; xn--9-i0j5967eg3qz.xn--ss-l1t; ; xn--9-i0j5967eg3qz.ss; [P1, V6] # 9ꍩ៓.ss
+ꗷ𑆀.ݝ𐩒; ; ; xn--ju8a625r.xn--hpb0073k; ; ; # ꗷ𑆀.ݝ𐩒
+xn--ju8a625r.xn--hpb0073k; ꗷ𑆀.ݝ𐩒; ; xn--ju8a625r.xn--hpb0073k; ; ; # ꗷ𑆀.ݝ𐩒
+⒐≯-。︒򩑣-񞛠; ⒐≯-.︒򩑣-񞛠; [P1, V3, V6]; xn----ogot9g.xn----n89hl0522az9u2a; ; ; # ⒐≯-.︒-
+⒐≯-。︒򩑣-񞛠; ⒐≯-.︒򩑣-񞛠; [P1, V3, V6]; xn----ogot9g.xn----n89hl0522az9u2a; ; ; # ⒐≯-.︒-
+9.≯-。。򩑣-񞛠; 9.≯-..򩑣-񞛠; [P1, V3, V6, X4_2]; 9.xn----ogo..xn----xj54d1s69k; [P1, V3, V6, A4_2]; ; # 9.≯-..-
+9.≯-。。򩑣-񞛠; 9.≯-..򩑣-񞛠; [P1, V3, V6, X4_2]; 9.xn----ogo..xn----xj54d1s69k; [P1, V3, V6, A4_2]; ; # 9.≯-..-
+9.xn----ogo..xn----xj54d1s69k; 9.≯-..򩑣-񞛠; [V3, V6, X4_2]; 9.xn----ogo..xn----xj54d1s69k; [V3, V6, A4_2]; ; # 9.≯-..-
+xn----ogot9g.xn----n89hl0522az9u2a; ⒐≯-.︒򩑣-񞛠; [V3, V6]; xn----ogot9g.xn----n89hl0522az9u2a; ; ; # ⒐≯-.︒-
+򈪚ೣჁ󠢏.؝; 򈪚ೣჁ󠢏.؝; [B6, P1, V6]; xn--vuc49qvu85xmju7a.xn--cgb; ; ; # ೣჁ.؝
+򈪚ೣჁ󠢏.؝; ; [B6, P1, V6]; xn--vuc49qvu85xmju7a.xn--cgb; ; ; # ೣჁ.؝
+򈪚ೣⴡ󠢏.؝; ; [B6, P1, V6]; xn--vuc226n8n28lmju7a.xn--cgb; ; ; # ೣⴡ.؝
+xn--vuc226n8n28lmju7a.xn--cgb; 򈪚ೣⴡ󠢏.؝; [B6, V6]; xn--vuc226n8n28lmju7a.xn--cgb; ; ; # ೣⴡ.؝
+xn--vuc49qvu85xmju7a.xn--cgb; 򈪚ೣჁ󠢏.؝; [B6, V6]; xn--vuc49qvu85xmju7a.xn--cgb; ; ; # ೣჁ.؝
+򈪚ೣⴡ󠢏.؝; 򈪚ೣⴡ󠢏.؝; [B6, P1, V6]; xn--vuc226n8n28lmju7a.xn--cgb; ; ; # ೣⴡ.؝
+ᷫ。𐋩ظ-𐫮; ᷫ.𐋩ظ-𐫮; [B1, B3, B6, V5]; xn--gfg.xn----xnc0815qyyg; ; ; # ᷫ.𐋩ظ-𐫮
+xn--gfg.xn----xnc0815qyyg; ᷫ.𐋩ظ-𐫮; [B1, B3, B6, V5]; xn--gfg.xn----xnc0815qyyg; ; ; # ᷫ.𐋩ظ-𐫮
+싇。⾇𐳋Ⴝ; 싇.舛𐳋Ⴝ; [B5, P1, V6]; xn--9u4b.xn--1nd7519ch79d; ; ; # 싇.舛𐳋Ⴝ
+싇。⾇𐳋Ⴝ; 싇.舛𐳋Ⴝ; [B5, P1, V6]; xn--9u4b.xn--1nd7519ch79d; ; ; # 싇.舛𐳋Ⴝ
+싇。舛𐳋Ⴝ; 싇.舛𐳋Ⴝ; [B5, P1, V6]; xn--9u4b.xn--1nd7519ch79d; ; ; # 싇.舛𐳋Ⴝ
+싇。舛𐳋Ⴝ; 싇.舛𐳋Ⴝ; [B5, P1, V6]; xn--9u4b.xn--1nd7519ch79d; ; ; # 싇.舛𐳋Ⴝ
+싇。舛𐳋ⴝ; 싇.舛𐳋ⴝ; [B5]; xn--9u4b.xn--llj123yh74e; ; ; # 싇.舛𐳋ⴝ
+싇。舛𐳋ⴝ; 싇.舛𐳋ⴝ; [B5]; xn--9u4b.xn--llj123yh74e; ; ; # 싇.舛𐳋ⴝ
+싇。舛𐲋Ⴝ; 싇.舛𐳋Ⴝ; [B5, P1, V6]; xn--9u4b.xn--1nd7519ch79d; ; ; # 싇.舛𐳋Ⴝ
+싇。舛𐲋Ⴝ; 싇.舛𐳋Ⴝ; [B5, P1, V6]; xn--9u4b.xn--1nd7519ch79d; ; ; # 싇.舛𐳋Ⴝ
+싇。舛𐲋ⴝ; 싇.舛𐳋ⴝ; [B5]; xn--9u4b.xn--llj123yh74e; ; ; # 싇.舛𐳋ⴝ
+싇。舛𐲋ⴝ; 싇.舛𐳋ⴝ; [B5]; xn--9u4b.xn--llj123yh74e; ; ; # 싇.舛𐳋ⴝ
+xn--9u4b.xn--llj123yh74e; 싇.舛𐳋ⴝ; [B5]; xn--9u4b.xn--llj123yh74e; ; ; # 싇.舛𐳋ⴝ
+xn--9u4b.xn--1nd7519ch79d; 싇.舛𐳋Ⴝ; [B5, V6]; xn--9u4b.xn--1nd7519ch79d; ; ; # 싇.舛𐳋Ⴝ
+싇。⾇𐳋ⴝ; 싇.舛𐳋ⴝ; [B5]; xn--9u4b.xn--llj123yh74e; ; ; # 싇.舛𐳋ⴝ
+싇。⾇𐳋ⴝ; 싇.舛𐳋ⴝ; [B5]; xn--9u4b.xn--llj123yh74e; ; ; # 싇.舛𐳋ⴝ
+싇。⾇𐲋Ⴝ; 싇.舛𐳋Ⴝ; [B5, P1, V6]; xn--9u4b.xn--1nd7519ch79d; ; ; # 싇.舛𐳋Ⴝ
+싇。⾇𐲋Ⴝ; 싇.舛𐳋Ⴝ; [B5, P1, V6]; xn--9u4b.xn--1nd7519ch79d; ; ; # 싇.舛𐳋Ⴝ
+싇。⾇𐲋ⴝ; 싇.舛𐳋ⴝ; [B5]; xn--9u4b.xn--llj123yh74e; ; ; # 싇.舛𐳋ⴝ
+싇。⾇𐲋ⴝ; 싇.舛𐳋ⴝ; [B5]; xn--9u4b.xn--llj123yh74e; ; ; # 싇.舛𐳋ⴝ
+𐹠ς。‌ڿჀ; 𐹠ς.‌ڿჀ; [B1, C1, P1, V6]; xn--3xa1267k.xn--ykb632cvxm; ; xn--4xa9167k.xn--ykb632c; [B1, B2, B3, P1, V6] # 𐹠ς.ڿჀ
+𐹠ς。‌ڿⴠ; 𐹠ς.‌ڿⴠ; [B1, C1]; xn--3xa1267k.xn--ykb760k9hj; ; xn--4xa9167k.xn--ykb467q; [B1, B2, B3] # 𐹠ς.ڿⴠ
+𐹠Σ。‌ڿჀ; 𐹠σ.‌ڿჀ; [B1, C1, P1, V6]; xn--4xa9167k.xn--ykb632cvxm; ; xn--4xa9167k.xn--ykb632c; [B1, B2, B3, P1, V6] # 𐹠σ.ڿჀ
+𐹠σ。‌ڿⴠ; 𐹠σ.‌ڿⴠ; [B1, C1]; xn--4xa9167k.xn--ykb760k9hj; ; xn--4xa9167k.xn--ykb467q; [B1, B2, B3] # 𐹠σ.ڿⴠ
+𐹠Σ。‌ڿⴠ; 𐹠σ.‌ڿⴠ; [B1, C1]; xn--4xa9167k.xn--ykb760k9hj; ; xn--4xa9167k.xn--ykb467q; [B1, B2, B3] # 𐹠σ.ڿⴠ
+xn--4xa9167k.xn--ykb467q; 𐹠σ.ڿⴠ; [B1, B2, B3]; xn--4xa9167k.xn--ykb467q; ; ; # 𐹠σ.ڿⴠ
+xn--4xa9167k.xn--ykb760k9hj; 𐹠σ.‌ڿⴠ; [B1, C1]; xn--4xa9167k.xn--ykb760k9hj; ; ; # 𐹠σ.ڿⴠ
+xn--4xa9167k.xn--ykb632c; 𐹠σ.ڿჀ; [B1, B2, B3, V6]; xn--4xa9167k.xn--ykb632c; ; ; # 𐹠σ.ڿჀ
+xn--4xa9167k.xn--ykb632cvxm; 𐹠σ.‌ڿჀ; [B1, C1, V6]; xn--4xa9167k.xn--ykb632cvxm; ; ; # 𐹠σ.ڿჀ
+xn--3xa1267k.xn--ykb760k9hj; 𐹠ς.‌ڿⴠ; [B1, C1]; xn--3xa1267k.xn--ykb760k9hj; ; ; # 𐹠ς.ڿⴠ
+xn--3xa1267k.xn--ykb632cvxm; 𐹠ς.‌ڿჀ; [B1, C1, V6]; xn--3xa1267k.xn--ykb632cvxm; ; ; # 𐹠ς.ڿჀ
+򇒐‌؄.ښ-ß; ; [B2, B3, B5, B6, C1, P1, V6]; xn--mfb144kqo32m.xn----qfa315b; ; xn--mfb98261i.xn---ss-sdf; [B2, B3, B5, B6, P1, V6] # .ښ-ß
+򇒐‌؄.ښ-SS; 򇒐‌؄.ښ-ss; [B2, B3, B5, B6, C1, P1, V6]; xn--mfb144kqo32m.xn---ss-sdf; ; xn--mfb98261i.xn---ss-sdf; [B2, B3, B5, B6, P1, V6] # .ښ-ss
+򇒐‌؄.ښ-ss; ; [B2, B3, B5, B6, C1, P1, V6]; xn--mfb144kqo32m.xn---ss-sdf; ; xn--mfb98261i.xn---ss-sdf; [B2, B3, B5, B6, P1, V6] # .ښ-ss
+򇒐‌؄.ښ-Ss; 򇒐‌؄.ښ-ss; [B2, B3, B5, B6, C1, P1, V6]; xn--mfb144kqo32m.xn---ss-sdf; ; xn--mfb98261i.xn---ss-sdf; [B2, B3, B5, B6, P1, V6] # .ښ-ss
+xn--mfb98261i.xn---ss-sdf; 򇒐؄.ښ-ss; [B2, B3, B5, B6, V6]; xn--mfb98261i.xn---ss-sdf; ; ; # .ښ-ss
+xn--mfb144kqo32m.xn---ss-sdf; 򇒐‌؄.ښ-ss; [B2, B3, B5, B6, C1, V6]; xn--mfb144kqo32m.xn---ss-sdf; ; ; # .ښ-ss
+xn--mfb144kqo32m.xn----qfa315b; 򇒐‌؄.ښ-ß; [B2, B3, B5, B6, C1, V6]; xn--mfb144kqo32m.xn----qfa315b; ; ; # .ښ-ß
+‌‍឵ٺ.-ﮰ󅄞𐸚; ‌‍឵ٺ.-ۓ󅄞𐸚; [B1, C1, C2, P1, V3, V6]; xn--zib539f8igea.xn----twc1133r17r6g; ; xn--zib539f.xn----twc1133r17r6g; [B1, P1, V3, V5, V6] # ٺ.-ۓ
+‌‍឵ٺ.-ۓ󅄞𐸚; ; [B1, C1, C2, P1, V3, V6]; xn--zib539f8igea.xn----twc1133r17r6g; ; xn--zib539f.xn----twc1133r17r6g; [B1, P1, V3, V5, V6] # ٺ.-ۓ
+‌‍឵ٺ.-ۓ󅄞𐸚; ‌‍឵ٺ.-ۓ󅄞𐸚; [B1, C1, C2, P1, V3, V6]; xn--zib539f8igea.xn----twc1133r17r6g; ; xn--zib539f.xn----twc1133r17r6g; [B1, P1, V3, V5, V6] # ٺ.-ۓ
+xn--zib539f.xn----twc1133r17r6g; ឵ٺ.-ۓ󅄞𐸚; [B1, V3, V5, V6]; xn--zib539f.xn----twc1133r17r6g; ; ; # ٺ.-ۓ
+xn--zib539f8igea.xn----twc1133r17r6g; ‌‍឵ٺ.-ۓ󅄞𐸚; [B1, C1, C2, V3, V6]; xn--zib539f8igea.xn----twc1133r17r6g; ; ; # ٺ.-ۓ
+򡶱。𐮬≠; 򡶱.𐮬≠; [B3, P1, V6]; xn--dd55c.xn--1ch3003g; ; ; # .𐮬≠
+򡶱。𐮬≠; 򡶱.𐮬≠; [B3, P1, V6]; xn--dd55c.xn--1ch3003g; ; ; # .𐮬≠
+򡶱。𐮬≠; 򡶱.𐮬≠; [B3, P1, V6]; xn--dd55c.xn--1ch3003g; ; ; # .𐮬≠
+򡶱。𐮬≠; 򡶱.𐮬≠; [B3, P1, V6]; xn--dd55c.xn--1ch3003g; ; ; # .𐮬≠
+xn--dd55c.xn--1ch3003g; 򡶱.𐮬≠; [B3, V6]; xn--dd55c.xn--1ch3003g; ; ; # .𐮬≠
+ྲ𞶅。𐹮𐹷덝۵; ྲ𞶅.𐹮𐹷덝۵; [B1, P1, V5, V6]; xn--fgd0675v.xn--imb5839fidpcbba; ; ; # ྲ.𐹮𐹷덝۵
+ྲ𞶅。𐹮𐹷덝۵; ྲ𞶅.𐹮𐹷덝۵; [B1, P1, V5, V6]; xn--fgd0675v.xn--imb5839fidpcbba; ; ; # ྲ.𐹮𐹷덝۵
+ྲ𞶅。𐹮𐹷덝۵; ྲ𞶅.𐹮𐹷덝۵; [B1, P1, V5, V6]; xn--fgd0675v.xn--imb5839fidpcbba; ; ; # ྲ.𐹮𐹷덝۵
+ྲ𞶅。𐹮𐹷덝۵; ྲ𞶅.𐹮𐹷덝۵; [B1, P1, V5, V6]; xn--fgd0675v.xn--imb5839fidpcbba; ; ; # ྲ.𐹮𐹷덝۵
+xn--fgd0675v.xn--imb5839fidpcbba; ྲ𞶅.𐹮𐹷덝۵; [B1, V5, V6]; xn--fgd0675v.xn--imb5839fidpcbba; ; ; # ྲ.𐹮𐹷덝۵
+Ⴏ󠅋-.‍Ⴉ; Ⴏ-.‍Ⴉ; [C2, P1, V3, V6]; xn----00g.xn--hnd399e; ; xn----00g.xn--hnd; [P1, V3, V6] # Ⴏ-.Ⴉ
+Ⴏ󠅋-.‍Ⴉ; Ⴏ-.‍Ⴉ; [C2, P1, V3, V6]; xn----00g.xn--hnd399e; ; xn----00g.xn--hnd; [P1, V3, V6] # Ⴏ-.Ⴉ
+ⴏ󠅋-.‍ⴉ; ⴏ-.‍ⴉ; [C2, V3]; xn----3vs.xn--1ug532c; ; xn----3vs.xn--0kj; [V3] # ⴏ-.ⴉ
+xn----3vs.xn--0kj; ⴏ-.ⴉ; [V3]; xn----3vs.xn--0kj; ; ; # ⴏ-.ⴉ
+xn----3vs.xn--1ug532c; ⴏ-.‍ⴉ; [C2, V3]; xn----3vs.xn--1ug532c; ; ; # ⴏ-.ⴉ
+xn----00g.xn--hnd; Ⴏ-.Ⴉ; [V3, V6]; xn----00g.xn--hnd; ; ; # Ⴏ-.Ⴉ
+xn----00g.xn--hnd399e; Ⴏ-.‍Ⴉ; [C2, V3, V6]; xn----00g.xn--hnd399e; ; ; # Ⴏ-.Ⴉ
+ⴏ󠅋-.‍ⴉ; ⴏ-.‍ⴉ; [C2, V3]; xn----3vs.xn--1ug532c; ; xn----3vs.xn--0kj; [V3] # ⴏ-.ⴉ
+⇧𐨏󠾈󯶅。؀󠈵󠆉; ⇧𐨏󠾈󯶅.؀󠈵; [B1, P1, V6]; xn--l8g5552g64t4g46xf.xn--ifb08144p; ; ; # ⇧𐨏.
+xn--l8g5552g64t4g46xf.xn--ifb08144p; ⇧𐨏󠾈󯶅.؀󠈵; [B1, V6]; xn--l8g5552g64t4g46xf.xn--ifb08144p; ; ; # ⇧𐨏.
+≠𐮂.↑🄇⒈; ; [B1, P1, V6]; xn--1chy492g.xn--45gx9iuy44d; ; ; # ≠𐮂.↑🄇⒈
+≠𐮂.↑🄇⒈; ≠𐮂.↑🄇⒈; [B1, P1, V6]; xn--1chy492g.xn--45gx9iuy44d; ; ; # ≠𐮂.↑🄇⒈
+≠𐮂.↑6,1.; ; [B1, P1, V6]; xn--1chy492g.xn--6,1-pw1a.; ; ; # ≠𐮂.↑6,1.
+≠𐮂.↑6,1.; ≠𐮂.↑6,1.; [B1, P1, V6]; xn--1chy492g.xn--6,1-pw1a.; ; ; # ≠𐮂.↑6,1.
+xn--1chy492g.xn--6,1-pw1a.; ≠𐮂.↑6,1.; [B1, P1, V6]; xn--1chy492g.xn--6,1-pw1a.; ; ; # ≠𐮂.↑6,1.
+xn--1chy492g.xn--45gx9iuy44d; ≠𐮂.↑🄇⒈; [B1, V6]; xn--1chy492g.xn--45gx9iuy44d; ; ; # ≠𐮂.↑🄇⒈
+𝩏󠲉ß.ᢤ򄦌‌𐹫; ; [B1, B5, B6, C1, P1, V5, V6]; xn--zca3153vupz3e.xn--ubf609atw1tynn3d; ; xn--ss-zb11ap1427e.xn--ubf2596jbt61c; [B1, B5, B6, P1, V5, V6] # 𝩏ß.ᢤ𐹫
+𝩏󠲉SS.ᢤ򄦌‌𐹫; 𝩏󠲉ss.ᢤ򄦌‌𐹫; [B1, B5, B6, C1, P1, V5, V6]; xn--ss-zb11ap1427e.xn--ubf609atw1tynn3d; ; xn--ss-zb11ap1427e.xn--ubf2596jbt61c; [B1, B5, B6, P1, V5, V6] # 𝩏ss.ᢤ𐹫
+𝩏󠲉ss.ᢤ򄦌‌𐹫; ; [B1, B5, B6, C1, P1, V5, V6]; xn--ss-zb11ap1427e.xn--ubf609atw1tynn3d; ; xn--ss-zb11ap1427e.xn--ubf2596jbt61c; [B1, B5, B6, P1, V5, V6] # 𝩏ss.ᢤ𐹫
+𝩏󠲉Ss.ᢤ򄦌‌𐹫; 𝩏󠲉ss.ᢤ򄦌‌𐹫; [B1, B5, B6, C1, P1, V5, V6]; xn--ss-zb11ap1427e.xn--ubf609atw1tynn3d; ; xn--ss-zb11ap1427e.xn--ubf2596jbt61c; [B1, B5, B6, P1, V5, V6] # 𝩏ss.ᢤ𐹫
+xn--ss-zb11ap1427e.xn--ubf2596jbt61c; 𝩏󠲉ss.ᢤ򄦌𐹫; [B1, B5, B6, V5, V6]; xn--ss-zb11ap1427e.xn--ubf2596jbt61c; ; ; # 𝩏ss.ᢤ𐹫
+xn--ss-zb11ap1427e.xn--ubf609atw1tynn3d; 𝩏󠲉ss.ᢤ򄦌‌𐹫; [B1, B5, B6, C1, V5, V6]; xn--ss-zb11ap1427e.xn--ubf609atw1tynn3d; ; ; # 𝩏ss.ᢤ𐹫
+xn--zca3153vupz3e.xn--ubf609atw1tynn3d; 𝩏󠲉ß.ᢤ򄦌‌𐹫; [B1, B5, B6, C1, V5, V6]; xn--zca3153vupz3e.xn--ubf609atw1tynn3d; ; ; # 𝩏ß.ᢤ𐹫
+ß𐵳񗘁Ⴇ。ꙺ; ß𐵳񗘁Ⴇ.ꙺ; [B1, B3, B5, B6, P1, V5, V6]; xn--zca491fci5qkn79a.xn--9x8a; ; xn--ss-rek7420r4hs7b.xn--9x8a; # ßႧ.ꙺ
+ß𐵳񗘁Ⴇ。ꙺ; ß𐵳񗘁Ⴇ.ꙺ; [B1, B3, B5, B6, P1, V5, V6]; xn--zca491fci5qkn79a.xn--9x8a; ; xn--ss-rek7420r4hs7b.xn--9x8a; # ßႧ.ꙺ
+ß𐵳񗘁ⴇ。ꙺ; ß𐵳񗘁ⴇ.ꙺ; [B1, B3, B5, B6, P1, V5, V6]; xn--zca227tpy4lkns1b.xn--9x8a; ; xn--ss-e61ar955h4hs7b.xn--9x8a; # ßⴇ.ꙺ
+SS𐵳񗘁Ⴇ。ꙺ; ss𐵳񗘁Ⴇ.ꙺ; [B1, B3, B5, B6, P1, V5, V6]; xn--ss-rek7420r4hs7b.xn--9x8a; ; ; # ssႧ.ꙺ
+ss𐵳񗘁ⴇ。ꙺ; ss𐵳񗘁ⴇ.ꙺ; [B1, B3, B5, B6, P1, V5, V6]; xn--ss-e61ar955h4hs7b.xn--9x8a; ; ; # ssⴇ.ꙺ
+Ss𐵳񗘁Ⴇ。ꙺ; ss𐵳񗘁Ⴇ.ꙺ; [B1, B3, B5, B6, P1, V5, V6]; xn--ss-rek7420r4hs7b.xn--9x8a; ; ; # ssႧ.ꙺ
+xn--ss-rek7420r4hs7b.xn--9x8a; ss𐵳񗘁Ⴇ.ꙺ; [B1, B3, B5, B6, V5, V6]; xn--ss-rek7420r4hs7b.xn--9x8a; ; ; # ssႧ.ꙺ
+xn--ss-e61ar955h4hs7b.xn--9x8a; ss𐵳񗘁ⴇ.ꙺ; [B1, B3, B5, B6, V5, V6]; xn--ss-e61ar955h4hs7b.xn--9x8a; ; ; # ssⴇ.ꙺ
+xn--zca227tpy4lkns1b.xn--9x8a; ß𐵳񗘁ⴇ.ꙺ; [B1, B3, B5, B6, V5, V6]; xn--zca227tpy4lkns1b.xn--9x8a; ; ; # ßⴇ.ꙺ
+xn--zca491fci5qkn79a.xn--9x8a; ß𐵳񗘁Ⴇ.ꙺ; [B1, B3, B5, B6, V5, V6]; xn--zca491fci5qkn79a.xn--9x8a; ; ; # ßႧ.ꙺ
+ß𐵳񗘁ⴇ。ꙺ; ß𐵳񗘁ⴇ.ꙺ; [B1, B3, B5, B6, P1, V5, V6]; xn--zca227tpy4lkns1b.xn--9x8a; ; xn--ss-e61ar955h4hs7b.xn--9x8a; # ßⴇ.ꙺ
+SS𐵳񗘁Ⴇ。ꙺ; ss𐵳񗘁Ⴇ.ꙺ; [B1, B3, B5, B6, P1, V5, V6]; xn--ss-rek7420r4hs7b.xn--9x8a; ; ; # ssႧ.ꙺ
+ss𐵳񗘁ⴇ。ꙺ; ss𐵳񗘁ⴇ.ꙺ; [B1, B3, B5, B6, P1, V5, V6]; xn--ss-e61ar955h4hs7b.xn--9x8a; ; ; # ssⴇ.ꙺ
+Ss𐵳񗘁Ⴇ。ꙺ; ss𐵳񗘁Ⴇ.ꙺ; [B1, B3, B5, B6, P1, V5, V6]; xn--ss-rek7420r4hs7b.xn--9x8a; ; ; # ssႧ.ꙺ
+᜔。󠆣-𑋪; ᜔.-𑋪; [V3, V5]; xn--fze.xn----ly8i; ; ; # ᜔.-𑋪
+xn--fze.xn----ly8i; ᜔.-𑋪; [V3, V5]; xn--fze.xn----ly8i; ; ; # ᜔.-𑋪
+ꯨ-.򨏜ֽß; ꯨ-.򨏜ֽß; [P1, V3, V5, V6]; xn----pw5e.xn--zca50wfv060a; ; xn----pw5e.xn--ss-7jd10716y; # ꯨ-.ֽß
+ꯨ-.򨏜ֽß; ; [P1, V3, V5, V6]; xn----pw5e.xn--zca50wfv060a; ; xn----pw5e.xn--ss-7jd10716y; # ꯨ-.ֽß
+ꯨ-.򨏜ֽSS; ꯨ-.򨏜ֽss; [P1, V3, V5, V6]; xn----pw5e.xn--ss-7jd10716y; ; ; # ꯨ-.ֽss
+ꯨ-.򨏜ֽss; ; [P1, V3, V5, V6]; xn----pw5e.xn--ss-7jd10716y; ; ; # ꯨ-.ֽss
+ꯨ-.򨏜ֽSs; ꯨ-.򨏜ֽss; [P1, V3, V5, V6]; xn----pw5e.xn--ss-7jd10716y; ; ; # ꯨ-.ֽss
+xn----pw5e.xn--ss-7jd10716y; ꯨ-.򨏜ֽss; [V3, V5, V6]; xn----pw5e.xn--ss-7jd10716y; ; ; # ꯨ-.ֽss
+xn----pw5e.xn--zca50wfv060a; ꯨ-.򨏜ֽß; [V3, V5, V6]; xn----pw5e.xn--zca50wfv060a; ; ; # ꯨ-.ֽß
+ꯨ-.򨏜ֽSS; ꯨ-.򨏜ֽss; [P1, V3, V5, V6]; xn----pw5e.xn--ss-7jd10716y; ; ; # ꯨ-.ֽss
+ꯨ-.򨏜ֽss; ꯨ-.򨏜ֽss; [P1, V3, V5, V6]; xn----pw5e.xn--ss-7jd10716y; ; ; # ꯨ-.ֽss
+ꯨ-.򨏜ֽSs; ꯨ-.򨏜ֽss; [P1, V3, V5, V6]; xn----pw5e.xn--ss-7jd10716y; ; ; # ꯨ-.ֽss
+ᡓ-≮。٫󠅱ᡄ; ᡓ-≮.٫ᡄ; [B1, B6, P1, V6]; xn----s7j866c.xn--kib252g; ; ; # ᡓ-≮.٫ᡄ
+ᡓ-≮。٫󠅱ᡄ; ᡓ-≮.٫ᡄ; [B1, B6, P1, V6]; xn----s7j866c.xn--kib252g; ; ; # ᡓ-≮.٫ᡄ
+xn----s7j866c.xn--kib252g; ᡓ-≮.٫ᡄ; [B1, B6, V6]; xn----s7j866c.xn--kib252g; ; ; # ᡓ-≮.٫ᡄ
+𝟥♮𑜫࣭.្𑜫8󠆏; 3♮𑜫࣭.្𑜫8; [V5]; xn--3-ksd277tlo7s.xn--8-f0jx021l; ; ; # 3♮𑜫࣭.្𑜫8
+3♮𑜫࣭.្𑜫8󠆏; 3♮𑜫࣭.្𑜫8; [V5]; xn--3-ksd277tlo7s.xn--8-f0jx021l; ; ; # 3♮𑜫࣭.្𑜫8
+xn--3-ksd277tlo7s.xn--8-f0jx021l; 3♮𑜫࣭.្𑜫8; [V5]; xn--3-ksd277tlo7s.xn--8-f0jx021l; ; ; # 3♮𑜫࣭.្𑜫8
+-。򕌀‍❡; -.򕌀‍❡; [C2, P1, V3, V6]; -.xn--1ug800aq795s; ; -.xn--nei54421f; [P1, V3, V6] # -.❡
+-。򕌀‍❡; -.򕌀‍❡; [C2, P1, V3, V6]; -.xn--1ug800aq795s; ; -.xn--nei54421f; [P1, V3, V6] # -.❡
+-.xn--nei54421f; -.򕌀❡; [V3, V6]; -.xn--nei54421f; ; ; # -.❡
+-.xn--1ug800aq795s; -.򕌀‍❡; [C2, V3, V6]; -.xn--1ug800aq795s; ; ; # -.❡
+𝟓☱𝟐򥰵。𝪮񐡳; 5☱2򥰵.𝪮񐡳; [P1, V5, V6]; xn--52-dwx47758j.xn--kd3hk431k; ; ; # 5☱2.𝪮
+5☱2򥰵。𝪮񐡳; 5☱2򥰵.𝪮񐡳; [P1, V5, V6]; xn--52-dwx47758j.xn--kd3hk431k; ; ; # 5☱2.𝪮
+xn--52-dwx47758j.xn--kd3hk431k; 5☱2򥰵.𝪮񐡳; [V5, V6]; xn--52-dwx47758j.xn--kd3hk431k; ; ; # 5☱2.𝪮
+-.-├򖦣; ; [P1, V3, V6]; -.xn----ukp70432h; ; ; # -.-├
+-.xn----ukp70432h; -.-├򖦣; [V3, V6]; -.xn----ukp70432h; ; ; # -.-├
+֥ݭ。‍󠀘; ֥ݭ.‍󠀘; [B1, C2, P1, V5, V6]; xn--wcb62g.xn--1ugy8001l; ; xn--wcb62g.xn--p526e; [B1, P1, V5, V6] # ֥ݭ.
+֥ݭ。‍󠀘; ֥ݭ.‍󠀘; [B1, C2, P1, V5, V6]; xn--wcb62g.xn--1ugy8001l; ; xn--wcb62g.xn--p526e; [B1, P1, V5, V6] # ֥ݭ.
+xn--wcb62g.xn--p526e; ֥ݭ.󠀘; [B1, V5, V6]; xn--wcb62g.xn--p526e; ; ; # ֥ݭ.
+xn--wcb62g.xn--1ugy8001l; ֥ݭ.‍󠀘; [B1, C2, V5, V6]; xn--wcb62g.xn--1ugy8001l; ; ; # ֥ݭ.
+쥥󔏉Ⴎ.‌⒈⒈𐫒; 쥥󔏉Ⴎ.‌⒈⒈𐫒; [B1, C1, P1, V6]; xn--mnd7865gcy28g.xn--0ug88oa0396u; ; xn--mnd7865gcy28g.xn--tsha6797o; [B1, P1, V6] # 쥥Ⴎ.⒈⒈𐫒
+쥥󔏉Ⴎ.‌⒈⒈𐫒; 쥥󔏉Ⴎ.‌⒈⒈𐫒; [B1, C1, P1, V6]; xn--mnd7865gcy28g.xn--0ug88oa0396u; ; xn--mnd7865gcy28g.xn--tsha6797o; [B1, P1, V6] # 쥥Ⴎ.⒈⒈𐫒
+쥥󔏉Ⴎ.‌1.1.𐫒; ; [B1, C1, P1, V6]; xn--mnd7865gcy28g.xn--1-rgn.1.xn--7w9c; ; xn--mnd7865gcy28g.1.1.xn--7w9c; [B1, P1, V6] # 쥥Ⴎ.1.1.𐫒
+쥥󔏉Ⴎ.‌1.1.𐫒; 쥥󔏉Ⴎ.‌1.1.𐫒; [B1, C1, P1, V6]; xn--mnd7865gcy28g.xn--1-rgn.1.xn--7w9c; ; xn--mnd7865gcy28g.1.1.xn--7w9c; [B1, P1, V6] # 쥥Ⴎ.1.1.𐫒
+쥥󔏉ⴎ.‌1.1.𐫒; 쥥󔏉ⴎ.‌1.1.𐫒; [B1, C1, P1, V6]; xn--5kj3511ccyw3h.xn--1-rgn.1.xn--7w9c; ; xn--5kj3511ccyw3h.1.1.xn--7w9c; [B1, P1, V6] # 쥥ⴎ.1.1.𐫒
+쥥󔏉ⴎ.‌1.1.𐫒; ; [B1, C1, P1, V6]; xn--5kj3511ccyw3h.xn--1-rgn.1.xn--7w9c; ; xn--5kj3511ccyw3h.1.1.xn--7w9c; [B1, P1, V6] # 쥥ⴎ.1.1.𐫒
+xn--5kj3511ccyw3h.1.1.xn--7w9c; 쥥󔏉ⴎ.1.1.𐫒; [B1, V6]; xn--5kj3511ccyw3h.1.1.xn--7w9c; ; ; # 쥥ⴎ.1.1.𐫒
+xn--5kj3511ccyw3h.xn--1-rgn.1.xn--7w9c; 쥥󔏉ⴎ.‌1.1.𐫒; [B1, C1, V6]; xn--5kj3511ccyw3h.xn--1-rgn.1.xn--7w9c; ; ; # 쥥ⴎ.1.1.𐫒
+xn--mnd7865gcy28g.1.1.xn--7w9c; 쥥󔏉Ⴎ.1.1.𐫒; [B1, V6]; xn--mnd7865gcy28g.1.1.xn--7w9c; ; ; # 쥥Ⴎ.1.1.𐫒
+xn--mnd7865gcy28g.xn--1-rgn.1.xn--7w9c; 쥥󔏉Ⴎ.‌1.1.𐫒; [B1, C1, V6]; xn--mnd7865gcy28g.xn--1-rgn.1.xn--7w9c; ; ; # 쥥Ⴎ.1.1.𐫒
+쥥󔏉ⴎ.‌⒈⒈𐫒; 쥥󔏉ⴎ.‌⒈⒈𐫒; [B1, C1, P1, V6]; xn--5kj3511ccyw3h.xn--0ug88oa0396u; ; xn--5kj3511ccyw3h.xn--tsha6797o; [B1, P1, V6] # 쥥ⴎ.⒈⒈𐫒
+쥥󔏉ⴎ.‌⒈⒈𐫒; 쥥󔏉ⴎ.‌⒈⒈𐫒; [B1, C1, P1, V6]; xn--5kj3511ccyw3h.xn--0ug88oa0396u; ; xn--5kj3511ccyw3h.xn--tsha6797o; [B1, P1, V6] # 쥥ⴎ.⒈⒈𐫒
+xn--5kj3511ccyw3h.xn--tsha6797o; 쥥󔏉ⴎ.⒈⒈𐫒; [B1, V6]; xn--5kj3511ccyw3h.xn--tsha6797o; ; ; # 쥥ⴎ.⒈⒈𐫒
+xn--5kj3511ccyw3h.xn--0ug88oa0396u; 쥥󔏉ⴎ.‌⒈⒈𐫒; [B1, C1, V6]; xn--5kj3511ccyw3h.xn--0ug88oa0396u; ; ; # 쥥ⴎ.⒈⒈𐫒
+xn--mnd7865gcy28g.xn--tsha6797o; 쥥󔏉Ⴎ.⒈⒈𐫒; [B1, V6]; xn--mnd7865gcy28g.xn--tsha6797o; ; ; # 쥥Ⴎ.⒈⒈𐫒
+xn--mnd7865gcy28g.xn--0ug88oa0396u; 쥥󔏉Ⴎ.‌⒈⒈𐫒; [B1, C1, V6]; xn--mnd7865gcy28g.xn--0ug88oa0396u; ; ; # 쥥Ⴎ.⒈⒈𐫒
+ࠧ𝟶ڠ-。𑄳; ࠧ0ڠ-.𑄳; [B1, B3, B6, V3, V5]; xn--0--p3d67m.xn--v80d; ; ; # ࠧ0ڠ-.𑄳
+ࠧ0ڠ-。𑄳; ࠧ0ڠ-.𑄳; [B1, B3, B6, V3, V5]; xn--0--p3d67m.xn--v80d; ; ; # ࠧ0ڠ-.𑄳
+xn--0--p3d67m.xn--v80d; ࠧ0ڠ-.𑄳; [B1, B3, B6, V3, V5]; xn--0--p3d67m.xn--v80d; ; ; # ࠧ0ڠ-.𑄳
+ς.ﷁ🞛⒈; ς.فمي🞛⒈; [P1, V6]; xn--3xa.xn--dhbip2802atb20c; ; xn--4xa.xn--dhbip2802atb20c; # ς.فمي🞛⒈
+ς.فمي🞛1.; ; ; xn--3xa.xn--1-gocmu97674d.; ; xn--4xa.xn--1-gocmu97674d.; # ς.فمي🞛1.
+Σ.فمي🞛1.; σ.فمي🞛1.; ; xn--4xa.xn--1-gocmu97674d.; ; ; # σ.فمي🞛1.
+σ.فمي🞛1.; ; ; xn--4xa.xn--1-gocmu97674d.; ; ; # σ.فمي🞛1.
+xn--4xa.xn--1-gocmu97674d.; σ.فمي🞛1.; ; xn--4xa.xn--1-gocmu97674d.; ; ; # σ.فمي🞛1.
+xn--3xa.xn--1-gocmu97674d.; ς.فمي🞛1.; ; xn--3xa.xn--1-gocmu97674d.; ; ; # ς.فمي🞛1.
+Σ.ﷁ🞛⒈; σ.فمي🞛⒈; [P1, V6]; xn--4xa.xn--dhbip2802atb20c; ; ; # σ.فمي🞛⒈
+σ.ﷁ🞛⒈; σ.فمي🞛⒈; [P1, V6]; xn--4xa.xn--dhbip2802atb20c; ; ; # σ.فمي🞛⒈
+xn--4xa.xn--dhbip2802atb20c; σ.فمي🞛⒈; [V6]; xn--4xa.xn--dhbip2802atb20c; ; ; # σ.فمي🞛⒈
+xn--3xa.xn--dhbip2802atb20c; ς.فمي🞛⒈; [V6]; xn--3xa.xn--dhbip2802atb20c; ; ; # ς.فمي🞛⒈
+🗩-。𐹻󐞆񥉮; 🗩-.𐹻󐞆񥉮; [B1, P1, V3, V6]; xn----6t3s.xn--zo0d4811u6ru6a; ; ; # 🗩-.𐹻
+🗩-。𐹻󐞆񥉮; 🗩-.𐹻󐞆񥉮; [B1, P1, V3, V6]; xn----6t3s.xn--zo0d4811u6ru6a; ; ; # 🗩-.𐹻
+xn----6t3s.xn--zo0d4811u6ru6a; 🗩-.𐹻󐞆񥉮; [B1, V3, V6]; xn----6t3s.xn--zo0d4811u6ru6a; ; ; # 🗩-.𐹻
+𐡜-🔪。𝟻‌𐿀; 𐡜-🔪.5‌𐿀; [B1, B3, C1]; xn----5j4iv089c.xn--5-sgn7149h; ; xn----5j4iv089c.xn--5-bn7i; [B1, B3] # 𐡜-🔪.5𐿀
+𐡜-🔪。5‌𐿀; 𐡜-🔪.5‌𐿀; [B1, B3, C1]; xn----5j4iv089c.xn--5-sgn7149h; ; xn----5j4iv089c.xn--5-bn7i; [B1, B3] # 𐡜-🔪.5𐿀
+xn----5j4iv089c.xn--5-bn7i; 𐡜-🔪.5𐿀; [B1, B3]; xn----5j4iv089c.xn--5-bn7i; ; ; # 𐡜-🔪.5𐿀
+xn----5j4iv089c.xn--5-sgn7149h; 𐡜-🔪.5‌𐿀; [B1, B3, C1]; xn----5j4iv089c.xn--5-sgn7149h; ; ; # 𐡜-🔪.5𐿀
+𐹣늿‍ß.ߏ0ּ; 𐹣늿‍ß.ߏ0ּ; [B1, C2]; xn--zca770n5s4hev6c.xn--0-vgc50n; ; xn--ss-i05i7041a.xn--0-vgc50n; [B1] # 𐹣늿ß.ߏ0ּ
+𐹣늿‍ß.ߏ0ּ; 𐹣늿‍ß.ߏ0ּ; [B1, C2]; xn--zca770n5s4hev6c.xn--0-vgc50n; ; xn--ss-i05i7041a.xn--0-vgc50n; [B1] # 𐹣늿ß.ߏ0ּ
+𐹣늿‍ß.ߏ0ּ; ; [B1, C2]; xn--zca770n5s4hev6c.xn--0-vgc50n; ; xn--ss-i05i7041a.xn--0-vgc50n; [B1] # 𐹣늿ß.ߏ0ּ
+𐹣늿‍ß.ߏ0ּ; 𐹣늿‍ß.ߏ0ּ; [B1, C2]; xn--zca770n5s4hev6c.xn--0-vgc50n; ; xn--ss-i05i7041a.xn--0-vgc50n; [B1] # 𐹣늿ß.ߏ0ּ
+𐹣늿‍SS.ߏ0ּ; 𐹣늿‍ss.ߏ0ּ; [B1, C2]; xn--ss-l1tu910fo0xd.xn--0-vgc50n; ; xn--ss-i05i7041a.xn--0-vgc50n; [B1] # 𐹣늿ss.ߏ0ּ
+𐹣늿‍SS.ߏ0ּ; 𐹣늿‍ss.ߏ0ּ; [B1, C2]; xn--ss-l1tu910fo0xd.xn--0-vgc50n; ; xn--ss-i05i7041a.xn--0-vgc50n; [B1] # 𐹣늿ss.ߏ0ּ
+𐹣늿‍ss.ߏ0ּ; ; [B1, C2]; xn--ss-l1tu910fo0xd.xn--0-vgc50n; ; xn--ss-i05i7041a.xn--0-vgc50n; [B1] # 𐹣늿ss.ߏ0ּ
+𐹣늿‍ss.ߏ0ּ; 𐹣늿‍ss.ߏ0ּ; [B1, C2]; xn--ss-l1tu910fo0xd.xn--0-vgc50n; ; xn--ss-i05i7041a.xn--0-vgc50n; [B1] # 𐹣늿ss.ߏ0ּ
+xn--ss-i05i7041a.xn--0-vgc50n; 𐹣늿ss.ߏ0ּ; [B1]; xn--ss-i05i7041a.xn--0-vgc50n; ; ; # 𐹣늿ss.ߏ0ּ
+xn--ss-l1tu910fo0xd.xn--0-vgc50n; 𐹣늿‍ss.ߏ0ּ; [B1, C2]; xn--ss-l1tu910fo0xd.xn--0-vgc50n; ; ; # 𐹣늿ss.ߏ0ּ
+𐹣늿‍Ss.ߏ0ּ; 𐹣늿‍ss.ߏ0ּ; [B1, C2]; xn--ss-l1tu910fo0xd.xn--0-vgc50n; ; xn--ss-i05i7041a.xn--0-vgc50n; [B1] # 𐹣늿ss.ߏ0ּ
+𐹣늿‍Ss.ߏ0ּ; 𐹣늿‍ss.ߏ0ּ; [B1, C2]; xn--ss-l1tu910fo0xd.xn--0-vgc50n; ; xn--ss-i05i7041a.xn--0-vgc50n; [B1] # 𐹣늿ss.ߏ0ּ
+xn--zca770n5s4hev6c.xn--0-vgc50n; 𐹣늿‍ß.ߏ0ּ; [B1, C2]; xn--zca770n5s4hev6c.xn--0-vgc50n; ; ; # 𐹣늿ß.ߏ0ּ
+𐹣늿‍SS.ߏ0ּ; 𐹣늿‍ss.ߏ0ּ; [B1, C2]; xn--ss-l1tu910fo0xd.xn--0-vgc50n; ; xn--ss-i05i7041a.xn--0-vgc50n; [B1] # 𐹣늿ss.ߏ0ּ
+𐹣늿‍SS.ߏ0ּ; 𐹣늿‍ss.ߏ0ּ; [B1, C2]; xn--ss-l1tu910fo0xd.xn--0-vgc50n; ; xn--ss-i05i7041a.xn--0-vgc50n; [B1] # 𐹣늿ss.ߏ0ּ
+𐹣늿‍ss.ߏ0ּ; 𐹣늿‍ss.ߏ0ּ; [B1, C2]; xn--ss-l1tu910fo0xd.xn--0-vgc50n; ; xn--ss-i05i7041a.xn--0-vgc50n; [B1] # 𐹣늿ss.ߏ0ּ
+𐹣늿‍ss.ߏ0ּ; 𐹣늿‍ss.ߏ0ּ; [B1, C2]; xn--ss-l1tu910fo0xd.xn--0-vgc50n; ; xn--ss-i05i7041a.xn--0-vgc50n; [B1] # 𐹣늿ss.ߏ0ּ
+𐹣늿‍Ss.ߏ0ּ; 𐹣늿‍ss.ߏ0ּ; [B1, C2]; xn--ss-l1tu910fo0xd.xn--0-vgc50n; ; xn--ss-i05i7041a.xn--0-vgc50n; [B1] # 𐹣늿ss.ߏ0ּ
+𐹣늿‍Ss.ߏ0ּ; 𐹣늿‍ss.ߏ0ּ; [B1, C2]; xn--ss-l1tu910fo0xd.xn--0-vgc50n; ; xn--ss-i05i7041a.xn--0-vgc50n; [B1] # 𐹣늿ss.ߏ0ּ
+9󠇥.󪴴ᢓ; 9.󪴴ᢓ; [P1, V6]; 9.xn--dbf91222q; ; ; # 9.ᢓ
+9󠇥.󪴴ᢓ; 9.󪴴ᢓ; [P1, V6]; 9.xn--dbf91222q; ; ; # 9.ᢓ
+9.xn--dbf91222q; 9.󪴴ᢓ; [V6]; 9.xn--dbf91222q; ; ; # 9.ᢓ
+‌ᅠ.𐫭🠗ß⽟; ‌ᅠ.𐫭🠗ß玉; [B1, B2, B3, C1, P1, V6]; xn--0ug7719f.xn--zca2289c550e0iwi; ; xn--cl7c.xn--ss-je6eq954cp25j; [B2, B3, P1, V6] # .𐫭🠗ß玉
+‌ᅠ.𐫭🠗ß玉; ; [B1, B2, B3, C1, P1, V6]; xn--psd526e.xn--zca2289c550e0iwi; ; xn--psd.xn--ss-je6eq954cp25j; [B2, B3, P1, V6] # .𐫭🠗ß玉
+‌ᅠ.𐫭🠗SS玉; ‌ᅠ.𐫭🠗ss玉; [B1, B2, B3, C1, P1, V6]; xn--psd526e.xn--ss-je6eq954cp25j; ; xn--psd.xn--ss-je6eq954cp25j; [B2, B3, P1, V6] # .𐫭🠗ss玉
+‌ᅠ.𐫭🠗ss玉; ; [B1, B2, B3, C1, P1, V6]; xn--psd526e.xn--ss-je6eq954cp25j; ; xn--psd.xn--ss-je6eq954cp25j; [B2, B3, P1, V6] # .𐫭🠗ss玉
+‌ᅠ.𐫭🠗Ss玉; ‌ᅠ.𐫭🠗ss玉; [B1, B2, B3, C1, P1, V6]; xn--psd526e.xn--ss-je6eq954cp25j; ; xn--psd.xn--ss-je6eq954cp25j; [B2, B3, P1, V6] # .𐫭🠗ss玉
+xn--psd.xn--ss-je6eq954cp25j; ᅠ.𐫭🠗ss玉; [B2, B3, V6]; xn--psd.xn--ss-je6eq954cp25j; ; ; # .𐫭🠗ss玉
+xn--psd526e.xn--ss-je6eq954cp25j; ‌ᅠ.𐫭🠗ss玉; [B1, B2, B3, C1, V6]; xn--psd526e.xn--ss-je6eq954cp25j; ; ; # .𐫭🠗ss玉
+xn--psd526e.xn--zca2289c550e0iwi; ‌ᅠ.𐫭🠗ß玉; [B1, B2, B3, C1, V6]; xn--psd526e.xn--zca2289c550e0iwi; ; ; # .𐫭🠗ß玉
+‌ᅠ.𐫭🠗SS⽟; ‌ᅠ.𐫭🠗ss玉; [B1, B2, B3, C1, P1, V6]; xn--0ug7719f.xn--ss-je6eq954cp25j; ; xn--cl7c.xn--ss-je6eq954cp25j; [B2, B3, P1, V6] # .𐫭🠗ss玉
+‌ᅠ.𐫭🠗ss⽟; ‌ᅠ.𐫭🠗ss玉; [B1, B2, B3, C1, P1, V6]; xn--0ug7719f.xn--ss-je6eq954cp25j; ; xn--cl7c.xn--ss-je6eq954cp25j; [B2, B3, P1, V6] # .𐫭🠗ss玉
+‌ᅠ.𐫭🠗Ss⽟; ‌ᅠ.𐫭🠗ss玉; [B1, B2, B3, C1, P1, V6]; xn--0ug7719f.xn--ss-je6eq954cp25j; ; xn--cl7c.xn--ss-je6eq954cp25j; [B2, B3, P1, V6] # .𐫭🠗ss玉
+xn--cl7c.xn--ss-je6eq954cp25j; ᅠ.𐫭🠗ss玉; [B2, B3, V6]; xn--cl7c.xn--ss-je6eq954cp25j; ; ; # .𐫭🠗ss玉
+xn--0ug7719f.xn--ss-je6eq954cp25j; ‌ᅠ.𐫭🠗ss玉; [B1, B2, B3, C1, V6]; xn--0ug7719f.xn--ss-je6eq954cp25j; ; ; # .𐫭🠗ss玉
+xn--0ug7719f.xn--zca2289c550e0iwi; ‌ᅠ.𐫭🠗ß玉; [B1, B2, B3, C1, V6]; xn--0ug7719f.xn--zca2289c550e0iwi; ; ; # .𐫭🠗ß玉
+︒Ⴖͦ.‌; ︒Ⴖͦ.‌; [C1, P1, V6]; xn--hva929dl29p.xn--0ug; ; xn--hva929dl29p.; [P1, V6] # ︒Ⴖͦ.
+。Ⴖͦ.‌; .Ⴖͦ.‌; [C1, P1, V6, X4_2]; .xn--hva929d.xn--0ug; [C1, P1, V6, A4_2]; .xn--hva929d.; [P1, V6, A4_2] # .Ⴖͦ.
+。ⴖͦ.‌; .ⴖͦ.‌; [C1, X4_2]; .xn--hva754s.xn--0ug; [C1, A4_2]; .xn--hva754s.; [A4_2] # .ⴖͦ.
+.xn--hva754s.; .ⴖͦ.; [X4_2]; .xn--hva754s.; [A4_2]; ; # .ⴖͦ.
+.xn--hva754s.xn--0ug; .ⴖͦ.‌; [C1, X4_2]; .xn--hva754s.xn--0ug; [C1, A4_2]; ; # .ⴖͦ.
+.xn--hva929d.; .Ⴖͦ.; [V6, X4_2]; .xn--hva929d.; [V6, A4_2]; ; # .Ⴖͦ.
+.xn--hva929d.xn--0ug; .Ⴖͦ.‌; [C1, V6, X4_2]; .xn--hva929d.xn--0ug; [C1, V6, A4_2]; ; # .Ⴖͦ.
+︒ⴖͦ.‌; ︒ⴖͦ.‌; [C1, P1, V6]; xn--hva754sy94k.xn--0ug; ; xn--hva754sy94k.; [P1, V6] # ︒ⴖͦ.
+xn--hva754sy94k.; ︒ⴖͦ.; [V6]; xn--hva754sy94k.; ; ; # ︒ⴖͦ.
+xn--hva754sy94k.xn--0ug; ︒ⴖͦ.‌; [C1, V6]; xn--hva754sy94k.xn--0ug; ; ; # ︒ⴖͦ.
+xn--hva929dl29p.; ︒Ⴖͦ.; [V6]; xn--hva929dl29p.; ; ; # ︒Ⴖͦ.
+xn--hva929dl29p.xn--0ug; ︒Ⴖͦ.‌; [C1, V6]; xn--hva929dl29p.xn--0ug; ; ; # ︒Ⴖͦ.
+xn--hva754s.; ⴖͦ.; ; xn--hva754s.; ; ; # ⴖͦ.
+ⴖͦ.; ; ; xn--hva754s.; ; ; # ⴖͦ.
+Ⴖͦ.; ; [P1, V6]; xn--hva929d.; ; ; # Ⴖͦ.
+xn--hva929d.; Ⴖͦ.; [V6]; xn--hva929d.; ; ; # Ⴖͦ.
+ࢻ.‌Ⴃ𞀒; ࢻ.‌Ⴃ𞀒; [B1, C1, P1, V6]; xn--hzb.xn--bnd300f7225a; ; xn--hzb.xn--bnd2938u; [P1, V6] # ࢻ.Ⴃ𞀒
+ࢻ.‌Ⴃ𞀒; ; [B1, C1, P1, V6]; xn--hzb.xn--bnd300f7225a; ; xn--hzb.xn--bnd2938u; [P1, V6] # ࢻ.Ⴃ𞀒
+ࢻ.‌ⴃ𞀒; ; [B1, C1]; xn--hzb.xn--0ug822cp045a; ; xn--hzb.xn--ukj4430l; [] # ࢻ.ⴃ𞀒
+xn--hzb.xn--ukj4430l; ࢻ.ⴃ𞀒; ; xn--hzb.xn--ukj4430l; ; ; # ࢻ.ⴃ𞀒
+ࢻ.ⴃ𞀒; ; ; xn--hzb.xn--ukj4430l; ; ; # ࢻ.ⴃ𞀒
+ࢻ.Ⴃ𞀒; ; [P1, V6]; xn--hzb.xn--bnd2938u; ; ; # ࢻ.Ⴃ𞀒
+xn--hzb.xn--bnd2938u; ࢻ.Ⴃ𞀒; [V6]; xn--hzb.xn--bnd2938u; ; ; # ࢻ.Ⴃ𞀒
+xn--hzb.xn--0ug822cp045a; ࢻ.‌ⴃ𞀒; [B1, C1]; xn--hzb.xn--0ug822cp045a; ; ; # ࢻ.ⴃ𞀒
+xn--hzb.xn--bnd300f7225a; ࢻ.‌Ⴃ𞀒; [B1, C1, V6]; xn--hzb.xn--bnd300f7225a; ; ; # ࢻ.Ⴃ𞀒
+ࢻ.‌ⴃ𞀒; ࢻ.‌ⴃ𞀒; [B1, C1]; xn--hzb.xn--0ug822cp045a; ; xn--hzb.xn--ukj4430l; [] # ࢻ.ⴃ𞀒
+‍‌。2䫷󠧷; ‍‌.2䫷󠧷; [C1, C2, P1, V6]; xn--0ugb.xn--2-me5ay1273i; ; .xn--2-me5ay1273i; [P1, V6, A4_2] # .2䫷
+‍‌。2䫷󠧷; ‍‌.2䫷󠧷; [C1, C2, P1, V6]; xn--0ugb.xn--2-me5ay1273i; ; .xn--2-me5ay1273i; [P1, V6, A4_2] # .2䫷
+.xn--2-me5ay1273i; .2䫷󠧷; [V6, X4_2]; .xn--2-me5ay1273i; [V6, A4_2]; ; # .2䫷
+xn--0ugb.xn--2-me5ay1273i; ‍‌.2䫷󠧷; [C1, C2, V6]; xn--0ugb.xn--2-me5ay1273i; ; ; # .2䫷
+-𞀤󜠐。򈬖; -𞀤󜠐.򈬖; [P1, V3, V6]; xn----rq4re4997d.xn--l707b; ; ; # -𞀤.
+xn----rq4re4997d.xn--l707b; -𞀤󜠐.򈬖; [V3, V6]; xn----rq4re4997d.xn--l707b; ; ; # -𞀤.
+󳛂︒‌㟀.ؤ⒈; 󳛂︒‌㟀.ؤ⒈; [C1, P1, V6]; xn--0ug754gxl4ldlt0k.xn--jgb476m; ; xn--etlt457ccrq7h.xn--jgb476m; [P1, V6] # ︒㟀.ؤ⒈
+󳛂︒‌㟀.ؤ⒈; 󳛂︒‌㟀.ؤ⒈; [C1, P1, V6]; xn--0ug754gxl4ldlt0k.xn--jgb476m; ; xn--etlt457ccrq7h.xn--jgb476m; [P1, V6] # ︒㟀.ؤ⒈
+󳛂。‌㟀.ؤ1.; 󳛂.‌㟀.ؤ1.; [B1, C1, P1, V6]; xn--z272f.xn--0ug754g.xn--1-smc.; ; xn--z272f.xn--etl.xn--1-smc.; [P1, V6] # .㟀.ؤ1.
+󳛂。‌㟀.ؤ1.; 󳛂.‌㟀.ؤ1.; [B1, C1, P1, V6]; xn--z272f.xn--0ug754g.xn--1-smc.; ; xn--z272f.xn--etl.xn--1-smc.; [P1, V6] # .㟀.ؤ1.
+xn--z272f.xn--etl.xn--1-smc.; 󳛂.㟀.ؤ1.; [V6]; xn--z272f.xn--etl.xn--1-smc.; ; ; # .㟀.ؤ1.
+xn--z272f.xn--0ug754g.xn--1-smc.; 󳛂.‌㟀.ؤ1.; [B1, C1, V6]; xn--z272f.xn--0ug754g.xn--1-smc.; ; ; # .㟀.ؤ1.
+xn--etlt457ccrq7h.xn--jgb476m; 󳛂︒㟀.ؤ⒈; [V6]; xn--etlt457ccrq7h.xn--jgb476m; ; ; # ︒㟀.ؤ⒈
+xn--0ug754gxl4ldlt0k.xn--jgb476m; 󳛂︒‌㟀.ؤ⒈; [C1, V6]; xn--0ug754gxl4ldlt0k.xn--jgb476m; ; ; # ︒㟀.ؤ⒈
+𑲜ߊ𝅼。-‍; 𑲜ߊ𝅼.-‍; [B1, C2, V3, V5]; xn--lsb5482l7nre.xn----ugn; ; xn--lsb5482l7nre.-; [B1, V3, V5] # 𑲜ߊ𝅼.-
+xn--lsb5482l7nre.-; 𑲜ߊ𝅼.-; [B1, V3, V5]; xn--lsb5482l7nre.-; ; ; # 𑲜ߊ𝅼.-
+xn--lsb5482l7nre.xn----ugn; 𑲜ߊ𝅼.-‍; [B1, C2, V3, V5]; xn--lsb5482l7nre.xn----ugn; ; ; # 𑲜ߊ𝅼.-
+‌.Ⴉ≠𐫶; ‌.Ⴉ≠𐫶; [B1, B5, B6, C1, P1, V6]; xn--0ug.xn--hnd481gv73o; ; .xn--hnd481gv73o; [B5, B6, P1, V6, A4_2] # .Ⴉ≠𐫶
+‌.Ⴉ≠𐫶; ‌.Ⴉ≠𐫶; [B1, B5, B6, C1, P1, V6]; xn--0ug.xn--hnd481gv73o; ; .xn--hnd481gv73o; [B5, B6, P1, V6, A4_2] # .Ⴉ≠𐫶
+‌.Ⴉ≠𐫶; ; [B1, B5, B6, C1, P1, V6]; xn--0ug.xn--hnd481gv73o; ; .xn--hnd481gv73o; [B5, B6, P1, V6, A4_2] # .Ⴉ≠𐫶
+‌.Ⴉ≠𐫶; ‌.Ⴉ≠𐫶; [B1, B5, B6, C1, P1, V6]; xn--0ug.xn--hnd481gv73o; ; .xn--hnd481gv73o; [B5, B6, P1, V6, A4_2] # .Ⴉ≠𐫶
+‌.ⴉ≠𐫶; ‌.ⴉ≠𐫶; [B1, B5, B6, C1, P1, V6]; xn--0ug.xn--1chx23bzj4p; ; .xn--1chx23bzj4p; [B5, B6, P1, V6, A4_2] # .ⴉ≠𐫶
+‌.ⴉ≠𐫶; ; [B1, B5, B6, C1, P1, V6]; xn--0ug.xn--1chx23bzj4p; ; .xn--1chx23bzj4p; [B5, B6, P1, V6, A4_2] # .ⴉ≠𐫶
+.xn--1chx23bzj4p; .ⴉ≠𐫶; [B5, B6, V6, X4_2]; .xn--1chx23bzj4p; [B5, B6, V6, A4_2]; ; # .ⴉ≠𐫶
+xn--0ug.xn--1chx23bzj4p; ‌.ⴉ≠𐫶; [B1, B5, B6, C1, V6]; xn--0ug.xn--1chx23bzj4p; ; ; # .ⴉ≠𐫶
+.xn--hnd481gv73o; .Ⴉ≠𐫶; [B5, B6, V6, X4_2]; .xn--hnd481gv73o; [B5, B6, V6, A4_2]; ; # .Ⴉ≠𐫶
+xn--0ug.xn--hnd481gv73o; ‌.Ⴉ≠𐫶; [B1, B5, B6, C1, V6]; xn--0ug.xn--hnd481gv73o; ; ; # .Ⴉ≠𐫶
+‌.ⴉ≠𐫶; ‌.ⴉ≠𐫶; [B1, B5, B6, C1, P1, V6]; xn--0ug.xn--1chx23bzj4p; ; .xn--1chx23bzj4p; [B5, B6, P1, V6, A4_2] # .ⴉ≠𐫶
+‌.ⴉ≠𐫶; ‌.ⴉ≠𐫶; [B1, B5, B6, C1, P1, V6]; xn--0ug.xn--1chx23bzj4p; ; .xn--1chx23bzj4p; [B5, B6, P1, V6, A4_2] # .ⴉ≠𐫶
+ݐ。≯ς; ݐ.≯ς; [B1, P1, V6]; xn--3ob.xn--3xa918m; ; xn--3ob.xn--4xa718m; # ݐ.≯ς
+ݐ。≯ς; ݐ.≯ς; [B1, P1, V6]; xn--3ob.xn--3xa918m; ; xn--3ob.xn--4xa718m; # ݐ.≯ς
+ݐ。≯Σ; ݐ.≯σ; [B1, P1, V6]; xn--3ob.xn--4xa718m; ; ; # ݐ.≯σ
+ݐ。≯Σ; ݐ.≯σ; [B1, P1, V6]; xn--3ob.xn--4xa718m; ; ; # ݐ.≯σ
+ݐ。≯σ; ݐ.≯σ; [B1, P1, V6]; xn--3ob.xn--4xa718m; ; ; # ݐ.≯σ
+ݐ。≯σ; ݐ.≯σ; [B1, P1, V6]; xn--3ob.xn--4xa718m; ; ; # ݐ.≯σ
+xn--3ob.xn--4xa718m; ݐ.≯σ; [B1, V6]; xn--3ob.xn--4xa718m; ; ; # ݐ.≯σ
+xn--3ob.xn--3xa918m; ݐ.≯ς; [B1, V6]; xn--3ob.xn--3xa918m; ; ; # ݐ.≯ς
+߼𐸆.𓖏︒񊨩Ⴐ; ; [P1, V6]; xn--0tb8725k.xn--ond3562jt18a7py9c; ; ; # .︒Ⴐ
+߼𐸆.𓖏。񊨩Ⴐ; ߼𐸆.𓖏.񊨩Ⴐ; [P1, V6]; xn--0tb8725k.xn--tu8d.xn--ond97931d; ; ; # ..Ⴐ
+߼𐸆.𓖏。񊨩ⴐ; ߼𐸆.𓖏.񊨩ⴐ; [P1, V6]; xn--0tb8725k.xn--tu8d.xn--7kj73887a; ; ; # ..ⴐ
+xn--0tb8725k.xn--tu8d.xn--7kj73887a; ߼𐸆.𓖏.񊨩ⴐ; [V6]; xn--0tb8725k.xn--tu8d.xn--7kj73887a; ; ; # ..ⴐ
+xn--0tb8725k.xn--tu8d.xn--ond97931d; ߼𐸆.𓖏.񊨩Ⴐ; [V6]; xn--0tb8725k.xn--tu8d.xn--ond97931d; ; ; # ..Ⴐ
+߼𐸆.𓖏︒񊨩ⴐ; ; [P1, V6]; xn--0tb8725k.xn--7kj9008dt18a7py9c; ; ; # .︒ⴐ
+xn--0tb8725k.xn--7kj9008dt18a7py9c; ߼𐸆.𓖏︒񊨩ⴐ; [V6]; xn--0tb8725k.xn--7kj9008dt18a7py9c; ; ; # .︒ⴐ
+xn--0tb8725k.xn--ond3562jt18a7py9c; ߼𐸆.𓖏︒񊨩Ⴐ; [V6]; xn--0tb8725k.xn--ond3562jt18a7py9c; ; ; # .︒Ⴐ
+Ⴥ⚭󠖫⋃。𑌼; Ⴥ⚭󠖫⋃.𑌼; [P1, V5, V6]; xn--9nd623g4zc5z060c.xn--ro1d; ; ; # Ⴥ⚭⋃.𑌼
+Ⴥ⚭󠖫⋃。𑌼; Ⴥ⚭󠖫⋃.𑌼; [P1, V5, V6]; xn--9nd623g4zc5z060c.xn--ro1d; ; ; # Ⴥ⚭⋃.𑌼
+ⴥ⚭󠖫⋃。𑌼; ⴥ⚭󠖫⋃.𑌼; [P1, V5, V6]; xn--vfh16m67gx1162b.xn--ro1d; ; ; # ⴥ⚭⋃.𑌼
+xn--vfh16m67gx1162b.xn--ro1d; ⴥ⚭󠖫⋃.𑌼; [V5, V6]; xn--vfh16m67gx1162b.xn--ro1d; ; ; # ⴥ⚭⋃.𑌼
+xn--9nd623g4zc5z060c.xn--ro1d; Ⴥ⚭󠖫⋃.𑌼; [V5, V6]; xn--9nd623g4zc5z060c.xn--ro1d; ; ; # Ⴥ⚭⋃.𑌼
+ⴥ⚭󠖫⋃。𑌼; ⴥ⚭󠖫⋃.𑌼; [P1, V5, V6]; xn--vfh16m67gx1162b.xn--ro1d; ; ; # ⴥ⚭⋃.𑌼
+🄈。󠷳ࡄ; 🄈.󠷳ࡄ; [B1, P1, V6]; xn--107h.xn--2vb13094p; ; ; # 🄈.ࡄ
+7,。󠷳ࡄ; 7,.󠷳ࡄ; [B1, P1, V6]; 7,.xn--2vb13094p; ; ; # 7,.ࡄ
+7,.xn--2vb13094p; 7,.󠷳ࡄ; [B1, P1, V6]; 7,.xn--2vb13094p; ; ; # 7,.ࡄ
+xn--107h.xn--2vb13094p; 🄈.󠷳ࡄ; [B1, V6]; xn--107h.xn--2vb13094p; ; ; # 🄈.ࡄ
+≮ࡆ。섖쮖ß; ≮ࡆ.섖쮖ß; [B1, P1, V6]; xn--4vb505k.xn--zca7259goug; ; xn--4vb505k.xn--ss-5z4j006a; # ≮ࡆ.섖쮖ß
+≮ࡆ。섖쮖ß; ≮ࡆ.섖쮖ß; [B1, P1, V6]; xn--4vb505k.xn--zca7259goug; ; xn--4vb505k.xn--ss-5z4j006a; # ≮ࡆ.섖쮖ß
+≮ࡆ。섖쮖SS; ≮ࡆ.섖쮖ss; [B1, P1, V6]; xn--4vb505k.xn--ss-5z4j006a; ; ; # ≮ࡆ.섖쮖ss
+≮ࡆ。섖쮖SS; ≮ࡆ.섖쮖ss; [B1, P1, V6]; xn--4vb505k.xn--ss-5z4j006a; ; ; # ≮ࡆ.섖쮖ss
+≮ࡆ。섖쮖ss; ≮ࡆ.섖쮖ss; [B1, P1, V6]; xn--4vb505k.xn--ss-5z4j006a; ; ; # ≮ࡆ.섖쮖ss
+≮ࡆ。섖쮖ss; ≮ࡆ.섖쮖ss; [B1, P1, V6]; xn--4vb505k.xn--ss-5z4j006a; ; ; # ≮ࡆ.섖쮖ss
+xn--4vb505k.xn--ss-5z4j006a; ≮ࡆ.섖쮖ss; [B1, V6]; xn--4vb505k.xn--ss-5z4j006a; ; ; # ≮ࡆ.섖쮖ss
+≮ࡆ。섖쮖Ss; ≮ࡆ.섖쮖ss; [B1, P1, V6]; xn--4vb505k.xn--ss-5z4j006a; ; ; # ≮ࡆ.섖쮖ss
+≮ࡆ。섖쮖Ss; ≮ࡆ.섖쮖ss; [B1, P1, V6]; xn--4vb505k.xn--ss-5z4j006a; ; ; # ≮ࡆ.섖쮖ss
+xn--4vb505k.xn--zca7259goug; ≮ࡆ.섖쮖ß; [B1, V6]; xn--4vb505k.xn--zca7259goug; ; ; # ≮ࡆ.섖쮖ß
+󠆓⛏-。ꡒ; ⛏-.ꡒ; [V3]; xn----o9p.xn--rc9a; ; ; # ⛏-.ꡒ
+xn----o9p.xn--rc9a; ⛏-.ꡒ; [V3]; xn----o9p.xn--rc9a; ; ; # ⛏-.ꡒ
+޻𐹳ئ𑁆。ࢧڰ‌ᢒ; ޻𐹳ئ𑁆.ࢧڰ‌ᢒ; [B2, B3, P1, V6]; xn--lgb32f2753cosb.xn--jkb91hlz1azih; ; xn--lgb32f2753cosb.xn--jkb91hlz1a; # 𐹳ئ𑁆.ࢧڰᢒ
+޻𐹳ئ𑁆。ࢧڰ‌ᢒ; ޻𐹳ئ𑁆.ࢧڰ‌ᢒ; [B2, B3, P1, V6]; xn--lgb32f2753cosb.xn--jkb91hlz1azih; ; xn--lgb32f2753cosb.xn--jkb91hlz1a; # 𐹳ئ𑁆.ࢧڰᢒ
+xn--lgb32f2753cosb.xn--jkb91hlz1a; ޻𐹳ئ𑁆.ࢧڰᢒ; [B2, B3, V6]; xn--lgb32f2753cosb.xn--jkb91hlz1a; ; ; # 𐹳ئ𑁆.ࢧڰᢒ
+xn--lgb32f2753cosb.xn--jkb91hlz1azih; ޻𐹳ئ𑁆.ࢧڰ‌ᢒ; [B2, B3, V6]; xn--lgb32f2753cosb.xn--jkb91hlz1azih; ; ; # 𐹳ئ𑁆.ࢧڰᢒ
+ࠖ.𐨕𚚕; ; [B1, B2, B3, B6, P1, V5, V6]; xn--rub.xn--tr9c248x; ; ; # ࠖ.𐨕
+xn--rub.xn--tr9c248x; ࠖ.𐨕𚚕; [B1, B2, B3, B6, V5, V6]; xn--rub.xn--tr9c248x; ; ; # ࠖ.𐨕
+--。𽊆ݧ𐽋𞠬; --.𽊆ݧ𐽋𞠬; [B1, B5, B6, P1, V3, V6]; --.xn--rpb6226k77pfh58p; ; ; # --.ݧ𐽋𞠬
+--.xn--rpb6226k77pfh58p; --.𽊆ݧ𐽋𞠬; [B1, B5, B6, V3, V6]; --.xn--rpb6226k77pfh58p; ; ; # --.ݧ𐽋𞠬
+򛭦𐋥𹸐.≯ࢰࢦ󔛣; ; [B1, P1, V6]; xn--887c2298i5mv6a.xn--vybt688qm8981a; ; ; # 𐋥.≯ࢰࢦ
+򛭦𐋥𹸐.≯ࢰࢦ󔛣; 򛭦𐋥𹸐.≯ࢰࢦ󔛣; [B1, P1, V6]; xn--887c2298i5mv6a.xn--vybt688qm8981a; ; ; # 𐋥.≯ࢰࢦ
+xn--887c2298i5mv6a.xn--vybt688qm8981a; 򛭦𐋥𹸐.≯ࢰࢦ󔛣; [B1, V6]; xn--887c2298i5mv6a.xn--vybt688qm8981a; ; ; # 𐋥.≯ࢰࢦ
+䔛󠇒򤸞𐹧.-䤷; 䔛򤸞𐹧.-䤷; [B1, B5, B6, P1, V3, V6]; xn--2loy662coo60e.xn----0n4a; ; ; # 䔛𐹧.-䤷
+䔛󠇒򤸞𐹧.-䤷; 䔛򤸞𐹧.-䤷; [B1, B5, B6, P1, V3, V6]; xn--2loy662coo60e.xn----0n4a; ; ; # 䔛𐹧.-䤷
+xn--2loy662coo60e.xn----0n4a; 䔛򤸞𐹧.-䤷; [B1, B5, B6, V3, V6]; xn--2loy662coo60e.xn----0n4a; ; ; # 䔛𐹧.-䤷
+𐹩.‍-; 𐹩.‍-; [B1, C2, V3]; xn--ho0d.xn----tgn; ; xn--ho0d.-; [B1, V3] # 𐹩.-
+𐹩.‍-; ; [B1, C2, V3]; xn--ho0d.xn----tgn; ; xn--ho0d.-; [B1, V3] # 𐹩.-
+xn--ho0d.-; 𐹩.-; [B1, V3]; xn--ho0d.-; ; ; # 𐹩.-
+xn--ho0d.xn----tgn; 𐹩.‍-; [B1, C2, V3]; xn--ho0d.xn----tgn; ; ; # 𐹩.-
+񂈦帷。≯萺᷈-; 񂈦帷.≯萺᷈-; [P1, V3, V6]; xn--qutw175s.xn----mimu6tf67j; ; ; # 帷.≯萺᷈-
+񂈦帷。≯萺᷈-; 񂈦帷.≯萺᷈-; [P1, V3, V6]; xn--qutw175s.xn----mimu6tf67j; ; ; # 帷.≯萺᷈-
+񂈦帷。≯萺᷈-; 񂈦帷.≯萺᷈-; [P1, V3, V6]; xn--qutw175s.xn----mimu6tf67j; ; ; # 帷.≯萺᷈-
+񂈦帷。≯萺᷈-; 񂈦帷.≯萺᷈-; [P1, V3, V6]; xn--qutw175s.xn----mimu6tf67j; ; ; # 帷.≯萺᷈-
+xn--qutw175s.xn----mimu6tf67j; 񂈦帷.≯萺᷈-; [V3, V6]; xn--qutw175s.xn----mimu6tf67j; ; ; # 帷.≯萺᷈-
+‍攌꯭。ᢖ-Ⴘ; ‍攌꯭.ᢖ-Ⴘ; [C2, P1, V6]; xn--1ug592ykp6b.xn----k1g451d; ; xn--p9ut19m.xn----k1g451d; [P1, V6] # 攌꯭.ᢖ-Ⴘ
+‍攌꯭。ᢖ-ⴘ; ‍攌꯭.ᢖ-ⴘ; [C2]; xn--1ug592ykp6b.xn----mck373i; ; xn--p9ut19m.xn----mck373i; [] # 攌꯭.ᢖ-ⴘ
+xn--p9ut19m.xn----mck373i; 攌꯭.ᢖ-ⴘ; ; xn--p9ut19m.xn----mck373i; ; ; # 攌꯭.ᢖ-ⴘ
+攌꯭.ᢖ-ⴘ; ; ; xn--p9ut19m.xn----mck373i; ; ; # 攌꯭.ᢖ-ⴘ
+攌꯭.ᢖ-Ⴘ; ; [P1, V6]; xn--p9ut19m.xn----k1g451d; ; ; # 攌꯭.ᢖ-Ⴘ
+xn--p9ut19m.xn----k1g451d; 攌꯭.ᢖ-Ⴘ; [V6]; xn--p9ut19m.xn----k1g451d; ; ; # 攌꯭.ᢖ-Ⴘ
+xn--1ug592ykp6b.xn----mck373i; ‍攌꯭.ᢖ-ⴘ; [C2]; xn--1ug592ykp6b.xn----mck373i; ; ; # 攌꯭.ᢖ-ⴘ
+xn--1ug592ykp6b.xn----k1g451d; ‍攌꯭.ᢖ-Ⴘ; [C2, V6]; xn--1ug592ykp6b.xn----k1g451d; ; ; # 攌꯭.ᢖ-Ⴘ
+‌ꖨ.⒗3툒۳; ‌ꖨ.⒗3툒۳; [C1, P1, V6]; xn--0ug2473c.xn--3-nyc678tu07m; ; xn--9r8a.xn--3-nyc678tu07m; [P1, V6] # ꖨ.⒗3툒۳
+‌ꖨ.⒗3툒۳; ‌ꖨ.⒗3툒۳; [C1, P1, V6]; xn--0ug2473c.xn--3-nyc678tu07m; ; xn--9r8a.xn--3-nyc678tu07m; [P1, V6] # ꖨ.⒗3툒۳
+‌ꖨ.16.3툒۳; ; [C1]; xn--0ug2473c.16.xn--3-nyc0117m; ; xn--9r8a.16.xn--3-nyc0117m; [] # ꖨ.16.3툒۳
+‌ꖨ.16.3툒۳; ‌ꖨ.16.3툒۳; [C1]; xn--0ug2473c.16.xn--3-nyc0117m; ; xn--9r8a.16.xn--3-nyc0117m; [] # ꖨ.16.3툒۳
+xn--9r8a.16.xn--3-nyc0117m; ꖨ.16.3툒۳; ; xn--9r8a.16.xn--3-nyc0117m; ; ; # ꖨ.16.3툒۳
+ꖨ.16.3툒۳; ; ; xn--9r8a.16.xn--3-nyc0117m; ; ; # ꖨ.16.3툒۳
+ꖨ.16.3툒۳; ꖨ.16.3툒۳; ; xn--9r8a.16.xn--3-nyc0117m; ; ; # ꖨ.16.3툒۳
+xn--0ug2473c.16.xn--3-nyc0117m; ‌ꖨ.16.3툒۳; [C1]; xn--0ug2473c.16.xn--3-nyc0117m; ; ; # ꖨ.16.3툒۳
+xn--9r8a.xn--3-nyc678tu07m; ꖨ.⒗3툒۳; [V6]; xn--9r8a.xn--3-nyc678tu07m; ; ; # ꖨ.⒗3툒۳
+xn--0ug2473c.xn--3-nyc678tu07m; ‌ꖨ.⒗3툒۳; [C1, V6]; xn--0ug2473c.xn--3-nyc678tu07m; ; ; # ꖨ.⒗3툒۳
+⒈걾6.𐱁ې; ; [B1, P1, V6]; xn--6-dcps419c.xn--glb1794k; ; ; # ⒈걾6.𐱁ې
+⒈걾6.𐱁ې; ⒈걾6.𐱁ې; [B1, P1, V6]; xn--6-dcps419c.xn--glb1794k; ; ; # ⒈걾6.𐱁ې
+1.걾6.𐱁ې; ; [B1]; 1.xn--6-945e.xn--glb1794k; ; ; # 1.걾6.𐱁ې
+1.걾6.𐱁ې; 1.걾6.𐱁ې; [B1]; 1.xn--6-945e.xn--glb1794k; ; ; # 1.걾6.𐱁ې
+1.xn--6-945e.xn--glb1794k; 1.걾6.𐱁ې; [B1]; 1.xn--6-945e.xn--glb1794k; ; ; # 1.걾6.𐱁ې
+xn--6-dcps419c.xn--glb1794k; ⒈걾6.𐱁ې; [B1, V6]; xn--6-dcps419c.xn--glb1794k; ; ; # ⒈걾6.𐱁ې
+𐲞𝟶≮≮.󠀧ع; 𐳞0≮≮.󠀧ع; [B1, B3, P1, V6]; xn--0-ngoa5711v.xn--4gb31034p; ; ; # 𐳞0≮≮.ع
+𐲞𝟶≮≮.󠀧ع; 𐳞0≮≮.󠀧ع; [B1, B3, P1, V6]; xn--0-ngoa5711v.xn--4gb31034p; ; ; # 𐳞0≮≮.ع
+𐲞0≮≮.󠀧ع; 𐳞0≮≮.󠀧ع; [B1, B3, P1, V6]; xn--0-ngoa5711v.xn--4gb31034p; ; ; # 𐳞0≮≮.ع
+𐲞0≮≮.󠀧ع; 𐳞0≮≮.󠀧ع; [B1, B3, P1, V6]; xn--0-ngoa5711v.xn--4gb31034p; ; ; # 𐳞0≮≮.ع
+𐳞0≮≮.󠀧ع; 𐳞0≮≮.󠀧ع; [B1, B3, P1, V6]; xn--0-ngoa5711v.xn--4gb31034p; ; ; # 𐳞0≮≮.ع
+𐳞0≮≮.󠀧ع; ; [B1, B3, P1, V6]; xn--0-ngoa5711v.xn--4gb31034p; ; ; # 𐳞0≮≮.ع
+xn--0-ngoa5711v.xn--4gb31034p; 𐳞0≮≮.󠀧ع; [B1, B3, V6]; xn--0-ngoa5711v.xn--4gb31034p; ; ; # 𐳞0≮≮.ع
+𐳞𝟶≮≮.󠀧ع; 𐳞0≮≮.󠀧ع; [B1, B3, P1, V6]; xn--0-ngoa5711v.xn--4gb31034p; ; ; # 𐳞0≮≮.ع
+𐳞𝟶≮≮.󠀧ع; 𐳞0≮≮.󠀧ع; [B1, B3, P1, V6]; xn--0-ngoa5711v.xn--4gb31034p; ; ; # 𐳞0≮≮.ع
+ૣ.𐹺ᅟ; ; [B1, B3, B6, P1, V5, V6]; xn--8fc.xn--osd3070k; ; ; # ૣ.𐹺
+xn--8fc.xn--osd3070k; ૣ.𐹺ᅟ; [B1, B3, B6, V5, V6]; xn--8fc.xn--osd3070k; ; ; # ૣ.𐹺
+𝟏𝨙⸖.‍; 1𝨙⸖.‍; [C2]; xn--1-5bt6845n.xn--1ug; ; xn--1-5bt6845n.; [] # 1𝨙⸖.
+1𝨙⸖.‍; ; [C2]; xn--1-5bt6845n.xn--1ug; ; xn--1-5bt6845n.; [] # 1𝨙⸖.
+xn--1-5bt6845n.; 1𝨙⸖.; ; xn--1-5bt6845n.; ; ; # 1𝨙⸖.
+1𝨙⸖.; ; ; xn--1-5bt6845n.; ; ; # 1𝨙⸖.
+xn--1-5bt6845n.xn--1ug; 1𝨙⸖.‍; [C2]; xn--1-5bt6845n.xn--1ug; ; ; # 1𝨙⸖.
+𞤐≠ܦ᩠。-‌ߕ; 𞤲≠ܦ᩠.-‌ߕ; [B1, C1, P1, V3, V6]; xn--wnb859grzfzw60c.xn----kcd017p; ; xn--wnb859grzfzw60c.xn----kcd; [B1, P1, V3, V6] # 𞤲≠ܦ᩠.-ߕ
+𞤐≠ܦ᩠。-‌ߕ; 𞤲≠ܦ᩠.-‌ߕ; [B1, C1, P1, V3, V6]; xn--wnb859grzfzw60c.xn----kcd017p; ; xn--wnb859grzfzw60c.xn----kcd; [B1, P1, V3, V6] # 𞤲≠ܦ᩠.-ߕ
+𞤐≠ܦ᩠。-‌ߕ; 𞤲≠ܦ᩠.-‌ߕ; [B1, C1, P1, V3, V6]; xn--wnb859grzfzw60c.xn----kcd017p; ; xn--wnb859grzfzw60c.xn----kcd; [B1, P1, V3, V6] # 𞤲≠ܦ᩠.-ߕ
+𞤐≠ܦ᩠。-‌ߕ; 𞤲≠ܦ᩠.-‌ߕ; [B1, C1, P1, V3, V6]; xn--wnb859grzfzw60c.xn----kcd017p; ; xn--wnb859grzfzw60c.xn----kcd; [B1, P1, V3, V6] # 𞤲≠ܦ᩠.-ߕ
+𞤲≠ܦ᩠。-‌ߕ; 𞤲≠ܦ᩠.-‌ߕ; [B1, C1, P1, V3, V6]; xn--wnb859grzfzw60c.xn----kcd017p; ; xn--wnb859grzfzw60c.xn----kcd; [B1, P1, V3, V6] # 𞤲≠ܦ᩠.-ߕ
+𞤲≠ܦ᩠。-‌ߕ; 𞤲≠ܦ᩠.-‌ߕ; [B1, C1, P1, V3, V6]; xn--wnb859grzfzw60c.xn----kcd017p; ; xn--wnb859grzfzw60c.xn----kcd; [B1, P1, V3, V6] # 𞤲≠ܦ᩠.-ߕ
+xn--wnb859grzfzw60c.xn----kcd; 𞤲≠ܦ᩠.-ߕ; [B1, V3, V6]; xn--wnb859grzfzw60c.xn----kcd; ; ; # 𞤲≠ܦ᩠.-ߕ
+xn--wnb859grzfzw60c.xn----kcd017p; 𞤲≠ܦ᩠.-‌ߕ; [B1, C1, V3, V6]; xn--wnb859grzfzw60c.xn----kcd017p; ; ; # 𞤲≠ܦ᩠.-ߕ
+𞤲≠ܦ᩠。-‌ߕ; 𞤲≠ܦ᩠.-‌ߕ; [B1, C1, P1, V3, V6]; xn--wnb859grzfzw60c.xn----kcd017p; ; xn--wnb859grzfzw60c.xn----kcd; [B1, P1, V3, V6] # 𞤲≠ܦ᩠.-ߕ
+𞤲≠ܦ᩠。-‌ߕ; 𞤲≠ܦ᩠.-‌ߕ; [B1, C1, P1, V3, V6]; xn--wnb859grzfzw60c.xn----kcd017p; ; xn--wnb859grzfzw60c.xn----kcd; [B1, P1, V3, V6] # 𞤲≠ܦ᩠.-ߕ
+𐹰ͨ-ꡧ。ٵ; 𐹰ͨ-ꡧ.اٴ; [B1]; xn----shb2387jgkqd.xn--mgb8m; ; ; # 𐹰ͨ-ꡧ.اٴ
+𐹰ͨ-ꡧ。اٴ; 𐹰ͨ-ꡧ.اٴ; [B1]; xn----shb2387jgkqd.xn--mgb8m; ; ; # 𐹰ͨ-ꡧ.اٴ
+xn----shb2387jgkqd.xn--mgb8m; 𐹰ͨ-ꡧ.اٴ; [B1]; xn----shb2387jgkqd.xn--mgb8m; ; ; # 𐹰ͨ-ꡧ.اٴ
+F󠅟。򏗅♚; f.򏗅♚; [P1, V6]; f.xn--45hz6953f; ; ; # f.♚
+F󠅟。򏗅♚; f.򏗅♚; [P1, V6]; f.xn--45hz6953f; ; ; # f.♚
+f󠅟。򏗅♚; f.򏗅♚; [P1, V6]; f.xn--45hz6953f; ; ; # f.♚
+f.xn--45hz6953f; f.򏗅♚; [V6]; f.xn--45hz6953f; ; ; # f.♚
+f󠅟。򏗅♚; f.򏗅♚; [P1, V6]; f.xn--45hz6953f; ; ; # f.♚
+୍𑄴ᷩ。𝟮Ⴘ𞀨񃥇; ୍𑄴ᷩ.2Ⴘ𞀨񃥇; [P1, V5, V6]; xn--9ic246gs21p.xn--2-k1g43076adrwq; ; ; # ୍𑄴ᷩ.2Ⴘ𞀨
+୍𑄴ᷩ。2Ⴘ𞀨񃥇; ୍𑄴ᷩ.2Ⴘ𞀨񃥇; [P1, V5, V6]; xn--9ic246gs21p.xn--2-k1g43076adrwq; ; ; # ୍𑄴ᷩ.2Ⴘ𞀨
+୍𑄴ᷩ。2ⴘ𞀨񃥇; ୍𑄴ᷩ.2ⴘ𞀨񃥇; [P1, V5, V6]; xn--9ic246gs21p.xn--2-nws2918ndrjr; ; ; # ୍𑄴ᷩ.2ⴘ𞀨
+xn--9ic246gs21p.xn--2-nws2918ndrjr; ୍𑄴ᷩ.2ⴘ𞀨񃥇; [V5, V6]; xn--9ic246gs21p.xn--2-nws2918ndrjr; ; ; # ୍𑄴ᷩ.2ⴘ𞀨
+xn--9ic246gs21p.xn--2-k1g43076adrwq; ୍𑄴ᷩ.2Ⴘ𞀨񃥇; [V5, V6]; xn--9ic246gs21p.xn--2-k1g43076adrwq; ; ; # ୍𑄴ᷩ.2Ⴘ𞀨
+୍𑄴ᷩ。𝟮ⴘ𞀨񃥇; ୍𑄴ᷩ.2ⴘ𞀨񃥇; [P1, V5, V6]; xn--9ic246gs21p.xn--2-nws2918ndrjr; ; ; # ୍𑄴ᷩ.2ⴘ𞀨
+򓠭‌‌⒈。勉𑁅; 򓠭‌‌⒈.勉𑁅; [C1, P1, V6]; xn--0uga855aez302a.xn--4grs325b; ; xn--tsh11906f.xn--4grs325b; [P1, V6] # ⒈.勉𑁅
+򓠭‌‌1.。勉𑁅; 򓠭‌‌1..勉𑁅; [C1, P1, V6, X4_2]; xn--1-rgna61159u..xn--4grs325b; [C1, P1, V6, A4_2]; xn--1-yi00h..xn--4grs325b; [P1, V6, A4_2] # 1..勉𑁅
+xn--1-yi00h..xn--4grs325b; 򓠭1..勉𑁅; [V6, X4_2]; xn--1-yi00h..xn--4grs325b; [V6, A4_2]; ; # 1..勉𑁅
+xn--1-rgna61159u..xn--4grs325b; 򓠭‌‌1..勉𑁅; [C1, V6, X4_2]; xn--1-rgna61159u..xn--4grs325b; [C1, V6, A4_2]; ; # 1..勉𑁅
+xn--tsh11906f.xn--4grs325b; 򓠭⒈.勉𑁅; [V6]; xn--tsh11906f.xn--4grs325b; ; ; # ⒈.勉𑁅
+xn--0uga855aez302a.xn--4grs325b; 򓠭‌‌⒈.勉𑁅; [C1, V6]; xn--0uga855aez302a.xn--4grs325b; ; ; # ⒈.勉𑁅
+ᡃ.玿񫈜󕞐; ; [P1, V6]; xn--27e.xn--7cy81125a0yq4a; ; ; # ᡃ.玿
+xn--27e.xn--7cy81125a0yq4a; ᡃ.玿񫈜󕞐; [V6]; xn--27e.xn--7cy81125a0yq4a; ; ; # ᡃ.玿
+‌‌。⒈≯𝟵; ‌‌.⒈≯9; [C1, P1, V6]; xn--0uga.xn--9-ogo37g; ; .xn--9-ogo37g; [P1, V6, A4_2] # .⒈≯9
+‌‌。⒈≯𝟵; ‌‌.⒈≯9; [C1, P1, V6]; xn--0uga.xn--9-ogo37g; ; .xn--9-ogo37g; [P1, V6, A4_2] # .⒈≯9
+‌‌。1.≯9; ‌‌.1.≯9; [C1, P1, V6]; xn--0uga.1.xn--9-ogo; ; .1.xn--9-ogo; [P1, V6, A4_2] # .1.≯9
+‌‌。1.≯9; ‌‌.1.≯9; [C1, P1, V6]; xn--0uga.1.xn--9-ogo; ; .1.xn--9-ogo; [P1, V6, A4_2] # .1.≯9
+.1.xn--9-ogo; .1.≯9; [V6, X4_2]; .1.xn--9-ogo; [V6, A4_2]; ; # .1.≯9
+xn--0uga.1.xn--9-ogo; ‌‌.1.≯9; [C1, V6]; xn--0uga.1.xn--9-ogo; ; ; # .1.≯9
+.xn--9-ogo37g; .⒈≯9; [V6, X4_2]; .xn--9-ogo37g; [V6, A4_2]; ; # .⒈≯9
+xn--0uga.xn--9-ogo37g; ‌‌.⒈≯9; [C1, V6]; xn--0uga.xn--9-ogo37g; ; ; # .⒈≯9
+ᅟᷠ򐀁.𺻆≯𐮁; ; [B5, B6, P1, V6]; xn--osd615d5659o.xn--hdh5192gkm6r; ; ; # ᷠ.≯𐮁
+ᅟᷠ򐀁.𺻆≯𐮁; ᅟᷠ򐀁.𺻆≯𐮁; [B5, B6, P1, V6]; xn--osd615d5659o.xn--hdh5192gkm6r; ; ; # ᷠ.≯𐮁
+xn--osd615d5659o.xn--hdh5192gkm6r; ᅟᷠ򐀁.𺻆≯𐮁; [B5, B6, V6]; xn--osd615d5659o.xn--hdh5192gkm6r; ; ; # ᷠ.≯𐮁
+󠄫𝩤‍ؾ.𝩩-ࠞ󑼩; 𝩤‍ؾ.𝩩-ࠞ󑼩; [B1, C2, P1, V5, V6]; xn--9gb723kg862a.xn----qgd52296avol4f; ; xn--9gb5080v.xn----qgd52296avol4f; [B1, P1, V5, V6] # 𝩤ؾ.𝩩-ࠞ
+xn--9gb5080v.xn----qgd52296avol4f; 𝩤ؾ.𝩩-ࠞ󑼩; [B1, V5, V6]; xn--9gb5080v.xn----qgd52296avol4f; ; ; # 𝩤ؾ.𝩩-ࠞ
+xn--9gb723kg862a.xn----qgd52296avol4f; 𝩤‍ؾ.𝩩-ࠞ󑼩; [B1, C2, V5, V6]; xn--9gb723kg862a.xn----qgd52296avol4f; ; ; # 𝩤ؾ.𝩩-ࠞ
+⃚.𑘿-; ⃚.𑘿-; [V3, V5]; xn--w0g.xn----bd0j; ; ; # ⃚.𑘿-
+⃚.𑘿-; ; [V3, V5]; xn--w0g.xn----bd0j; ; ; # ⃚.𑘿-
+xn--w0g.xn----bd0j; ⃚.𑘿-; [V3, V5]; xn--w0g.xn----bd0j; ; ; # ⃚.𑘿-
+䮸ß.󠵟󠭎紙ࢨ; ; [B1, P1, V6]; xn--zca5349a.xn--xyb1370div70kpzba; ; xn--ss-sf1c.xn--xyb1370div70kpzba; # 䮸ß.紙ࢨ
+䮸SS.󠵟󠭎紙ࢨ; 䮸ss.󠵟󠭎紙ࢨ; [B1, P1, V6]; xn--ss-sf1c.xn--xyb1370div70kpzba; ; ; # 䮸ss.紙ࢨ
+䮸ss.󠵟󠭎紙ࢨ; ; [B1, P1, V6]; xn--ss-sf1c.xn--xyb1370div70kpzba; ; ; # 䮸ss.紙ࢨ
+䮸Ss.󠵟󠭎紙ࢨ; 䮸ss.󠵟󠭎紙ࢨ; [B1, P1, V6]; xn--ss-sf1c.xn--xyb1370div70kpzba; ; ; # 䮸ss.紙ࢨ
+xn--ss-sf1c.xn--xyb1370div70kpzba; 䮸ss.󠵟󠭎紙ࢨ; [B1, V6]; xn--ss-sf1c.xn--xyb1370div70kpzba; ; ; # 䮸ss.紙ࢨ
+xn--zca5349a.xn--xyb1370div70kpzba; 䮸ß.󠵟󠭎紙ࢨ; [B1, V6]; xn--zca5349a.xn--xyb1370div70kpzba; ; ; # 䮸ß.紙ࢨ
+-Ⴞ.-𝩨⅔𐦕; -Ⴞ.-𝩨2⁄3𐦕; [B1, P1, V3, V6]; xn----w1g.xn---23-pt0a0433lk3jj; ; ; # -Ⴞ.-𝩨2⁄3𐦕
+-Ⴞ.-𝩨2⁄3𐦕; ; [B1, P1, V3, V6]; xn----w1g.xn---23-pt0a0433lk3jj; ; ; # -Ⴞ.-𝩨2⁄3𐦕
+-ⴞ.-𝩨2⁄3𐦕; ; [B1, V3]; xn----zws.xn---23-pt0a0433lk3jj; ; ; # -ⴞ.-𝩨2⁄3𐦕
+xn----zws.xn---23-pt0a0433lk3jj; -ⴞ.-𝩨2⁄3𐦕; [B1, V3]; xn----zws.xn---23-pt0a0433lk3jj; ; ; # -ⴞ.-𝩨2⁄3𐦕
+xn----w1g.xn---23-pt0a0433lk3jj; -Ⴞ.-𝩨2⁄3𐦕; [B1, V3, V6]; xn----w1g.xn---23-pt0a0433lk3jj; ; ; # -Ⴞ.-𝩨2⁄3𐦕
+-ⴞ.-𝩨⅔𐦕; -ⴞ.-𝩨2⁄3𐦕; [B1, V3]; xn----zws.xn---23-pt0a0433lk3jj; ; ; # -ⴞ.-𝩨2⁄3𐦕
+󧈯𐹯ૂ。򖢨𐮁񇼖ᡂ; 󧈯𐹯ૂ.򖢨𐮁񇼖ᡂ; [B5, B6, P1, V6]; xn--bfc7604kv8m3g.xn--17e5565jl7zw4h16a; ; ; # 𐹯ૂ.𐮁ᡂ
+󧈯𐹯ૂ。򖢨𐮁񇼖ᡂ; 󧈯𐹯ૂ.򖢨𐮁񇼖ᡂ; [B5, B6, P1, V6]; xn--bfc7604kv8m3g.xn--17e5565jl7zw4h16a; ; ; # 𐹯ૂ.𐮁ᡂ
+xn--bfc7604kv8m3g.xn--17e5565jl7zw4h16a; 󧈯𐹯ૂ.򖢨𐮁񇼖ᡂ; [B5, B6, V6]; xn--bfc7604kv8m3g.xn--17e5565jl7zw4h16a; ; ; # 𐹯ૂ.𐮁ᡂ
+ႂ-‍꣪.ꡊ‍񼸳; ႂ-‍꣪.ꡊ‍񼸳; [C2, P1, V5, V6]; xn----gyg250jio7k.xn--1ug8774cri56d; ; xn----gyg3618i.xn--jc9ao4185a; [P1, V5, V6] # ႂ-꣪.ꡊ
+ႂ-‍꣪.ꡊ‍񼸳; ; [C2, P1, V5, V6]; xn----gyg250jio7k.xn--1ug8774cri56d; ; xn----gyg3618i.xn--jc9ao4185a; [P1, V5, V6] # ႂ-꣪.ꡊ
+xn----gyg3618i.xn--jc9ao4185a; ႂ-꣪.ꡊ񼸳; [V5, V6]; xn----gyg3618i.xn--jc9ao4185a; ; ; # ႂ-꣪.ꡊ
+xn----gyg250jio7k.xn--1ug8774cri56d; ႂ-‍꣪.ꡊ‍񼸳; [C2, V5, V6]; xn----gyg250jio7k.xn--1ug8774cri56d; ; ; # ႂ-꣪.ꡊ
+۱。≠٨; ۱.≠٨; [B1, P1, V6]; xn--emb.xn--hib334l; ; ; # ۱.≠٨
+۱。≠٨; ۱.≠٨; [B1, P1, V6]; xn--emb.xn--hib334l; ; ; # ۱.≠٨
+xn--emb.xn--hib334l; ۱.≠٨; [B1, V6]; xn--emb.xn--hib334l; ; ; # ۱.≠٨
+𑈵廊.𐠍; ; [V5]; xn--xytw701b.xn--yc9c; ; ; # 𑈵廊.𐠍
+xn--xytw701b.xn--yc9c; 𑈵廊.𐠍; [V5]; xn--xytw701b.xn--yc9c; ; ; # 𑈵廊.𐠍
+‍͖-.-Ⴐ١; ‍͖-.-Ⴐ١; [B1, C2, P1, V3, V6]; xn----rgb661t.xn----bqc030f; ; xn----rgb.xn----bqc030f; [B1, P1, V3, V5, V6] # ͖-.-Ⴐ١
+‍͖-.-Ⴐ١; ; [B1, C2, P1, V3, V6]; xn----rgb661t.xn----bqc030f; ; xn----rgb.xn----bqc030f; [B1, P1, V3, V5, V6] # ͖-.-Ⴐ١
+‍͖-.-ⴐ١; ; [B1, C2, V3]; xn----rgb661t.xn----bqc2280a; ; xn----rgb.xn----bqc2280a; [B1, V3, V5] # ͖-.-ⴐ١
+xn----rgb.xn----bqc2280a; ͖-.-ⴐ١; [B1, V3, V5]; xn----rgb.xn----bqc2280a; ; ; # ͖-.-ⴐ١
+xn----rgb661t.xn----bqc2280a; ‍͖-.-ⴐ١; [B1, C2, V3]; xn----rgb661t.xn----bqc2280a; ; ; # ͖-.-ⴐ١
+xn----rgb.xn----bqc030f; ͖-.-Ⴐ١; [B1, V3, V5, V6]; xn----rgb.xn----bqc030f; ; ; # ͖-.-Ⴐ١
+xn----rgb661t.xn----bqc030f; ‍͖-.-Ⴐ١; [B1, C2, V3, V6]; xn----rgb661t.xn----bqc030f; ; ; # ͖-.-Ⴐ١
+‍͖-.-ⴐ١; ‍͖-.-ⴐ١; [B1, C2, V3]; xn----rgb661t.xn----bqc2280a; ; xn----rgb.xn----bqc2280a; [B1, V3, V5] # ͖-.-ⴐ١
+غ١挏󾯐.-; ; [B1, B2, B3, P1, V3, V6]; xn--5gb2f4205aqi47p.-; ; ; # غ١挏.-
+xn--5gb2f4205aqi47p.-; غ١挏󾯐.-; [B1, B2, B3, V3, V6]; xn--5gb2f4205aqi47p.-; ; ; # غ١挏.-
+ۯ。𐹧𞤽; ۯ.𐹧𞤽; [B1]; xn--cmb.xn--fo0dy848a; ; ; # ۯ.𐹧𞤽
+ۯ。𐹧𞤽; ۯ.𐹧𞤽; [B1]; xn--cmb.xn--fo0dy848a; ; ; # ۯ.𐹧𞤽
+ۯ。𐹧𞤛; ۯ.𐹧𞤽; [B1]; xn--cmb.xn--fo0dy848a; ; ; # ۯ.𐹧𞤽
+xn--cmb.xn--fo0dy848a; ۯ.𐹧𞤽; [B1]; xn--cmb.xn--fo0dy848a; ; ; # ۯ.𐹧𞤽
+ۯ。𐹧𞤛; ۯ.𐹧𞤽; [B1]; xn--cmb.xn--fo0dy848a; ; ; # ۯ.𐹧𞤽
+Ⴞ𶛀𛗻.ᢗ릫; Ⴞ𶛀𛗻.ᢗ릫; [P1, V6]; xn--2nd8876sgl2j.xn--hbf6853f; ; ; # Ⴞ.ᢗ릫
+Ⴞ𶛀𛗻.ᢗ릫; Ⴞ𶛀𛗻.ᢗ릫; [P1, V6]; xn--2nd8876sgl2j.xn--hbf6853f; ; ; # Ⴞ.ᢗ릫
+Ⴞ𶛀𛗻.ᢗ릫; ; [P1, V6]; xn--2nd8876sgl2j.xn--hbf6853f; ; ; # Ⴞ.ᢗ릫
+Ⴞ𶛀𛗻.ᢗ릫; Ⴞ𶛀𛗻.ᢗ릫; [P1, V6]; xn--2nd8876sgl2j.xn--hbf6853f; ; ; # Ⴞ.ᢗ릫
+ⴞ𶛀𛗻.ᢗ릫; ⴞ𶛀𛗻.ᢗ릫; [P1, V6]; xn--mlj0486jgl2j.xn--hbf6853f; ; ; # ⴞ.ᢗ릫
+ⴞ𶛀𛗻.ᢗ릫; ; [P1, V6]; xn--mlj0486jgl2j.xn--hbf6853f; ; ; # ⴞ.ᢗ릫
+xn--mlj0486jgl2j.xn--hbf6853f; ⴞ𶛀𛗻.ᢗ릫; [V6]; xn--mlj0486jgl2j.xn--hbf6853f; ; ; # ⴞ.ᢗ릫
+xn--2nd8876sgl2j.xn--hbf6853f; Ⴞ𶛀𛗻.ᢗ릫; [V6]; xn--2nd8876sgl2j.xn--hbf6853f; ; ; # Ⴞ.ᢗ릫
+ⴞ𶛀𛗻.ᢗ릫; ⴞ𶛀𛗻.ᢗ릫; [P1, V6]; xn--mlj0486jgl2j.xn--hbf6853f; ; ; # ⴞ.ᢗ릫
+ⴞ𶛀𛗻.ᢗ릫; ⴞ𶛀𛗻.ᢗ릫; [P1, V6]; xn--mlj0486jgl2j.xn--hbf6853f; ; ; # ⴞ.ᢗ릫
+󠎃󗭞ڷ𐹷。≯‌᷾; 󠎃󗭞ڷ𐹷.≯‌᷾; [B1, C1, P1, V6]; xn--qkb4516kbi06fg2id.xn--zfg59fm0c; ; xn--qkb4516kbi06fg2id.xn--zfg31q; [B1, P1, V6] # ڷ𐹷.≯᷾
+󠎃󗭞ڷ𐹷。≯‌᷾; 󠎃󗭞ڷ𐹷.≯‌᷾; [B1, C1, P1, V6]; xn--qkb4516kbi06fg2id.xn--zfg59fm0c; ; xn--qkb4516kbi06fg2id.xn--zfg31q; [B1, P1, V6] # ڷ𐹷.≯᷾
+󠎃󗭞ڷ𐹷。≯‌᷾; 󠎃󗭞ڷ𐹷.≯‌᷾; [B1, C1, P1, V6]; xn--qkb4516kbi06fg2id.xn--zfg59fm0c; ; xn--qkb4516kbi06fg2id.xn--zfg31q; [B1, P1, V6] # ڷ𐹷.≯᷾
+󠎃󗭞ڷ𐹷。≯‌᷾; 󠎃󗭞ڷ𐹷.≯‌᷾; [B1, C1, P1, V6]; xn--qkb4516kbi06fg2id.xn--zfg59fm0c; ; xn--qkb4516kbi06fg2id.xn--zfg31q; [B1, P1, V6] # ڷ𐹷.≯᷾
+xn--qkb4516kbi06fg2id.xn--zfg31q; 󠎃󗭞ڷ𐹷.≯᷾; [B1, V6]; xn--qkb4516kbi06fg2id.xn--zfg31q; ; ; # ڷ𐹷.≯᷾
+xn--qkb4516kbi06fg2id.xn--zfg59fm0c; 󠎃󗭞ڷ𐹷.≯‌᷾; [B1, C1, V6]; xn--qkb4516kbi06fg2id.xn--zfg59fm0c; ; ; # ڷ𐹷.≯᷾
+ᛎ󠅍󠐕‍。𐹾𐹪𐻝-; ᛎ󠐕‍.𐹾𐹪𐻝-; [B1, B6, C2, P1, V3, V6]; xn--fxe848bq3411a.xn----q26i2bvu; ; xn--fxe63563p.xn----q26i2bvu; [B1, B6, P1, V3, V6] # ᛎ.𐹾𐹪-
+ᛎ󠅍󠐕‍。𐹾𐹪𐻝-; ᛎ󠐕‍.𐹾𐹪𐻝-; [B1, B6, C2, P1, V3, V6]; xn--fxe848bq3411a.xn----q26i2bvu; ; xn--fxe63563p.xn----q26i2bvu; [B1, B6, P1, V3, V6] # ᛎ.𐹾𐹪-
+xn--fxe63563p.xn----q26i2bvu; ᛎ󠐕.𐹾𐹪𐻝-; [B1, B6, V3, V6]; xn--fxe63563p.xn----q26i2bvu; ; ; # ᛎ.𐹾𐹪-
+xn--fxe848bq3411a.xn----q26i2bvu; ᛎ󠐕‍.𐹾𐹪𐻝-; [B1, B6, C2, V3, V6]; xn--fxe848bq3411a.xn----q26i2bvu; ; ; # ᛎ.𐹾𐹪-
+𐹶.𐫂; ; [B1]; xn--uo0d.xn--rw9c; ; ; # 𐹶.𐫂
+xn--uo0d.xn--rw9c; 𐹶.𐫂; [B1]; xn--uo0d.xn--rw9c; ; ; # 𐹶.𐫂
+ß‍်。⒈; ß‍်.⒈; [C2, P1, V6]; xn--zca679eh2l.xn--tsh; ; xn--ss-f4j.xn--tsh; [P1, V6] # ß်.⒈
+ß‍်。1.; ß‍်.1.; [C2]; xn--zca679eh2l.1.; ; xn--ss-f4j.1.; [] # ß်.1.
+SS‍်。1.; ss‍်.1.; [C2]; xn--ss-f4j585j.1.; ; xn--ss-f4j.1.; [] # ss်.1.
+ss‍်。1.; ss‍်.1.; [C2]; xn--ss-f4j585j.1.; ; xn--ss-f4j.1.; [] # ss်.1.
+Ss‍်。1.; ss‍်.1.; [C2]; xn--ss-f4j585j.1.; ; xn--ss-f4j.1.; [] # ss်.1.
+xn--ss-f4j.1.; ss်.1.; ; xn--ss-f4j.1.; ; ; # ss်.1.
+ss်.1.; ; ; xn--ss-f4j.1.; ; ; # ss်.1.
+SS်.1.; ss်.1.; ; xn--ss-f4j.1.; ; ; # ss်.1.
+Ss်.1.; ss်.1.; ; xn--ss-f4j.1.; ; ; # ss်.1.
+xn--ss-f4j585j.1.; ss‍်.1.; [C2]; xn--ss-f4j585j.1.; ; ; # ss်.1.
+xn--zca679eh2l.1.; ß‍်.1.; [C2]; xn--zca679eh2l.1.; ; ; # ß်.1.
+SS‍်。⒈; ss‍်.⒈; [C2, P1, V6]; xn--ss-f4j585j.xn--tsh; ; xn--ss-f4j.xn--tsh; [P1, V6] # ss်.⒈
+ss‍်。⒈; ss‍်.⒈; [C2, P1, V6]; xn--ss-f4j585j.xn--tsh; ; xn--ss-f4j.xn--tsh; [P1, V6] # ss်.⒈
+Ss‍်。⒈; ss‍်.⒈; [C2, P1, V6]; xn--ss-f4j585j.xn--tsh; ; xn--ss-f4j.xn--tsh; [P1, V6] # ss်.⒈
+xn--ss-f4j.xn--tsh; ss်.⒈; [V6]; xn--ss-f4j.xn--tsh; ; ; # ss်.⒈
+xn--ss-f4j585j.xn--tsh; ss‍်.⒈; [C2, V6]; xn--ss-f4j585j.xn--tsh; ; ; # ss်.⒈
+xn--zca679eh2l.xn--tsh; ß‍်.⒈; [C2, V6]; xn--zca679eh2l.xn--tsh; ; ; # ß်.⒈
+୍‌𙶵𞻘。‍; ୍‌𙶵𞻘.‍; [B1, C2, P1, V5, V6]; xn--9ic637hz82z32jc.xn--1ug; ; xn--9ic6417rn4xb.; [B1, P1, V5, V6] # ୍.
+xn--9ic6417rn4xb.; ୍𙶵𞻘.; [B1, V5, V6]; xn--9ic6417rn4xb.; ; ; # ୍.
+xn--9ic637hz82z32jc.xn--1ug; ୍‌𙶵𞻘.‍; [B1, C2, V5, V6]; xn--9ic637hz82z32jc.xn--1ug; ; ; # ୍.
+𐮅。ڼ🁕; 𐮅.ڼ🁕; [B3]; xn--c29c.xn--vkb8871w; ; ; # 𐮅.ڼ🁕
+𐮅。ڼ🁕; 𐮅.ڼ🁕; [B3]; xn--c29c.xn--vkb8871w; ; ; # 𐮅.ڼ🁕
+xn--c29c.xn--vkb8871w; 𐮅.ڼ🁕; [B3]; xn--c29c.xn--vkb8871w; ; ; # 𐮅.ڼ🁕
+ؠ្。𐫔󠀧‌𑈵; ؠ្.𐫔󠀧‌𑈵; [B2, B3, C1, P1, V6]; xn--fgb471g.xn--0ug9853g7verp838a; ; xn--fgb471g.xn--9w9c29jw3931a; [B2, B3, P1, V6] # ؠ្.𐫔𑈵
+xn--fgb471g.xn--9w9c29jw3931a; ؠ្.𐫔󠀧𑈵; [B2, B3, V6]; xn--fgb471g.xn--9w9c29jw3931a; ; ; # ؠ្.𐫔𑈵
+xn--fgb471g.xn--0ug9853g7verp838a; ؠ្.𐫔󠀧‌𑈵; [B2, B3, C1, V6]; xn--fgb471g.xn--0ug9853g7verp838a; ; ; # ؠ្.𐫔𑈵
+񋉕.𞣕𞤊; 񋉕.𞣕𞤬; [B1, P1, V5, V6]; xn--tf5w.xn--2b6hof; ; ; # .𞣕𞤬
+񋉕.𞣕𞤬; ; [B1, P1, V5, V6]; xn--tf5w.xn--2b6hof; ; ; # .𞣕𞤬
+xn--tf5w.xn--2b6hof; 񋉕.𞣕𞤬; [B1, V5, V6]; xn--tf5w.xn--2b6hof; ; ; # .𞣕𞤬
+ی𐨿.ß྄𑍬; ی𐨿.ß྄𑍬; ; xn--clb2593k.xn--zca216edt0r; ; xn--clb2593k.xn--ss-toj6092t; # ی𐨿.ß྄𑍬
+ی𐨿.ß྄𑍬; ; ; xn--clb2593k.xn--zca216edt0r; ; xn--clb2593k.xn--ss-toj6092t; # ی𐨿.ß྄𑍬
+ی𐨿.SS྄𑍬; ی𐨿.ss྄𑍬; ; xn--clb2593k.xn--ss-toj6092t; ; ; # ی𐨿.ss྄𑍬
+ی𐨿.ss྄𑍬; ; ; xn--clb2593k.xn--ss-toj6092t; ; ; # ی𐨿.ss྄𑍬
+xn--clb2593k.xn--ss-toj6092t; ی𐨿.ss྄𑍬; ; xn--clb2593k.xn--ss-toj6092t; ; ; # ی𐨿.ss྄𑍬
+xn--clb2593k.xn--zca216edt0r; ی𐨿.ß྄𑍬; ; xn--clb2593k.xn--zca216edt0r; ; ; # ی𐨿.ß྄𑍬
+ی𐨿.SS྄𑍬; ی𐨿.ss྄𑍬; ; xn--clb2593k.xn--ss-toj6092t; ; ; # ی𐨿.ss྄𑍬
+ی𐨿.ss྄𑍬; ی𐨿.ss྄𑍬; ; xn--clb2593k.xn--ss-toj6092t; ; ; # ی𐨿.ss྄𑍬
+ی𐨿.Ss྄𑍬; ی𐨿.ss྄𑍬; ; xn--clb2593k.xn--ss-toj6092t; ; ; # ی𐨿.ss྄𑍬
+ی𐨿.Ss྄𑍬; ی𐨿.ss྄𑍬; ; xn--clb2593k.xn--ss-toj6092t; ; ; # ی𐨿.ss྄𑍬
+𝟠≮‌。󠅱឴; 8≮‌.឴; [C1, P1, V5, V6]; xn--8-sgn10i.xn--z3e; ; xn--8-ngo.xn--z3e; [P1, V5, V6] # 8≮.
+𝟠≮‌。󠅱឴; 8≮‌.឴; [C1, P1, V5, V6]; xn--8-sgn10i.xn--z3e; ; xn--8-ngo.xn--z3e; [P1, V5, V6] # 8≮.
+8≮‌。󠅱឴; 8≮‌.឴; [C1, P1, V5, V6]; xn--8-sgn10i.xn--z3e; ; xn--8-ngo.xn--z3e; [P1, V5, V6] # 8≮.
+8≮‌。󠅱឴; 8≮‌.឴; [C1, P1, V5, V6]; xn--8-sgn10i.xn--z3e; ; xn--8-ngo.xn--z3e; [P1, V5, V6] # 8≮.
+xn--8-ngo.xn--z3e; 8≮.឴; [V5, V6]; xn--8-ngo.xn--z3e; ; ; # 8≮.
+xn--8-sgn10i.xn--z3e; 8≮‌.឴; [C1, V5, V6]; xn--8-sgn10i.xn--z3e; ; ; # 8≮.
+ᢕ≯︒񄂯.Ⴀ; ᢕ≯︒񄂯.Ⴀ; [P1, V6]; xn--fbf851cq98poxw1a.xn--7md; ; ; # ᢕ≯︒.Ⴀ
+ᢕ≯︒񄂯.Ⴀ; ᢕ≯︒񄂯.Ⴀ; [P1, V6]; xn--fbf851cq98poxw1a.xn--7md; ; ; # ᢕ≯︒.Ⴀ
+ᢕ≯。񄂯.Ⴀ; ᢕ≯.񄂯.Ⴀ; [P1, V6]; xn--fbf851c.xn--ko1u.xn--7md; ; ; # ᢕ≯..Ⴀ
+ᢕ≯。񄂯.Ⴀ; ᢕ≯.񄂯.Ⴀ; [P1, V6]; xn--fbf851c.xn--ko1u.xn--7md; ; ; # ᢕ≯..Ⴀ
+ᢕ≯。񄂯.ⴀ; ᢕ≯.񄂯.ⴀ; [P1, V6]; xn--fbf851c.xn--ko1u.xn--rkj; ; ; # ᢕ≯..ⴀ
+ᢕ≯。񄂯.ⴀ; ᢕ≯.񄂯.ⴀ; [P1, V6]; xn--fbf851c.xn--ko1u.xn--rkj; ; ; # ᢕ≯..ⴀ
+xn--fbf851c.xn--ko1u.xn--rkj; ᢕ≯.񄂯.ⴀ; [V6]; xn--fbf851c.xn--ko1u.xn--rkj; ; ; # ᢕ≯..ⴀ
+xn--fbf851c.xn--ko1u.xn--7md; ᢕ≯.񄂯.Ⴀ; [V6]; xn--fbf851c.xn--ko1u.xn--7md; ; ; # ᢕ≯..Ⴀ
+ᢕ≯︒񄂯.ⴀ; ᢕ≯︒񄂯.ⴀ; [P1, V6]; xn--fbf851cq98poxw1a.xn--rkj; ; ; # ᢕ≯︒.ⴀ
+ᢕ≯︒񄂯.ⴀ; ᢕ≯︒񄂯.ⴀ; [P1, V6]; xn--fbf851cq98poxw1a.xn--rkj; ; ; # ᢕ≯︒.ⴀ
+xn--fbf851cq98poxw1a.xn--rkj; ᢕ≯︒񄂯.ⴀ; [V6]; xn--fbf851cq98poxw1a.xn--rkj; ; ; # ᢕ≯︒.ⴀ
+xn--fbf851cq98poxw1a.xn--7md; ᢕ≯︒񄂯.Ⴀ; [V6]; xn--fbf851cq98poxw1a.xn--7md; ; ; # ᢕ≯︒.Ⴀ
+ྟ.-ࠪ; ྟ.-ࠪ; [V3, V5]; xn--vfd.xn----fhd; ; ; # ྟ.-ࠪ
+ྟ.-ࠪ; ; [V3, V5]; xn--vfd.xn----fhd; ; ; # ྟ.-ࠪ
+xn--vfd.xn----fhd; ྟ.-ࠪ; [V3, V5]; xn--vfd.xn----fhd; ; ; # ྟ.-ࠪ
+ᵬ󠆠.핒⒒⒈􈄦; ᵬ.핒⒒⒈􈄦; [P1, V6]; xn--tbg.xn--tsht7586kyts9l; ; ; # ᵬ.핒⒒⒈
+ᵬ󠆠.핒⒒⒈􈄦; ᵬ.핒⒒⒈􈄦; [P1, V6]; xn--tbg.xn--tsht7586kyts9l; ; ; # ᵬ.핒⒒⒈
+ᵬ󠆠.핒11.1.􈄦; ᵬ.핒11.1.􈄦; [P1, V6]; xn--tbg.xn--11-5o7k.1.xn--k469f; ; ; # ᵬ.핒11.1.
+ᵬ󠆠.핒11.1.􈄦; ᵬ.핒11.1.􈄦; [P1, V6]; xn--tbg.xn--11-5o7k.1.xn--k469f; ; ; # ᵬ.핒11.1.
+xn--tbg.xn--11-5o7k.1.xn--k469f; ᵬ.핒11.1.􈄦; [V6]; xn--tbg.xn--11-5o7k.1.xn--k469f; ; ; # ᵬ.핒11.1.
+xn--tbg.xn--tsht7586kyts9l; ᵬ.핒⒒⒈􈄦; [V6]; xn--tbg.xn--tsht7586kyts9l; ; ; # ᵬ.핒⒒⒈
+ς𑓂𐋢.٨; ς𑓂𐋢.٨; [B1]; xn--3xa8371khhl.xn--hib; ; xn--4xa6371khhl.xn--hib; # ς𑓂𐋢.٨
+ς𑓂𐋢.٨; ; [B1]; xn--3xa8371khhl.xn--hib; ; xn--4xa6371khhl.xn--hib; # ς𑓂𐋢.٨
+Σ𑓂𐋢.٨; σ𑓂𐋢.٨; [B1]; xn--4xa6371khhl.xn--hib; ; ; # σ𑓂𐋢.٨
+σ𑓂𐋢.٨; ; [B1]; xn--4xa6371khhl.xn--hib; ; ; # σ𑓂𐋢.٨
+xn--4xa6371khhl.xn--hib; σ𑓂𐋢.٨; [B1]; xn--4xa6371khhl.xn--hib; ; ; # σ𑓂𐋢.٨
+xn--3xa8371khhl.xn--hib; ς𑓂𐋢.٨; [B1]; xn--3xa8371khhl.xn--hib; ; ; # ς𑓂𐋢.٨
+Σ𑓂𐋢.٨; σ𑓂𐋢.٨; [B1]; xn--4xa6371khhl.xn--hib; ; ; # σ𑓂𐋢.٨
+σ𑓂𐋢.٨; σ𑓂𐋢.٨; [B1]; xn--4xa6371khhl.xn--hib; ; ; # σ𑓂𐋢.٨
+꥓‌𐋻‍.ⷸ𞿄𐹲; ; [B1, B6, C2, P1, V5, V6]; xn--0ugc8356he76c.xn--urju692efj0f; ; xn--3j9a531o.xn--urju692efj0f; [B1, P1, V5, V6] # ꥓𐋻.ⷸ𐹲
+xn--3j9a531o.xn--urju692efj0f; ꥓𐋻.ⷸ𞿄𐹲; [B1, V5, V6]; xn--3j9a531o.xn--urju692efj0f; ; ; # ꥓𐋻.ⷸ𐹲
+xn--0ugc8356he76c.xn--urju692efj0f; ꥓‌𐋻‍.ⷸ𞿄𐹲; [B1, B6, C2, V5, V6]; xn--0ugc8356he76c.xn--urju692efj0f; ; ; # ꥓𐋻.ⷸ𐹲
+⊼。񪧖ڕ; ⊼.񪧖ڕ; [B1, B5, B6, P1, V6]; xn--ofh.xn--rjb13118f; ; ; # ⊼.ڕ
+xn--ofh.xn--rjb13118f; ⊼.񪧖ڕ; [B1, B5, B6, V6]; xn--ofh.xn--rjb13118f; ; ; # ⊼.ڕ
+𐯬񖋔。󜳥; 𐯬񖋔.󜳥; [B2, B3, P1, V6]; xn--949co370q.xn--7g25e; ; ; # .
+xn--949co370q.xn--7g25e; 𐯬񖋔.󜳥; [B2, B3, V6]; xn--949co370q.xn--7g25e; ; ; # .
+؁𑍧ߝ。ς򬍘🀞឵; ؁𑍧ߝ.ς򬍘🀞឵; [B1, B6, P1, V6]; xn--jfb66gt010c.xn--3xa823h9p95ars26d; ; xn--jfb66gt010c.xn--4xa623h9p95ars26d; # 𑍧ߝ.ς🀞
+؁𑍧ߝ。Σ򬍘🀞឵; ؁𑍧ߝ.σ򬍘🀞឵; [B1, B6, P1, V6]; xn--jfb66gt010c.xn--4xa623h9p95ars26d; ; ; # 𑍧ߝ.σ🀞
+؁𑍧ߝ。σ򬍘🀞឵; ؁𑍧ߝ.σ򬍘🀞឵; [B1, B6, P1, V6]; xn--jfb66gt010c.xn--4xa623h9p95ars26d; ; ; # 𑍧ߝ.σ🀞
+xn--jfb66gt010c.xn--4xa623h9p95ars26d; ؁𑍧ߝ.σ򬍘🀞឵; [B1, B6, V6]; xn--jfb66gt010c.xn--4xa623h9p95ars26d; ; ; # 𑍧ߝ.σ🀞
+xn--jfb66gt010c.xn--3xa823h9p95ars26d; ؁𑍧ߝ.ς򬍘🀞឵; [B1, B6, V6]; xn--jfb66gt010c.xn--3xa823h9p95ars26d; ; ; # 𑍧ߝ.ς🀞
+-𐳲ن󠺐。꯭𝟥; -𐳲ن󠺐.꯭3; [B1, P1, V3, V5, V6]; xn----roc5482rek10i.xn--3-zw5e; ; ; # -𐳲ن.꯭3
+-𐳲ن󠺐。꯭3; -𐳲ن󠺐.꯭3; [B1, P1, V3, V5, V6]; xn----roc5482rek10i.xn--3-zw5e; ; ; # -𐳲ن.꯭3
+-𐲲ن󠺐。꯭3; -𐳲ن󠺐.꯭3; [B1, P1, V3, V5, V6]; xn----roc5482rek10i.xn--3-zw5e; ; ; # -𐳲ن.꯭3
+xn----roc5482rek10i.xn--3-zw5e; -𐳲ن󠺐.꯭3; [B1, V3, V5, V6]; xn----roc5482rek10i.xn--3-zw5e; ; ; # -𐳲ن.꯭3
+-𐲲ن󠺐。꯭𝟥; -𐳲ن󠺐.꯭3; [B1, P1, V3, V5, V6]; xn----roc5482rek10i.xn--3-zw5e; ; ; # -𐳲ن.꯭3
+‌󠴦。񲨕≮𐦜; ‌󠴦.񲨕≮𐦜; [B1, B5, B6, C1, P1, V6]; xn--0ug22251l.xn--gdhz712gzlr6b; ; xn--6v56e.xn--gdhz712gzlr6b; [B1, B5, B6, P1, V6] # .≮𐦜
+‌󠴦。񲨕≮𐦜; ‌󠴦.񲨕≮𐦜; [B1, B5, B6, C1, P1, V6]; xn--0ug22251l.xn--gdhz712gzlr6b; ; xn--6v56e.xn--gdhz712gzlr6b; [B1, B5, B6, P1, V6] # .≮𐦜
+‌󠴦。񲨕≮𐦜; ‌󠴦.񲨕≮𐦜; [B1, B5, B6, C1, P1, V6]; xn--0ug22251l.xn--gdhz712gzlr6b; ; xn--6v56e.xn--gdhz712gzlr6b; [B1, B5, B6, P1, V6] # .≮𐦜
+‌󠴦。񲨕≮𐦜; ‌󠴦.񲨕≮𐦜; [B1, B5, B6, C1, P1, V6]; xn--0ug22251l.xn--gdhz712gzlr6b; ; xn--6v56e.xn--gdhz712gzlr6b; [B1, B5, B6, P1, V6] # .≮𐦜
+xn--6v56e.xn--gdhz712gzlr6b; 󠴦.񲨕≮𐦜; [B1, B5, B6, V6]; xn--6v56e.xn--gdhz712gzlr6b; ; ; # .≮𐦜
+xn--0ug22251l.xn--gdhz712gzlr6b; ‌󠴦.񲨕≮𐦜; [B1, B5, B6, C1, V6]; xn--0ug22251l.xn--gdhz712gzlr6b; ; ; # .≮𐦜
+⒈✌򟬟.𝟡񠱣; ⒈✌򟬟.9񠱣; [P1, V6]; xn--tsh24g49550b.xn--9-o706d; ; ; # ⒈✌.9
+1.✌򟬟.9񠱣; ; [P1, V6]; 1.xn--7bi44996f.xn--9-o706d; ; ; # 1.✌.9
+1.xn--7bi44996f.xn--9-o706d; 1.✌򟬟.9񠱣; [V6]; 1.xn--7bi44996f.xn--9-o706d; ; ; # 1.✌.9
+xn--tsh24g49550b.xn--9-o706d; ⒈✌򟬟.9񠱣; [V6]; xn--tsh24g49550b.xn--9-o706d; ; ; # ⒈✌.9
+𑆾𞤬𐮆.٦ᷔ; ; [B1, V5]; xn--d29c79hf98r.xn--fib011j; ; ; # 𑆾𞤬𐮆.٦ᷔ
+𑆾𞤊𐮆.٦ᷔ; 𑆾𞤬𐮆.٦ᷔ; [B1, V5]; xn--d29c79hf98r.xn--fib011j; ; ; # 𑆾𞤬𐮆.٦ᷔ
+xn--d29c79hf98r.xn--fib011j; 𑆾𞤬𐮆.٦ᷔ; [B1, V5]; xn--d29c79hf98r.xn--fib011j; ; ; # 𑆾𞤬𐮆.٦ᷔ
+ς.꧀꣄; ς.꧀꣄; [V5]; xn--3xa.xn--0f9ars; ; xn--4xa.xn--0f9ars; # ς.꧀꣄
+ς.꧀꣄; ; [V5]; xn--3xa.xn--0f9ars; ; xn--4xa.xn--0f9ars; # ς.꧀꣄
+Σ.꧀꣄; σ.꧀꣄; [V5]; xn--4xa.xn--0f9ars; ; ; # σ.꧀꣄
+σ.꧀꣄; ; [V5]; xn--4xa.xn--0f9ars; ; ; # σ.꧀꣄
+xn--4xa.xn--0f9ars; σ.꧀꣄; [V5]; xn--4xa.xn--0f9ars; ; ; # σ.꧀꣄
+xn--3xa.xn--0f9ars; ς.꧀꣄; [V5]; xn--3xa.xn--0f9ars; ; ; # ς.꧀꣄
+Σ.꧀꣄; σ.꧀꣄; [V5]; xn--4xa.xn--0f9ars; ; ; # σ.꧀꣄
+σ.꧀꣄; σ.꧀꣄; [V5]; xn--4xa.xn--0f9ars; ; ; # σ.꧀꣄
+𑰶‌≯𐳐.࡛; 𑰶‌≯𐳐.࡛; [B1, B3, B6, C1, P1, V5, V6]; xn--0ug06g7697ap4ma.xn--qwb; ; xn--hdhz343g3wj.xn--qwb; [B1, B3, B6, P1, V5, V6] # 𑰶≯𐳐.࡛
+𑰶‌≯𐳐.࡛; 𑰶‌≯𐳐.࡛; [B1, B3, B6, C1, P1, V5, V6]; xn--0ug06g7697ap4ma.xn--qwb; ; xn--hdhz343g3wj.xn--qwb; [B1, B3, B6, P1, V5, V6] # 𑰶≯𐳐.࡛
+𑰶‌≯𐳐.࡛; ; [B1, B3, B6, C1, P1, V5, V6]; xn--0ug06g7697ap4ma.xn--qwb; ; xn--hdhz343g3wj.xn--qwb; [B1, B3, B6, P1, V5, V6] # 𑰶≯𐳐.࡛
+𑰶‌≯𐳐.࡛; 𑰶‌≯𐳐.࡛; [B1, B3, B6, C1, P1, V5, V6]; xn--0ug06g7697ap4ma.xn--qwb; ; xn--hdhz343g3wj.xn--qwb; [B1, B3, B6, P1, V5, V6] # 𑰶≯𐳐.࡛
+𑰶‌≯𐲐.࡛; 𑰶‌≯𐳐.࡛; [B1, B3, B6, C1, P1, V5, V6]; xn--0ug06g7697ap4ma.xn--qwb; ; xn--hdhz343g3wj.xn--qwb; [B1, B3, B6, P1, V5, V6] # 𑰶≯𐳐.࡛
+𑰶‌≯𐲐.࡛; 𑰶‌≯𐳐.࡛; [B1, B3, B6, C1, P1, V5, V6]; xn--0ug06g7697ap4ma.xn--qwb; ; xn--hdhz343g3wj.xn--qwb; [B1, B3, B6, P1, V5, V6] # 𑰶≯𐳐.࡛
+xn--hdhz343g3wj.xn--qwb; 𑰶≯𐳐.࡛; [B1, B3, B6, V5, V6]; xn--hdhz343g3wj.xn--qwb; ; ; # 𑰶≯𐳐.࡛
+xn--0ug06g7697ap4ma.xn--qwb; 𑰶‌≯𐳐.࡛; [B1, B3, B6, C1, V5, V6]; xn--0ug06g7697ap4ma.xn--qwb; ; ; # 𑰶≯𐳐.࡛
+𑰶‌≯𐲐.࡛; 𑰶‌≯𐳐.࡛; [B1, B3, B6, C1, P1, V5, V6]; xn--0ug06g7697ap4ma.xn--qwb; ; xn--hdhz343g3wj.xn--qwb; [B1, B3, B6, P1, V5, V6] # 𑰶≯𐳐.࡛
+𑰶‌≯𐲐.࡛; 𑰶‌≯𐳐.࡛; [B1, B3, B6, C1, P1, V5, V6]; xn--0ug06g7697ap4ma.xn--qwb; ; xn--hdhz343g3wj.xn--qwb; [B1, B3, B6, P1, V5, V6] # 𑰶≯𐳐.࡛
+羚。≯; 羚.≯; [P1, V6]; xn--xt0a.xn--hdh; ; ; # 羚.≯
+羚。≯; 羚.≯; [P1, V6]; xn--xt0a.xn--hdh; ; ; # 羚.≯
+羚。≯; 羚.≯; [P1, V6]; xn--xt0a.xn--hdh; ; ; # 羚.≯
+羚。≯; 羚.≯; [P1, V6]; xn--xt0a.xn--hdh; ; ; # 羚.≯
+xn--xt0a.xn--hdh; 羚.≯; [V6]; xn--xt0a.xn--hdh; ; ; # 羚.≯
+𑓂᝙.ࢨ; 𑓂᝙.ࢨ; [B1, P1, V5, V6]; xn--e1e9580k.xn--xyb; ; ; # 𑓂.ࢨ
+𑓂᝙.ࢨ; ; [B1, P1, V5, V6]; xn--e1e9580k.xn--xyb; ; ; # 𑓂.ࢨ
+xn--e1e9580k.xn--xyb; 𑓂᝙.ࢨ; [B1, V5, V6]; xn--e1e9580k.xn--xyb; ; ; # 𑓂.ࢨ
+󨣿󠇀‍。٣ҠჀ𝟑; 󨣿‍.٣ҡჀ3; [B1, B6, C2, P1, V6]; xn--1ug89936l.xn--3-ozb36kixu; ; xn--1r19e.xn--3-ozb36kixu; [B1, P1, V6] # .٣ҡჀ3
+󨣿󠇀‍。٣ҠჀ3; 󨣿‍.٣ҡჀ3; [B1, B6, C2, P1, V6]; xn--1ug89936l.xn--3-ozb36kixu; ; xn--1r19e.xn--3-ozb36kixu; [B1, P1, V6] # .٣ҡჀ3
+󨣿󠇀‍。٣ҡⴠ3; 󨣿‍.٣ҡⴠ3; [B1, B6, C2, P1, V6]; xn--1ug89936l.xn--3-ozb36ko13f; ; xn--1r19e.xn--3-ozb36ko13f; [B1, P1, V6] # .٣ҡⴠ3
+xn--1r19e.xn--3-ozb36ko13f; 󨣿.٣ҡⴠ3; [B1, V6]; xn--1r19e.xn--3-ozb36ko13f; ; ; # .٣ҡⴠ3
+xn--1ug89936l.xn--3-ozb36ko13f; 󨣿‍.٣ҡⴠ3; [B1, B6, C2, V6]; xn--1ug89936l.xn--3-ozb36ko13f; ; ; # .٣ҡⴠ3
+xn--1r19e.xn--3-ozb36kixu; 󨣿.٣ҡჀ3; [B1, V6]; xn--1r19e.xn--3-ozb36kixu; ; ; # .٣ҡჀ3
+xn--1ug89936l.xn--3-ozb36kixu; 󨣿‍.٣ҡჀ3; [B1, B6, C2, V6]; xn--1ug89936l.xn--3-ozb36kixu; ; ; # .٣ҡჀ3
+󨣿󠇀‍。٣ҡⴠ𝟑; 󨣿‍.٣ҡⴠ3; [B1, B6, C2, P1, V6]; xn--1ug89936l.xn--3-ozb36ko13f; ; xn--1r19e.xn--3-ozb36ko13f; [B1, P1, V6] # .٣ҡⴠ3
+󨣿󠇀‍。٣Ҡⴠ3; 󨣿‍.٣ҡⴠ3; [B1, B6, C2, P1, V6]; xn--1ug89936l.xn--3-ozb36ko13f; ; xn--1r19e.xn--3-ozb36ko13f; [B1, P1, V6] # .٣ҡⴠ3
+󨣿󠇀‍。٣Ҡⴠ𝟑; 󨣿‍.٣ҡⴠ3; [B1, B6, C2, P1, V6]; xn--1ug89936l.xn--3-ozb36ko13f; ; xn--1r19e.xn--3-ozb36ko13f; [B1, P1, V6] # .٣ҡⴠ3
+ᡷ。𐹢࣠; ᡷ.𐹢࣠; [B1]; xn--k9e.xn--j0b5005k; ; ; # ᡷ.𐹢࣠
+xn--k9e.xn--j0b5005k; ᡷ.𐹢࣠; [B1]; xn--k9e.xn--j0b5005k; ; ; # ᡷ.𐹢࣠
+򕮇᯳。٦񗜼្ß; 򕮇᯳.٦񗜼្ß; [B1, P1, V6]; xn--1zf58212h.xn--zca34zk4qx711k; ; xn--1zf58212h.xn--ss-pyd459o3258m; # ᯳.٦្ß
+򕮇᯳。٦񗜼្ß; 򕮇᯳.٦񗜼្ß; [B1, P1, V6]; xn--1zf58212h.xn--zca34zk4qx711k; ; xn--1zf58212h.xn--ss-pyd459o3258m; # ᯳.٦្ß
+򕮇᯳。٦񗜼្SS; 򕮇᯳.٦񗜼្ss; [B1, P1, V6]; xn--1zf58212h.xn--ss-pyd459o3258m; ; ; # ᯳.٦្ss
+򕮇᯳。٦񗜼្ss; 򕮇᯳.٦񗜼្ss; [B1, P1, V6]; xn--1zf58212h.xn--ss-pyd459o3258m; ; ; # ᯳.٦្ss
+򕮇᯳。٦񗜼្Ss; 򕮇᯳.٦񗜼្ss; [B1, P1, V6]; xn--1zf58212h.xn--ss-pyd459o3258m; ; ; # ᯳.٦្ss
+xn--1zf58212h.xn--ss-pyd459o3258m; 򕮇᯳.٦񗜼្ss; [B1, V6]; xn--1zf58212h.xn--ss-pyd459o3258m; ; ; # ᯳.٦្ss
+xn--1zf58212h.xn--zca34zk4qx711k; 򕮇᯳.٦񗜼្ß; [B1, V6]; xn--1zf58212h.xn--zca34zk4qx711k; ; ; # ᯳.٦្ß
+򕮇᯳。٦񗜼្SS; 򕮇᯳.٦񗜼្ss; [B1, P1, V6]; xn--1zf58212h.xn--ss-pyd459o3258m; ; ; # ᯳.٦្ss
+򕮇᯳。٦񗜼្ss; 򕮇᯳.٦񗜼្ss; [B1, P1, V6]; xn--1zf58212h.xn--ss-pyd459o3258m; ; ; # ᯳.٦្ss
+򕮇᯳。٦񗜼្Ss; 򕮇᯳.٦񗜼្ss; [B1, P1, V6]; xn--1zf58212h.xn--ss-pyd459o3258m; ; ; # ᯳.٦្ss
+٤򤽎𑲛.󠔢︒≠; ; [B1, P1, V6]; xn--dib0653l2i02d.xn--1ch7467f14u4g; ; ; # ٤𑲛.︒≠
+٤򤽎𑲛.󠔢︒≠; ٤򤽎𑲛.󠔢︒≠; [B1, P1, V6]; xn--dib0653l2i02d.xn--1ch7467f14u4g; ; ; # ٤𑲛.︒≠
+٤򤽎𑲛.󠔢。≠; ٤򤽎𑲛.󠔢.≠; [B1, P1, V6]; xn--dib0653l2i02d.xn--k736e.xn--1ch; ; ; # ٤𑲛..≠
+٤򤽎𑲛.󠔢。≠; ٤򤽎𑲛.󠔢.≠; [B1, P1, V6]; xn--dib0653l2i02d.xn--k736e.xn--1ch; ; ; # ٤𑲛..≠
+xn--dib0653l2i02d.xn--k736e.xn--1ch; ٤򤽎𑲛.󠔢.≠; [B1, V6]; xn--dib0653l2i02d.xn--k736e.xn--1ch; ; ; # ٤𑲛..≠
+xn--dib0653l2i02d.xn--1ch7467f14u4g; ٤򤽎𑲛.󠔢︒≠; [B1, V6]; xn--dib0653l2i02d.xn--1ch7467f14u4g; ; ; # ٤𑲛.︒≠
+➆񷧕ỗ⒈.򑬒񡘮࡛𝟫; ➆񷧕ỗ⒈.򑬒񡘮࡛9; [P1, V6]; xn--6lg26tvvc6v99z.xn--9-6jd87310jtcqs; ; ; # ➆ỗ⒈.࡛9
+➆񷧕ỗ⒈.򑬒񡘮࡛𝟫; ➆񷧕ỗ⒈.򑬒񡘮࡛9; [P1, V6]; xn--6lg26tvvc6v99z.xn--9-6jd87310jtcqs; ; ; # ➆ỗ⒈.࡛9
+➆񷧕ỗ1..򑬒񡘮࡛9; ; [P1, V6, X4_2]; xn--1-3xm292b6044r..xn--9-6jd87310jtcqs; [P1, V6, A4_2]; ; # ➆ỗ1..࡛9
+➆񷧕ỗ1..򑬒񡘮࡛9; ➆񷧕ỗ1..򑬒񡘮࡛9; [P1, V6, X4_2]; xn--1-3xm292b6044r..xn--9-6jd87310jtcqs; [P1, V6, A4_2]; ; # ➆ỗ1..࡛9
+➆񷧕Ỗ1..򑬒񡘮࡛9; ➆񷧕ỗ1..򑬒񡘮࡛9; [P1, V6, X4_2]; xn--1-3xm292b6044r..xn--9-6jd87310jtcqs; [P1, V6, A4_2]; ; # ➆ỗ1..࡛9
+➆񷧕Ỗ1..򑬒񡘮࡛9; ➆񷧕ỗ1..򑬒񡘮࡛9; [P1, V6, X4_2]; xn--1-3xm292b6044r..xn--9-6jd87310jtcqs; [P1, V6, A4_2]; ; # ➆ỗ1..࡛9
+xn--1-3xm292b6044r..xn--9-6jd87310jtcqs; ➆񷧕ỗ1..򑬒񡘮࡛9; [V6, X4_2]; xn--1-3xm292b6044r..xn--9-6jd87310jtcqs; [V6, A4_2]; ; # ➆ỗ1..࡛9
+➆񷧕Ỗ⒈.򑬒񡘮࡛𝟫; ➆񷧕ỗ⒈.򑬒񡘮࡛9; [P1, V6]; xn--6lg26tvvc6v99z.xn--9-6jd87310jtcqs; ; ; # ➆ỗ⒈.࡛9
+➆񷧕Ỗ⒈.򑬒񡘮࡛𝟫; ➆񷧕ỗ⒈.򑬒񡘮࡛9; [P1, V6]; xn--6lg26tvvc6v99z.xn--9-6jd87310jtcqs; ; ; # ➆ỗ⒈.࡛9
+xn--6lg26tvvc6v99z.xn--9-6jd87310jtcqs; ➆񷧕ỗ⒈.򑬒񡘮࡛9; [V6]; xn--6lg26tvvc6v99z.xn--9-6jd87310jtcqs; ; ; # ➆ỗ⒈.࡛9
+‍。𞤘; ‍.𞤺; [B1, C2]; xn--1ug.xn--ye6h; ; .xn--ye6h; [A4_2] # .𞤺
+‍。𞤘; ‍.𞤺; [B1, C2]; xn--1ug.xn--ye6h; ; .xn--ye6h; [A4_2] # .𞤺
+‍。𞤺; ‍.𞤺; [B1, C2]; xn--1ug.xn--ye6h; ; .xn--ye6h; [A4_2] # .𞤺
+.xn--ye6h; .𞤺; [X4_2]; .xn--ye6h; [A4_2]; ; # .𞤺
+xn--1ug.xn--ye6h; ‍.𞤺; [B1, C2]; xn--1ug.xn--ye6h; ; ; # .𞤺
+‍。𞤺; ‍.𞤺; [B1, C2]; xn--1ug.xn--ye6h; ; .xn--ye6h; [A4_2] # .𞤺
+xn--ye6h; 𞤺; ; xn--ye6h; ; ; # 𞤺
+𞤺; ; ; xn--ye6h; ; ; # 𞤺
+𞤘; 𞤺; ; xn--ye6h; ; ; # 𞤺
+ࠩܤ.ᢣ; ; [B1, V5]; xn--unb53c.xn--tbf; ; ; # ࠩܤ.ᢣ
+xn--unb53c.xn--tbf; ࠩܤ.ᢣ; [B1, V5]; xn--unb53c.xn--tbf; ; ; # ࠩܤ.ᢣ
+ܼ‌-。𓐾ß; ܼ‌-.𓐾ß; [C1, P1, V3, V5, V6]; xn----s2c071q.xn--zca7848m; ; xn----s2c.xn--ss-066q; [P1, V3, V5, V6] # ܼ-.ß
+ܼ‌-。𓐾SS; ܼ‌-.𓐾ss; [C1, P1, V3, V5, V6]; xn----s2c071q.xn--ss-066q; ; xn----s2c.xn--ss-066q; [P1, V3, V5, V6] # ܼ-.ss
+ܼ‌-。𓐾ss; ܼ‌-.𓐾ss; [C1, P1, V3, V5, V6]; xn----s2c071q.xn--ss-066q; ; xn----s2c.xn--ss-066q; [P1, V3, V5, V6] # ܼ-.ss
+ܼ‌-。𓐾Ss; ܼ‌-.𓐾ss; [C1, P1, V3, V5, V6]; xn----s2c071q.xn--ss-066q; ; xn----s2c.xn--ss-066q; [P1, V3, V5, V6] # ܼ-.ss
+xn----s2c.xn--ss-066q; ܼ-.𓐾ss; [V3, V5, V6]; xn----s2c.xn--ss-066q; ; ; # ܼ-.ss
+xn----s2c071q.xn--ss-066q; ܼ‌-.𓐾ss; [C1, V3, V5, V6]; xn----s2c071q.xn--ss-066q; ; ; # ܼ-.ss
+xn----s2c071q.xn--zca7848m; ܼ‌-.𓐾ß; [C1, V3, V5, V6]; xn----s2c071q.xn--zca7848m; ; ; # ܼ-.ß
+‌ς🃡⒗.ೆ仧ݖ; ; [B1, B5, B6, C1, P1, V5, V6]; xn--3xa795lz9czy52d.xn--9ob79ycx2e; ; xn--4xa229nbu92a.xn--9ob79ycx2e; [B5, B6, P1, V5, V6] # ς🃡⒗.ೆ仧ݖ
+‌ς🃡16..ೆ仧ݖ; ; [B1, B5, B6, C1, V5, X4_2]; xn--16-rbc1800avy99b..xn--9ob79ycx2e; [B1, B5, B6, C1, V5, A4_2]; xn--16-ubc66061c..xn--9ob79ycx2e; [B5, B6, V5, A4_2] # ς🃡16..ೆ仧ݖ
+‌Σ🃡16..ೆ仧ݖ; ‌σ🃡16..ೆ仧ݖ; [B1, B5, B6, C1, V5, X4_2]; xn--16-ubc7700avy99b..xn--9ob79ycx2e; [B1, B5, B6, C1, V5, A4_2]; xn--16-ubc66061c..xn--9ob79ycx2e; [B5, B6, V5, A4_2] # σ🃡16..ೆ仧ݖ
+‌σ🃡16..ೆ仧ݖ; ; [B1, B5, B6, C1, V5, X4_2]; xn--16-ubc7700avy99b..xn--9ob79ycx2e; [B1, B5, B6, C1, V5, A4_2]; xn--16-ubc66061c..xn--9ob79ycx2e; [B5, B6, V5, A4_2] # σ🃡16..ೆ仧ݖ
+xn--16-ubc66061c..xn--9ob79ycx2e; σ🃡16..ೆ仧ݖ; [B5, B6, V5, X4_2]; xn--16-ubc66061c..xn--9ob79ycx2e; [B5, B6, V5, A4_2]; ; # σ🃡16..ೆ仧ݖ
+xn--16-ubc7700avy99b..xn--9ob79ycx2e; ‌σ🃡16..ೆ仧ݖ; [B1, B5, B6, C1, V5, X4_2]; xn--16-ubc7700avy99b..xn--9ob79ycx2e; [B1, B5, B6, C1, V5, A4_2]; ; # σ🃡16..ೆ仧ݖ
+xn--16-rbc1800avy99b..xn--9ob79ycx2e; ‌ς🃡16..ೆ仧ݖ; [B1, B5, B6, C1, V5, X4_2]; xn--16-rbc1800avy99b..xn--9ob79ycx2e; [B1, B5, B6, C1, V5, A4_2]; ; # ς🃡16..ೆ仧ݖ
+‌Σ🃡⒗.ೆ仧ݖ; ‌σ🃡⒗.ೆ仧ݖ; [B1, B5, B6, C1, P1, V5, V6]; xn--4xa595lz9czy52d.xn--9ob79ycx2e; ; xn--4xa229nbu92a.xn--9ob79ycx2e; [B5, B6, P1, V5, V6] # σ🃡⒗.ೆ仧ݖ
+‌σ🃡⒗.ೆ仧ݖ; ; [B1, B5, B6, C1, P1, V5, V6]; xn--4xa595lz9czy52d.xn--9ob79ycx2e; ; xn--4xa229nbu92a.xn--9ob79ycx2e; [B5, B6, P1, V5, V6] # σ🃡⒗.ೆ仧ݖ
+xn--4xa229nbu92a.xn--9ob79ycx2e; σ🃡⒗.ೆ仧ݖ; [B5, B6, V5, V6]; xn--4xa229nbu92a.xn--9ob79ycx2e; ; ; # σ🃡⒗.ೆ仧ݖ
+xn--4xa595lz9czy52d.xn--9ob79ycx2e; ‌σ🃡⒗.ೆ仧ݖ; [B1, B5, B6, C1, V5, V6]; xn--4xa595lz9czy52d.xn--9ob79ycx2e; ; ; # σ🃡⒗.ೆ仧ݖ
+xn--3xa795lz9czy52d.xn--9ob79ycx2e; ‌ς🃡⒗.ೆ仧ݖ; [B1, B5, B6, C1, V5, V6]; xn--3xa795lz9czy52d.xn--9ob79ycx2e; ; ; # ς🃡⒗.ೆ仧ݖ
+-.𞸚; -.ظ; [B1, V3]; -.xn--3gb; ; ; # -.ظ
+-.ظ; ; [B1, V3]; -.xn--3gb; ; ; # -.ظ
+-.xn--3gb; -.ظ; [B1, V3]; -.xn--3gb; ; ; # -.ظ
+򏛓ڃ.ཾش; ; [B1, B5, B6, P1, V5, V6]; xn--8ib92728i.xn--zgb968b; ; ; # ڃ.ཾش
+xn--8ib92728i.xn--zgb968b; 򏛓ڃ.ཾش; [B1, B5, B6, V5, V6]; xn--8ib92728i.xn--zgb968b; ; ; # ڃ.ཾش
+࿦ࡃ񽶬.𐮏; ; [B5, P1, V6]; xn--1vb320b5m04p.xn--m29c; ; ; # ࡃ.𐮏
+xn--1vb320b5m04p.xn--m29c; ࿦ࡃ񽶬.𐮏; [B5, V6]; xn--1vb320b5m04p.xn--m29c; ; ; # ࡃ.𐮏
+2񎨠ߋß。ᠽ; 2񎨠ߋß.ᠽ; [B1, P1, V6]; xn--2-qfa924cez02l.xn--w7e; ; xn--2ss-odg83511n.xn--w7e; # 2ߋß.ᠽ
+2񎨠ߋSS。ᠽ; 2񎨠ߋss.ᠽ; [B1, P1, V6]; xn--2ss-odg83511n.xn--w7e; ; ; # 2ߋss.ᠽ
+2񎨠ߋss。ᠽ; 2񎨠ߋss.ᠽ; [B1, P1, V6]; xn--2ss-odg83511n.xn--w7e; ; ; # 2ߋss.ᠽ
+xn--2ss-odg83511n.xn--w7e; 2񎨠ߋss.ᠽ; [B1, V6]; xn--2ss-odg83511n.xn--w7e; ; ; # 2ߋss.ᠽ
+xn--2-qfa924cez02l.xn--w7e; 2񎨠ߋß.ᠽ; [B1, V6]; xn--2-qfa924cez02l.xn--w7e; ; ; # 2ߋß.ᠽ
+2񎨠ߋSs。ᠽ; 2񎨠ߋss.ᠽ; [B1, P1, V6]; xn--2ss-odg83511n.xn--w7e; ; ; # 2ߋss.ᠽ
+㸳ߊ≮.ێß-‍; 㸳ߊ≮.ێß-‍; [B2, B3, B5, B6, C2, P1, V6]; xn--lsb457kkut.xn----pfa076bys4a; ; xn--lsb457kkut.xn--ss--qjf; [B2, B3, B5, B6, P1, V3, V6] # 㸳ߊ≮.ێß-
+㸳ߊ≮.ێß-‍; 㸳ߊ≮.ێß-‍; [B2, B3, B5, B6, C2, P1, V6]; xn--lsb457kkut.xn----pfa076bys4a; ; xn--lsb457kkut.xn--ss--qjf; [B2, B3, B5, B6, P1, V3, V6] # 㸳ߊ≮.ێß-
+㸳ߊ≮.ێß-‍; ; [B2, B3, B5, B6, C2, P1, V6]; xn--lsb457kkut.xn----pfa076bys4a; ; xn--lsb457kkut.xn--ss--qjf; [B2, B3, B5, B6, P1, V3, V6] # 㸳ߊ≮.ێß-
+㸳ߊ≮.ێß-‍; 㸳ߊ≮.ێß-‍; [B2, B3, B5, B6, C2, P1, V6]; xn--lsb457kkut.xn----pfa076bys4a; ; xn--lsb457kkut.xn--ss--qjf; [B2, B3, B5, B6, P1, V3, V6] # 㸳ߊ≮.ێß-
+㸳ߊ≮.ێSS-‍; 㸳ߊ≮.ێss-‍; [B2, B3, B5, B6, C2, P1, V6]; xn--lsb457kkut.xn--ss--qjf2343a; ; xn--lsb457kkut.xn--ss--qjf; [B2, B3, B5, B6, P1, V3, V6] # 㸳ߊ≮.ێss-
+㸳ߊ≮.ێSS-‍; 㸳ߊ≮.ێss-‍; [B2, B3, B5, B6, C2, P1, V6]; xn--lsb457kkut.xn--ss--qjf2343a; ; xn--lsb457kkut.xn--ss--qjf; [B2, B3, B5, B6, P1, V3, V6] # 㸳ߊ≮.ێss-
+㸳ߊ≮.ێss-‍; ; [B2, B3, B5, B6, C2, P1, V6]; xn--lsb457kkut.xn--ss--qjf2343a; ; xn--lsb457kkut.xn--ss--qjf; [B2, B3, B5, B6, P1, V3, V6] # 㸳ߊ≮.ێss-
+㸳ߊ≮.ێss-‍; 㸳ߊ≮.ێss-‍; [B2, B3, B5, B6, C2, P1, V6]; xn--lsb457kkut.xn--ss--qjf2343a; ; xn--lsb457kkut.xn--ss--qjf; [B2, B3, B5, B6, P1, V3, V6] # 㸳ߊ≮.ێss-
+xn--lsb457kkut.xn--ss--qjf; 㸳ߊ≮.ێss-; [B2, B3, B5, B6, V3, V6]; xn--lsb457kkut.xn--ss--qjf; ; ; # 㸳ߊ≮.ێss-
+xn--lsb457kkut.xn--ss--qjf2343a; 㸳ߊ≮.ێss-‍; [B2, B3, B5, B6, C2, V6]; xn--lsb457kkut.xn--ss--qjf2343a; ; ; # 㸳ߊ≮.ێss-
+xn--lsb457kkut.xn----pfa076bys4a; 㸳ߊ≮.ێß-‍; [B2, B3, B5, B6, C2, V6]; xn--lsb457kkut.xn----pfa076bys4a; ; ; # 㸳ߊ≮.ێß-
+㸳ߊ≮.ێSS-‍; 㸳ߊ≮.ێss-‍; [B2, B3, B5, B6, C2, P1, V6]; xn--lsb457kkut.xn--ss--qjf2343a; ; xn--lsb457kkut.xn--ss--qjf; [B2, B3, B5, B6, P1, V3, V6] # 㸳ߊ≮.ێss-
+㸳ߊ≮.ێSS-‍; 㸳ߊ≮.ێss-‍; [B2, B3, B5, B6, C2, P1, V6]; xn--lsb457kkut.xn--ss--qjf2343a; ; xn--lsb457kkut.xn--ss--qjf; [B2, B3, B5, B6, P1, V3, V6] # 㸳ߊ≮.ێss-
+㸳ߊ≮.ێss-‍; 㸳ߊ≮.ێss-‍; [B2, B3, B5, B6, C2, P1, V6]; xn--lsb457kkut.xn--ss--qjf2343a; ; xn--lsb457kkut.xn--ss--qjf; [B2, B3, B5, B6, P1, V3, V6] # 㸳ߊ≮.ێss-
+㸳ߊ≮.ێss-‍; 㸳ߊ≮.ێss-‍; [B2, B3, B5, B6, C2, P1, V6]; xn--lsb457kkut.xn--ss--qjf2343a; ; xn--lsb457kkut.xn--ss--qjf; [B2, B3, B5, B6, P1, V3, V6] # 㸳ߊ≮.ێss-
+㸳ߊ≮.ێSs-‍; 㸳ߊ≮.ێss-‍; [B2, B3, B5, B6, C2, P1, V6]; xn--lsb457kkut.xn--ss--qjf2343a; ; xn--lsb457kkut.xn--ss--qjf; [B2, B3, B5, B6, P1, V3, V6] # 㸳ߊ≮.ێss-
+㸳ߊ≮.ێSs-‍; 㸳ߊ≮.ێss-‍; [B2, B3, B5, B6, C2, P1, V6]; xn--lsb457kkut.xn--ss--qjf2343a; ; xn--lsb457kkut.xn--ss--qjf; [B2, B3, B5, B6, P1, V3, V6] # 㸳ߊ≮.ێss-
+㸳ߊ≮.ێSs-‍; 㸳ߊ≮.ێss-‍; [B2, B3, B5, B6, C2, P1, V6]; xn--lsb457kkut.xn--ss--qjf2343a; ; xn--lsb457kkut.xn--ss--qjf; [B2, B3, B5, B6, P1, V3, V6] # 㸳ߊ≮.ێss-
+㸳ߊ≮.ێSs-‍; 㸳ߊ≮.ێss-‍; [B2, B3, B5, B6, C2, P1, V6]; xn--lsb457kkut.xn--ss--qjf2343a; ; xn--lsb457kkut.xn--ss--qjf; [B2, B3, B5, B6, P1, V3, V6] # 㸳ߊ≮.ێss-
+-򷝬፞𑜧.ᷫ-︒; ; [P1, V3, V5, V6]; xn----b5h1837n2ok9f.xn----mkmw278h; ; ; # -፞𑜧.ᷫ-︒
+-򷝬፞𑜧.ᷫ-。; -򷝬፞𑜧.ᷫ-.; [P1, V3, V5, V6]; xn----b5h1837n2ok9f.xn----mkm.; ; ; # -፞𑜧.ᷫ-.
+xn----b5h1837n2ok9f.xn----mkm.; -򷝬፞𑜧.ᷫ-.; [V3, V5, V6]; xn----b5h1837n2ok9f.xn----mkm.; ; ; # -፞𑜧.ᷫ-.
+xn----b5h1837n2ok9f.xn----mkmw278h; -򷝬፞𑜧.ᷫ-︒; [V3, V5, V6]; xn----b5h1837n2ok9f.xn----mkmw278h; ; ; # -፞𑜧.ᷫ-︒
+︒.򚠡ᩙ; ; [P1, V6]; xn--y86c.xn--cof61594i; ; ; # ︒.ᩙ
+。.򚠡ᩙ; ..򚠡ᩙ; [P1, V6, X4_2]; ..xn--cof61594i; [P1, V6, A4_2]; ; # ..ᩙ
+..xn--cof61594i; ..򚠡ᩙ; [V6, X4_2]; ..xn--cof61594i; [V6, A4_2]; ; # ..ᩙ
+xn--y86c.xn--cof61594i; ︒.򚠡ᩙ; [V6]; xn--y86c.xn--cof61594i; ; ; # ︒.ᩙ
+̣ⷡ。‌⓾‌ڹ; ̣ⷡ.‌⓾‌ڹ; [B1, B3, B6, C1, V5]; xn--kta899s.xn--skb970ka771c; ; xn--kta899s.xn--skb116m; [B1, B3, B6, V5] # ̣ⷡ.⓾ڹ
+xn--kta899s.xn--skb116m; ̣ⷡ.⓾ڹ; [B1, B3, B6, V5]; xn--kta899s.xn--skb116m; ; ; # ̣ⷡ.⓾ڹ
+xn--kta899s.xn--skb970ka771c; ̣ⷡ.‌⓾‌ڹ; [B1, B3, B6, C1, V5]; xn--kta899s.xn--skb970ka771c; ; ; # ̣ⷡ.⓾ڹ
+𞠶ᠴ۝。ၴ𞤵󠅦; 𞠶ᠴ۝.ၴ𞤵; [B1, B2, P1, V5, V6]; xn--tlb199fwl35a.xn--yld4613v; ; ; # 𞠶ᠴ.ၴ𞤵
+𞠶ᠴ۝。ၴ𞤵󠅦; 𞠶ᠴ۝.ၴ𞤵; [B1, B2, P1, V5, V6]; xn--tlb199fwl35a.xn--yld4613v; ; ; # 𞠶ᠴ.ၴ𞤵
+𞠶ᠴ۝。ၴ𞤓󠅦; 𞠶ᠴ۝.ၴ𞤵; [B1, B2, P1, V5, V6]; xn--tlb199fwl35a.xn--yld4613v; ; ; # 𞠶ᠴ.ၴ𞤵
+xn--tlb199fwl35a.xn--yld4613v; 𞠶ᠴ۝.ၴ𞤵; [B1, B2, V5, V6]; xn--tlb199fwl35a.xn--yld4613v; ; ; # 𞠶ᠴ.ၴ𞤵
+𞠶ᠴ۝。ၴ𞤓󠅦; 𞠶ᠴ۝.ၴ𞤵; [B1, B2, P1, V5, V6]; xn--tlb199fwl35a.xn--yld4613v; ; ; # 𞠶ᠴ.ၴ𞤵
+𑰺.-򑟏; ; [P1, V3, V5, V6]; xn--jk3d.xn----iz68g; ; ; # 𑰺.-
+xn--jk3d.xn----iz68g; 𑰺.-򑟏; [V3, V5, V6]; xn--jk3d.xn----iz68g; ; ; # 𑰺.-
+󠻩.赏; 󠻩.赏; [P1, V6]; xn--2856e.xn--6o3a; ; ; # .赏
+󠻩.赏; ; [P1, V6]; xn--2856e.xn--6o3a; ; ; # .赏
+xn--2856e.xn--6o3a; 󠻩.赏; [V6]; xn--2856e.xn--6o3a; ; ; # .赏
+ڰᠡ。Ⴁ; ڰᠡ.Ⴁ; [B2, B3, P1, V6]; xn--jkb440g.xn--8md; ; ; # ڰᠡ.Ⴁ
+ڰᠡ。Ⴁ; ڰᠡ.Ⴁ; [B2, B3, P1, V6]; xn--jkb440g.xn--8md; ; ; # ڰᠡ.Ⴁ
+ڰᠡ。ⴁ; ڰᠡ.ⴁ; [B2, B3]; xn--jkb440g.xn--skj; ; ; # ڰᠡ.ⴁ
+xn--jkb440g.xn--skj; ڰᠡ.ⴁ; [B2, B3]; xn--jkb440g.xn--skj; ; ; # ڰᠡ.ⴁ
+xn--jkb440g.xn--8md; ڰᠡ.Ⴁ; [B2, B3, V6]; xn--jkb440g.xn--8md; ; ; # ڰᠡ.Ⴁ
+ڰᠡ。ⴁ; ڰᠡ.ⴁ; [B2, B3]; xn--jkb440g.xn--skj; ; ; # ڰᠡ.ⴁ
+⃞Ⴊڻς。-; ⃞Ⴊڻς.-; [B1, P1, V3, V5, V6]; xn--3xa53m7zmb0q.-; ; xn--4xa33m7zmb0q.-; # ⃞Ⴊڻς.-
+⃞Ⴊڻς。-; ⃞Ⴊڻς.-; [B1, P1, V3, V5, V6]; xn--3xa53m7zmb0q.-; ; xn--4xa33m7zmb0q.-; # ⃞Ⴊڻς.-
+⃞ⴊڻς。-; ⃞ⴊڻς.-; [B1, V3, V5]; xn--3xa53mr38aeel.-; ; xn--4xa33mr38aeel.-; # ⃞ⴊڻς.-
+⃞ႪڻΣ。-; ⃞Ⴊڻσ.-; [B1, P1, V3, V5, V6]; xn--4xa33m7zmb0q.-; ; ; # ⃞Ⴊڻσ.-
+⃞ⴊڻσ。-; ⃞ⴊڻσ.-; [B1, V3, V5]; xn--4xa33mr38aeel.-; ; ; # ⃞ⴊڻσ.-
+⃞Ⴊڻσ。-; ⃞Ⴊڻσ.-; [B1, P1, V3, V5, V6]; xn--4xa33m7zmb0q.-; ; ; # ⃞Ⴊڻσ.-
+xn--4xa33m7zmb0q.-; ⃞Ⴊڻσ.-; [B1, V3, V5, V6]; xn--4xa33m7zmb0q.-; ; ; # ⃞Ⴊڻσ.-
+xn--4xa33mr38aeel.-; ⃞ⴊڻσ.-; [B1, V3, V5]; xn--4xa33mr38aeel.-; ; ; # ⃞ⴊڻσ.-
+xn--3xa53mr38aeel.-; ⃞ⴊڻς.-; [B1, V3, V5]; xn--3xa53mr38aeel.-; ; ; # ⃞ⴊڻς.-
+xn--3xa53m7zmb0q.-; ⃞Ⴊڻς.-; [B1, V3, V5, V6]; xn--3xa53m7zmb0q.-; ; ; # ⃞Ⴊڻς.-
+⃞ⴊڻς。-; ⃞ⴊڻς.-; [B1, V3, V5]; xn--3xa53mr38aeel.-; ; xn--4xa33mr38aeel.-; # ⃞ⴊڻς.-
+⃞ႪڻΣ。-; ⃞Ⴊڻσ.-; [B1, P1, V3, V5, V6]; xn--4xa33m7zmb0q.-; ; ; # ⃞Ⴊڻσ.-
+⃞ⴊڻσ。-; ⃞ⴊڻσ.-; [B1, V3, V5]; xn--4xa33mr38aeel.-; ; ; # ⃞ⴊڻσ.-
+⃞Ⴊڻσ。-; ⃞Ⴊڻσ.-; [B1, P1, V3, V5, V6]; xn--4xa33m7zmb0q.-; ; ; # ⃞Ⴊڻσ.-
+Ⴍ.񍇦‌; Ⴍ.񍇦‌; [C1, P1, V6]; xn--lnd.xn--0ug56448b; ; xn--lnd.xn--p01x; [P1, V6] # Ⴍ.
+Ⴍ.񍇦‌; ; [C1, P1, V6]; xn--lnd.xn--0ug56448b; ; xn--lnd.xn--p01x; [P1, V6] # Ⴍ.
+ⴍ.񍇦‌; ; [C1, P1, V6]; xn--4kj.xn--0ug56448b; ; xn--4kj.xn--p01x; [P1, V6] # ⴍ.
+xn--4kj.xn--p01x; ⴍ.񍇦; [V6]; xn--4kj.xn--p01x; ; ; # ⴍ.
+xn--4kj.xn--0ug56448b; ⴍ.񍇦‌; [C1, V6]; xn--4kj.xn--0ug56448b; ; ; # ⴍ.
+xn--lnd.xn--p01x; Ⴍ.񍇦; [V6]; xn--lnd.xn--p01x; ; ; # Ⴍ.
+xn--lnd.xn--0ug56448b; Ⴍ.񍇦‌; [C1, V6]; xn--lnd.xn--0ug56448b; ; ; # Ⴍ.
+ⴍ.񍇦‌; ⴍ.񍇦‌; [C1, P1, V6]; xn--4kj.xn--0ug56448b; ; xn--4kj.xn--p01x; [P1, V6] # ⴍ.
+򉟂󠵣.𐫫᩠󴺖᭄; ; [B2, B3, B6, P1, V6]; xn--9u37blu98h.xn--jof13bt568cork1j; ; ; # .𐫫᩠᭄
+xn--9u37blu98h.xn--jof13bt568cork1j; 򉟂󠵣.𐫫᩠󴺖᭄; [B2, B3, B6, V6]; xn--9u37blu98h.xn--jof13bt568cork1j; ; ; # .𐫫᩠᭄
+≯❊ᠯ。𐹱⺨; ≯❊ᠯ.𐹱⺨; [B1, P1, V6]; xn--i7e163ct2d.xn--vwj7372e; ; ; # ≯❊ᠯ.𐹱⺨
+≯❊ᠯ。𐹱⺨; ≯❊ᠯ.𐹱⺨; [B1, P1, V6]; xn--i7e163ct2d.xn--vwj7372e; ; ; # ≯❊ᠯ.𐹱⺨
+≯❊ᠯ。𐹱⺨; ≯❊ᠯ.𐹱⺨; [B1, P1, V6]; xn--i7e163ct2d.xn--vwj7372e; ; ; # ≯❊ᠯ.𐹱⺨
+≯❊ᠯ。𐹱⺨; ≯❊ᠯ.𐹱⺨; [B1, P1, V6]; xn--i7e163ct2d.xn--vwj7372e; ; ; # ≯❊ᠯ.𐹱⺨
+xn--i7e163ct2d.xn--vwj7372e; ≯❊ᠯ.𐹱⺨; [B1, V6]; xn--i7e163ct2d.xn--vwj7372e; ; ; # ≯❊ᠯ.𐹱⺨
+􁕜𐹧𞭁𐹩。Ⴈ𐫮Ⴏ; 􁕜𐹧𞭁𐹩.Ⴈ𐫮Ⴏ; [B5, B6, P1, V6]; xn--fo0de1270ope54j.xn--gndo2033q; ; ; # 𐹧𐹩.Ⴈ𐫮Ⴏ
+􁕜𐹧𞭁𐹩。ⴈ𐫮ⴏ; 􁕜𐹧𞭁𐹩.ⴈ𐫮ⴏ; [B5, B6, P1, V6]; xn--fo0de1270ope54j.xn--zkjo0151o; ; ; # 𐹧𐹩.ⴈ𐫮ⴏ
+xn--fo0de1270ope54j.xn--zkjo0151o; 􁕜𐹧𞭁𐹩.ⴈ𐫮ⴏ; [B5, B6, V6]; xn--fo0de1270ope54j.xn--zkjo0151o; ; ; # 𐹧𐹩.ⴈ𐫮ⴏ
+xn--fo0de1270ope54j.xn--gndo2033q; 􁕜𐹧𞭁𐹩.Ⴈ𐫮Ⴏ; [B5, B6, V6]; xn--fo0de1270ope54j.xn--gndo2033q; ; ; # 𐹧𐹩.Ⴈ𐫮Ⴏ
+𞠂。ꤦ; 𞠂.ꤦ; [B1, B3, B6, V5]; xn--145h.xn--ti9a; ; ; # 𞠂.ꤦ
+xn--145h.xn--ti9a; 𞠂.ꤦ; [B1, B3, B6, V5]; xn--145h.xn--ti9a; ; ; # 𞠂.ꤦ
+𝟔𐹫.့ܳ9ꡇ; 6𐹫.့ܳ9ꡇ; [B1, V5]; xn--6-t26i.xn--9-91c730e8u8n; ; ; # 6𐹫.့ܳ9ꡇ
+𝟔𐹫.့ܳ9ꡇ; 6𐹫.့ܳ9ꡇ; [B1, V5]; xn--6-t26i.xn--9-91c730e8u8n; ; ; # 6𐹫.့ܳ9ꡇ
+6𐹫.့ܳ9ꡇ; ; [B1, V5]; xn--6-t26i.xn--9-91c730e8u8n; ; ; # 6𐹫.့ܳ9ꡇ
+xn--6-t26i.xn--9-91c730e8u8n; 6𐹫.့ܳ9ꡇ; [B1, V5]; xn--6-t26i.xn--9-91c730e8u8n; ; ; # 6𐹫.့ܳ9ꡇ
+ܤ؃𞲶.ۘ; ܤ؃𞲶.ۘ; [B1, B3, B6, P1, V5, V6]; xn--lfb19ct414i.xn--olb; ; ; # ܤ.ۘ
+ܤ؃𞲶.ۘ; ; [B1, B3, B6, P1, V5, V6]; xn--lfb19ct414i.xn--olb; ; ; # ܤ.ۘ
+xn--lfb19ct414i.xn--olb; ܤ؃𞲶.ۘ; [B1, B3, B6, V5, V6]; xn--lfb19ct414i.xn--olb; ; ; # ܤ.ۘ
+✆񱔩ꡋ.ز‍𞣴; ✆񱔩ꡋ.ز‍𞣴; [B1, C2, P1, V6]; xn--1biv525bcix0d.xn--xgb253k0m73a; ; xn--1biv525bcix0d.xn--xgb6828v; [B1, P1, V6] # ✆ꡋ.ز
+✆񱔩ꡋ.ز‍𞣴; ; [B1, C2, P1, V6]; xn--1biv525bcix0d.xn--xgb253k0m73a; ; xn--1biv525bcix0d.xn--xgb6828v; [B1, P1, V6] # ✆ꡋ.ز
+xn--1biv525bcix0d.xn--xgb6828v; ✆񱔩ꡋ.ز𞣴; [B1, V6]; xn--1biv525bcix0d.xn--xgb6828v; ; ; # ✆ꡋ.ز
+xn--1biv525bcix0d.xn--xgb253k0m73a; ✆񱔩ꡋ.ز‍𞣴; [B1, C2, V6]; xn--1biv525bcix0d.xn--xgb253k0m73a; ; ; # ✆ꡋ.ز
+ࡅ񃾰𞸍-.≠򃁟𑋪; ࡅ񃾰ن-.≠򃁟𑋪; [B1, B2, B3, P1, V3, V6]; xn----qoc64my971s.xn--1ch7585g76o3c; ; ; # ࡅن-.≠𑋪
+ࡅ񃾰𞸍-.≠򃁟𑋪; ࡅ񃾰ن-.≠򃁟𑋪; [B1, B2, B3, P1, V3, V6]; xn----qoc64my971s.xn--1ch7585g76o3c; ; ; # ࡅن-.≠𑋪
+ࡅ񃾰ن-.≠򃁟𑋪; ; [B1, B2, B3, P1, V3, V6]; xn----qoc64my971s.xn--1ch7585g76o3c; ; ; # ࡅن-.≠𑋪
+ࡅ񃾰ن-.≠򃁟𑋪; ࡅ񃾰ن-.≠򃁟𑋪; [B1, B2, B3, P1, V3, V6]; xn----qoc64my971s.xn--1ch7585g76o3c; ; ; # ࡅن-.≠𑋪
+xn----qoc64my971s.xn--1ch7585g76o3c; ࡅ񃾰ن-.≠򃁟𑋪; [B1, B2, B3, V3, V6]; xn----qoc64my971s.xn--1ch7585g76o3c; ; ; # ࡅن-.≠𑋪
+𝟛.笠; 3.笠; ; 3.xn--6vz; ; ; # 3.笠
+𝟛.笠; 3.笠; ; 3.xn--6vz; ; ; # 3.笠
+3.笠; ; ; 3.xn--6vz; ; ; # 3.笠
+3.xn--6vz; 3.笠; ; 3.xn--6vz; ; ; # 3.笠
+-‍.Ⴞ𐋷; ; [C2, P1, V3, V6]; xn----ugn.xn--2nd2315j; ; -.xn--2nd2315j; [P1, V3, V6] # -.Ⴞ𐋷
+-‍.ⴞ𐋷; ; [C2, V3]; xn----ugn.xn--mlj8559d; ; -.xn--mlj8559d; [V3] # -.ⴞ𐋷
+-.xn--mlj8559d; -.ⴞ𐋷; [V3]; -.xn--mlj8559d; ; ; # -.ⴞ𐋷
+xn----ugn.xn--mlj8559d; -‍.ⴞ𐋷; [C2, V3]; xn----ugn.xn--mlj8559d; ; ; # -.ⴞ𐋷
+-.xn--2nd2315j; -.Ⴞ𐋷; [V3, V6]; -.xn--2nd2315j; ; ; # -.Ⴞ𐋷
+xn----ugn.xn--2nd2315j; -‍.Ⴞ𐋷; [C2, V3, V6]; xn----ugn.xn--2nd2315j; ; ; # -.Ⴞ𐋷
+‍ςßܱ.்; ‍ςßܱ.்; [C2, V5]; xn--zca19ln1di19a.xn--xmc; ; xn--ss-ubc826a.xn--xmc; [V5] # ςßܱ.்
+‍ςßܱ.்; ; [C2, V5]; xn--zca19ln1di19a.xn--xmc; ; xn--ss-ubc826a.xn--xmc; [V5] # ςßܱ.்
+‍ΣSSܱ.்; ‍σssܱ.்; [C2, V5]; xn--ss-ubc826ab34b.xn--xmc; ; xn--ss-ubc826a.xn--xmc; [V5] # σssܱ.்
+‍σssܱ.்; ; [C2, V5]; xn--ss-ubc826ab34b.xn--xmc; ; xn--ss-ubc826a.xn--xmc; [V5] # σssܱ.்
+‍Σssܱ.்; ‍σssܱ.்; [C2, V5]; xn--ss-ubc826ab34b.xn--xmc; ; xn--ss-ubc826a.xn--xmc; [V5] # σssܱ.்
+xn--ss-ubc826a.xn--xmc; σssܱ.்; [V5]; xn--ss-ubc826a.xn--xmc; ; ; # σssܱ.்
+xn--ss-ubc826ab34b.xn--xmc; ‍σssܱ.்; [C2, V5]; xn--ss-ubc826ab34b.xn--xmc; ; ; # σssܱ.்
+‍Σßܱ.்; ‍σßܱ.்; [C2, V5]; xn--zca39lk1di19a.xn--xmc; ; xn--ss-ubc826a.xn--xmc; [V5] # σßܱ.்
+‍σßܱ.்; ; [C2, V5]; xn--zca39lk1di19a.xn--xmc; ; xn--ss-ubc826a.xn--xmc; [V5] # σßܱ.்
+xn--zca39lk1di19a.xn--xmc; ‍σßܱ.்; [C2, V5]; xn--zca39lk1di19a.xn--xmc; ; ; # σßܱ.்
+xn--zca19ln1di19a.xn--xmc; ‍ςßܱ.்; [C2, V5]; xn--zca19ln1di19a.xn--xmc; ; ; # ςßܱ.்
+‍ΣSSܱ.்; ‍σssܱ.்; [C2, V5]; xn--ss-ubc826ab34b.xn--xmc; ; xn--ss-ubc826a.xn--xmc; [V5] # σssܱ.்
+‍σssܱ.்; ‍σssܱ.்; [C2, V5]; xn--ss-ubc826ab34b.xn--xmc; ; xn--ss-ubc826a.xn--xmc; [V5] # σssܱ.்
+‍Σssܱ.்; ‍σssܱ.்; [C2, V5]; xn--ss-ubc826ab34b.xn--xmc; ; xn--ss-ubc826a.xn--xmc; [V5] # σssܱ.்
+‍Σßܱ.்; ‍σßܱ.்; [C2, V5]; xn--zca39lk1di19a.xn--xmc; ; xn--ss-ubc826a.xn--xmc; [V5] # σßܱ.்
+‍σßܱ.்; ‍σßܱ.்; [C2, V5]; xn--zca39lk1di19a.xn--xmc; ; xn--ss-ubc826a.xn--xmc; [V5] # σßܱ.்
+≠.‍; ≠.‍; [C2, P1, V6]; xn--1ch.xn--1ug; ; xn--1ch.; [P1, V6] # ≠.
+≠.‍; ≠.‍; [C2, P1, V6]; xn--1ch.xn--1ug; ; xn--1ch.; [P1, V6] # ≠.
+≠.‍; ; [C2, P1, V6]; xn--1ch.xn--1ug; ; xn--1ch.; [P1, V6] # ≠.
+≠.‍; ≠.‍; [C2, P1, V6]; xn--1ch.xn--1ug; ; xn--1ch.; [P1, V6] # ≠.
+xn--1ch.; ≠.; [V6]; xn--1ch.; ; ; # ≠.
+xn--1ch.xn--1ug; ≠.‍; [C2, V6]; xn--1ch.xn--1ug; ; ; # ≠.
+ﰁ。ಁᠼ▗򒁋; ئح.ಁᠼ▗򒁋; [B1, P1, V5, V6]; xn--lgbo.xn--2rc021dcxkrx55t; ; ; # ئح.ಁᠼ▗
+ئح。ಁᠼ▗򒁋; ئح.ಁᠼ▗򒁋; [B1, P1, V5, V6]; xn--lgbo.xn--2rc021dcxkrx55t; ; ; # ئح.ಁᠼ▗
+ئح。ಁᠼ▗򒁋; ئح.ಁᠼ▗򒁋; [B1, P1, V5, V6]; xn--lgbo.xn--2rc021dcxkrx55t; ; ; # ئح.ಁᠼ▗
+xn--lgbo.xn--2rc021dcxkrx55t; ئح.ಁᠼ▗򒁋; [B1, V5, V6]; xn--lgbo.xn--2rc021dcxkrx55t; ; ; # ئح.ಁᠼ▗
+󧋵্ς.ς𐨿; 󧋵্ς.ς𐨿; [P1, V6]; xn--3xa702av8297a.xn--3xa8055k; ; xn--4xa502av8297a.xn--4xa6055k; # ্ς.ς𐨿
+󧋵্ς.ς𐨿; ; [P1, V6]; xn--3xa702av8297a.xn--3xa8055k; ; xn--4xa502av8297a.xn--4xa6055k; # ্ς.ς𐨿
+󧋵্Σ.Σ𐨿; 󧋵্σ.σ𐨿; [P1, V6]; xn--4xa502av8297a.xn--4xa6055k; ; ; # ্σ.σ𐨿
+󧋵্σ.ς𐨿; ; [P1, V6]; xn--4xa502av8297a.xn--3xa8055k; ; xn--4xa502av8297a.xn--4xa6055k; # ্σ.ς𐨿
+󧋵্σ.σ𐨿; ; [P1, V6]; xn--4xa502av8297a.xn--4xa6055k; ; ; # ্σ.σ𐨿
+󧋵্Σ.σ𐨿; 󧋵্σ.σ𐨿; [P1, V6]; xn--4xa502av8297a.xn--4xa6055k; ; ; # ্σ.σ𐨿
+xn--4xa502av8297a.xn--4xa6055k; 󧋵্σ.σ𐨿; [V6]; xn--4xa502av8297a.xn--4xa6055k; ; ; # ্σ.σ𐨿
+󧋵্Σ.ς𐨿; 󧋵্σ.ς𐨿; [P1, V6]; xn--4xa502av8297a.xn--3xa8055k; ; xn--4xa502av8297a.xn--4xa6055k; # ্σ.ς𐨿
+xn--4xa502av8297a.xn--3xa8055k; 󧋵্σ.ς𐨿; [V6]; xn--4xa502av8297a.xn--3xa8055k; ; ; # ্σ.ς𐨿
+xn--3xa702av8297a.xn--3xa8055k; 󧋵্ς.ς𐨿; [V6]; xn--3xa702av8297a.xn--3xa8055k; ; ; # ্ς.ς𐨿
+󧋵্Σ.Σ𐨿; 󧋵্σ.σ𐨿; [P1, V6]; xn--4xa502av8297a.xn--4xa6055k; ; ; # ্σ.σ𐨿
+󧋵্σ.ς𐨿; 󧋵্σ.ς𐨿; [P1, V6]; xn--4xa502av8297a.xn--3xa8055k; ; xn--4xa502av8297a.xn--4xa6055k; # ্σ.ς𐨿
+󧋵্σ.σ𐨿; 󧋵্σ.σ𐨿; [P1, V6]; xn--4xa502av8297a.xn--4xa6055k; ; ; # ্σ.σ𐨿
+󧋵্Σ.σ𐨿; 󧋵্σ.σ𐨿; [P1, V6]; xn--4xa502av8297a.xn--4xa6055k; ; ; # ্σ.σ𐨿
+󧋵্Σ.ς𐨿; 󧋵্σ.ς𐨿; [P1, V6]; xn--4xa502av8297a.xn--3xa8055k; ; xn--4xa502av8297a.xn--4xa6055k; # ্σ.ς𐨿
+𐫓ߘ牅ࣸ。𞦤ᨗ򱍰Ⴙ; 𐫓ߘ牅ࣸ.𞦤ᨗ򱍰Ⴙ; [B2, B3, P1, V6]; xn--zsb09cu46vjs6f.xn--xnd909bv540bm5k9d; ; ; # 𐫓ߘ牅ࣸ.ᨗႹ
+𐫓ߘ牅ࣸ。𞦤ᨗ򱍰Ⴙ; 𐫓ߘ牅ࣸ.𞦤ᨗ򱍰Ⴙ; [B2, B3, P1, V6]; xn--zsb09cu46vjs6f.xn--xnd909bv540bm5k9d; ; ; # 𐫓ߘ牅ࣸ.ᨗႹ
+𐫓ߘ牅ࣸ。𞦤ᨗ򱍰ⴙ; 𐫓ߘ牅ࣸ.𞦤ᨗ򱍰ⴙ; [B2, B3, P1, V6]; xn--zsb09cu46vjs6f.xn--gmf469fr883am5r1e; ; ; # 𐫓ߘ牅ࣸ.ᨗⴙ
+xn--zsb09cu46vjs6f.xn--gmf469fr883am5r1e; 𐫓ߘ牅ࣸ.𞦤ᨗ򱍰ⴙ; [B2, B3, V6]; xn--zsb09cu46vjs6f.xn--gmf469fr883am5r1e; ; ; # 𐫓ߘ牅ࣸ.ᨗⴙ
+xn--zsb09cu46vjs6f.xn--xnd909bv540bm5k9d; 𐫓ߘ牅ࣸ.𞦤ᨗ򱍰Ⴙ; [B2, B3, V6]; xn--zsb09cu46vjs6f.xn--xnd909bv540bm5k9d; ; ; # 𐫓ߘ牅ࣸ.ᨗႹ
+𐫓ߘ牅ࣸ。𞦤ᨗ򱍰ⴙ; 𐫓ߘ牅ࣸ.𞦤ᨗ򱍰ⴙ; [B2, B3, P1, V6]; xn--zsb09cu46vjs6f.xn--gmf469fr883am5r1e; ; ; # 𐫓ߘ牅ࣸ.ᨗⴙ
+񣤒。륧; 񣤒.륧; [P1, V6]; xn--s264a.xn--pw2b; ; ; # .륧
+񣤒。륧; 񣤒.륧; [P1, V6]; xn--s264a.xn--pw2b; ; ; # .륧
+񣤒。륧; 񣤒.륧; [P1, V6]; xn--s264a.xn--pw2b; ; ; # .륧
+񣤒。륧; 񣤒.륧; [P1, V6]; xn--s264a.xn--pw2b; ; ; # .륧
+xn--s264a.xn--pw2b; 񣤒.륧; [V6]; xn--s264a.xn--pw2b; ; ; # .륧
+𐹷‍。󉵢; 𐹷‍.󉵢; [B1, C2, P1, V6]; xn--1ugx205g.xn--8088d; ; xn--vo0d.xn--8088d; [B1, P1, V6] # 𐹷.
+xn--vo0d.xn--8088d; 𐹷.󉵢; [B1, V6]; xn--vo0d.xn--8088d; ; ; # 𐹷.
+xn--1ugx205g.xn--8088d; 𐹷‍.󉵢; [B1, C2, V6]; xn--1ugx205g.xn--8088d; ; ; # 𐹷.
+Ⴘۂ𑲭。-; Ⴘۂ𑲭.-; [B1, B5, B6, P1, V3, V6]; xn--1kb312c139t.-; ; ; # Ⴘۂ𑲭.-
+Ⴘۂ𑲭。-; Ⴘۂ𑲭.-; [B1, B5, B6, P1, V3, V6]; xn--1kb312c139t.-; ; ; # Ⴘۂ𑲭.-
+Ⴘۂ𑲭。-; Ⴘۂ𑲭.-; [B1, B5, B6, P1, V3, V6]; xn--1kb312c139t.-; ; ; # Ⴘۂ𑲭.-
+Ⴘۂ𑲭。-; Ⴘۂ𑲭.-; [B1, B5, B6, P1, V3, V6]; xn--1kb312c139t.-; ; ; # Ⴘۂ𑲭.-
+ⴘۂ𑲭。-; ⴘۂ𑲭.-; [B1, B5, B6, V3]; xn--1kb147qfk3n.-; ; ; # ⴘۂ𑲭.-
+ⴘۂ𑲭。-; ⴘۂ𑲭.-; [B1, B5, B6, V3]; xn--1kb147qfk3n.-; ; ; # ⴘۂ𑲭.-
+xn--1kb147qfk3n.-; ⴘۂ𑲭.-; [B1, B5, B6, V3]; xn--1kb147qfk3n.-; ; ; # ⴘۂ𑲭.-
+xn--1kb312c139t.-; Ⴘۂ𑲭.-; [B1, B5, B6, V3, V6]; xn--1kb312c139t.-; ; ; # Ⴘۂ𑲭.-
+ⴘۂ𑲭。-; ⴘۂ𑲭.-; [B1, B5, B6, V3]; xn--1kb147qfk3n.-; ; ; # ⴘۂ𑲭.-
+ⴘۂ𑲭。-; ⴘۂ𑲭.-; [B1, B5, B6, V3]; xn--1kb147qfk3n.-; ; ; # ⴘۂ𑲭.-
+꠆ٻ₆ᡐ。🛇ﳝ; ꠆ٻ6ᡐ.🛇يم; [B1, V5]; xn--6-rrc018krt9k.xn--hhbj61429a; ; ; # ꠆ٻ6ᡐ.🛇يم
+꠆ٻ6ᡐ。🛇يم; ꠆ٻ6ᡐ.🛇يم; [B1, V5]; xn--6-rrc018krt9k.xn--hhbj61429a; ; ; # ꠆ٻ6ᡐ.🛇يم
+xn--6-rrc018krt9k.xn--hhbj61429a; ꠆ٻ6ᡐ.🛇يم; [B1, V5]; xn--6-rrc018krt9k.xn--hhbj61429a; ; ; # ꠆ٻ6ᡐ.🛇يم
+򸍂.㇄ᡟ𐫂آ; ; [B1, P1, V6]; xn--p292d.xn--hgb154ghrsvm2r; ; ; # .㇄ᡟ𐫂آ
+򸍂.㇄ᡟ𐫂آ; 򸍂.㇄ᡟ𐫂آ; [B1, P1, V6]; xn--p292d.xn--hgb154ghrsvm2r; ; ; # .㇄ᡟ𐫂آ
+xn--p292d.xn--hgb154ghrsvm2r; 򸍂.㇄ᡟ𐫂آ; [B1, V6]; xn--p292d.xn--hgb154ghrsvm2r; ; ; # .㇄ᡟ𐫂آ
+ߟ򵚌。-ߩ; ߟ򵚌.-ߩ; [B1, B2, B3, P1, V3, V6]; xn--6sb88139l.xn----pdd; ; ; # ߟ.-ߩ
+xn--6sb88139l.xn----pdd; ߟ򵚌.-ߩ; [B1, B2, B3, V3, V6]; xn--6sb88139l.xn----pdd; ; ; # ߟ.-ߩ
+ςك⾑.‌ᢟ‌⒈; ςك襾.‌ᢟ‌⒈; [B1, B5, C1, P1, V6]; xn--3xa69jux8r.xn--pbf519aba607b; ; xn--4xa49jux8r.xn--pbf212d; [B5, P1, V6] # ςك襾.ᢟ⒈
+ςك襾.‌ᢟ‌1.; ; [B1, B5, C1]; xn--3xa69jux8r.xn--1-4ck691bba.; ; xn--4xa49jux8r.xn--1-4ck.; [B5] # ςك襾.ᢟ1.
+Σك襾.‌ᢟ‌1.; σك襾.‌ᢟ‌1.; [B1, B5, C1]; xn--4xa49jux8r.xn--1-4ck691bba.; ; xn--4xa49jux8r.xn--1-4ck.; [B5] # σك襾.ᢟ1.
+σك襾.‌ᢟ‌1.; ; [B1, B5, C1]; xn--4xa49jux8r.xn--1-4ck691bba.; ; xn--4xa49jux8r.xn--1-4ck.; [B5] # σك襾.ᢟ1.
+xn--4xa49jux8r.xn--1-4ck.; σك襾.ᢟ1.; [B5]; xn--4xa49jux8r.xn--1-4ck.; ; ; # σك襾.ᢟ1.
+xn--4xa49jux8r.xn--1-4ck691bba.; σك襾.‌ᢟ‌1.; [B1, B5, C1]; xn--4xa49jux8r.xn--1-4ck691bba.; ; ; # σك襾.ᢟ1.
+xn--3xa69jux8r.xn--1-4ck691bba.; ςك襾.‌ᢟ‌1.; [B1, B5, C1]; xn--3xa69jux8r.xn--1-4ck691bba.; ; ; # ςك襾.ᢟ1.
+Σك⾑.‌ᢟ‌⒈; σك襾.‌ᢟ‌⒈; [B1, B5, C1, P1, V6]; xn--4xa49jux8r.xn--pbf519aba607b; ; xn--4xa49jux8r.xn--pbf212d; [B5, P1, V6] # σك襾.ᢟ⒈
+σك⾑.‌ᢟ‌⒈; σك襾.‌ᢟ‌⒈; [B1, B5, C1, P1, V6]; xn--4xa49jux8r.xn--pbf519aba607b; ; xn--4xa49jux8r.xn--pbf212d; [B5, P1, V6] # σك襾.ᢟ⒈
+xn--4xa49jux8r.xn--pbf212d; σك襾.ᢟ⒈; [B5, V6]; xn--4xa49jux8r.xn--pbf212d; ; ; # σك襾.ᢟ⒈
+xn--4xa49jux8r.xn--pbf519aba607b; σك襾.‌ᢟ‌⒈; [B1, B5, C1, V6]; xn--4xa49jux8r.xn--pbf519aba607b; ; ; # σك襾.ᢟ⒈
+xn--3xa69jux8r.xn--pbf519aba607b; ςك襾.‌ᢟ‌⒈; [B1, B5, C1, V6]; xn--3xa69jux8r.xn--pbf519aba607b; ; ; # ςك襾.ᢟ⒈
+ᡆ𑓝.𞵆; ᡆ𑓝.𞵆; [P1, V6]; xn--57e0440k.xn--k86h; ; ; # ᡆ.
+ᡆ𑓝.𞵆; ; [P1, V6]; xn--57e0440k.xn--k86h; ; ; # ᡆ.
+xn--57e0440k.xn--k86h; ᡆ𑓝.𞵆; [V6]; xn--57e0440k.xn--k86h; ; ; # ᡆ.
+੍𦍓ᷮ。‌ࢽ񝹲; ੍𦍓ᷮ.‌ࢽ񝹲; [B1, C1, P1, V5, V6]; xn--ybc461hph93b.xn--jzb740j1y45h; ; xn--ybc461hph93b.xn--jzb29857e; [B1, B2, B3, P1, V5, V6] # ੍𦍓ᷮ.ࢽ
+੍𦍓ᷮ。‌ࢽ񝹲; ੍𦍓ᷮ.‌ࢽ񝹲; [B1, C1, P1, V5, V6]; xn--ybc461hph93b.xn--jzb740j1y45h; ; xn--ybc461hph93b.xn--jzb29857e; [B1, B2, B3, P1, V5, V6] # ੍𦍓ᷮ.ࢽ
+xn--ybc461hph93b.xn--jzb29857e; ੍𦍓ᷮ.ࢽ񝹲; [B1, B2, B3, V5, V6]; xn--ybc461hph93b.xn--jzb29857e; ; ; # ੍𦍓ᷮ.ࢽ
+xn--ybc461hph93b.xn--jzb740j1y45h; ੍𦍓ᷮ.‌ࢽ񝹲; [B1, C1, V5, V6]; xn--ybc461hph93b.xn--jzb740j1y45h; ; ; # ੍𦍓ᷮ.ࢽ
+خ݈񅪪-.‌먿; خ݈񅪪-.‌먿; [B1, B2, B3, C1, P1, V3, V6]; xn----dnc06f42153a.xn--0ug1581d; ; xn----dnc06f42153a.xn--v22b; [B2, B3, P1, V3, V6] # خ݈-.먿
+خ݈񅪪-.‌먿; خ݈񅪪-.‌먿; [B1, B2, B3, C1, P1, V3, V6]; xn----dnc06f42153a.xn--0ug1581d; ; xn----dnc06f42153a.xn--v22b; [B2, B3, P1, V3, V6] # خ݈-.먿
+خ݈񅪪-.‌먿; ; [B1, B2, B3, C1, P1, V3, V6]; xn----dnc06f42153a.xn--0ug1581d; ; xn----dnc06f42153a.xn--v22b; [B2, B3, P1, V3, V6] # خ݈-.먿
+خ݈񅪪-.‌먿; خ݈񅪪-.‌먿; [B1, B2, B3, C1, P1, V3, V6]; xn----dnc06f42153a.xn--0ug1581d; ; xn----dnc06f42153a.xn--v22b; [B2, B3, P1, V3, V6] # خ݈-.먿
+xn----dnc06f42153a.xn--v22b; خ݈񅪪-.먿; [B2, B3, V3, V6]; xn----dnc06f42153a.xn--v22b; ; ; # خ݈-.먿
+xn----dnc06f42153a.xn--0ug1581d; خ݈񅪪-.‌먿; [B1, B2, B3, C1, V3, V6]; xn----dnc06f42153a.xn--0ug1581d; ; ; # خ݈-.먿
+􋿦。ᠽ; 􋿦.ᠽ; [P1, V6]; xn--j890g.xn--w7e; ; ; # .ᠽ
+􋿦。ᠽ; 􋿦.ᠽ; [P1, V6]; xn--j890g.xn--w7e; ; ; # .ᠽ
+xn--j890g.xn--w7e; 􋿦.ᠽ; [V6]; xn--j890g.xn--w7e; ; ; # .ᠽ
+嬃𝍌.‍ୄ; 嬃𝍌.‍ୄ; [C2]; xn--b6s0078f.xn--0ic557h; ; xn--b6s0078f.xn--0ic; [V5] # 嬃𝍌.ୄ
+嬃𝍌.‍ୄ; ; [C2]; xn--b6s0078f.xn--0ic557h; ; xn--b6s0078f.xn--0ic; [V5] # 嬃𝍌.ୄ
+xn--b6s0078f.xn--0ic; 嬃𝍌.ୄ; [V5]; xn--b6s0078f.xn--0ic; ; ; # 嬃𝍌.ୄ
+xn--b6s0078f.xn--0ic557h; 嬃𝍌.‍ୄ; [C2]; xn--b6s0078f.xn--0ic557h; ; ; # 嬃𝍌.ୄ
+؂𝌪≯.𚋲򵁨; ؂𝌪≯.𚋲򵁨; [B1, P1, V6]; xn--kfb866llx01a.xn--wp1gm3570b; ; ; # 𝌪≯.
+؂𝌪≯.𚋲򵁨; ؂𝌪≯.𚋲򵁨; [B1, P1, V6]; xn--kfb866llx01a.xn--wp1gm3570b; ; ; # 𝌪≯.
+؂𝌪≯.𚋲򵁨; ; [B1, P1, V6]; xn--kfb866llx01a.xn--wp1gm3570b; ; ; # 𝌪≯.
+؂𝌪≯.𚋲򵁨; ؂𝌪≯.𚋲򵁨; [B1, P1, V6]; xn--kfb866llx01a.xn--wp1gm3570b; ; ; # 𝌪≯.
+xn--kfb866llx01a.xn--wp1gm3570b; ؂𝌪≯.𚋲򵁨; [B1, V6]; xn--kfb866llx01a.xn--wp1gm3570b; ; ; # 𝌪≯.
+򫾥ࢷ៌꧀.𞼠; ; [B5, P1, V6]; xn--dzb638ewm4i1iy1h.xn--3m7h; ; ; # ࢷ៌꧀.
+xn--dzb638ewm4i1iy1h.xn--3m7h; 򫾥ࢷ៌꧀.𞼠; [B5, V6]; xn--dzb638ewm4i1iy1h.xn--3m7h; ; ; # ࢷ៌꧀.
+‌.񟛤; ; [C1, P1, V6]; xn--0ug.xn--q823a; ; .xn--q823a; [P1, V6, A4_2] # .
+.xn--q823a; .񟛤; [V6, X4_2]; .xn--q823a; [V6, A4_2]; ; # .
+xn--0ug.xn--q823a; ‌.񟛤; [C1, V6]; xn--0ug.xn--q823a; ; ; # .
+򺛕Ⴃ䠅.𐸑; 򺛕Ⴃ䠅.𐸑; [P1, V6]; xn--bnd074zr557n.xn--yl0d; ; ; # Ⴃ䠅.
+򺛕Ⴃ䠅.𐸑; ; [P1, V6]; xn--bnd074zr557n.xn--yl0d; ; ; # Ⴃ䠅.
+򺛕ⴃ䠅.𐸑; ; [P1, V6]; xn--ukju77frl47r.xn--yl0d; ; ; # ⴃ䠅.
+xn--ukju77frl47r.xn--yl0d; 򺛕ⴃ䠅.𐸑; [V6]; xn--ukju77frl47r.xn--yl0d; ; ; # ⴃ䠅.
+xn--bnd074zr557n.xn--yl0d; 򺛕Ⴃ䠅.𐸑; [V6]; xn--bnd074zr557n.xn--yl0d; ; ; # Ⴃ䠅.
+򺛕ⴃ䠅.𐸑; 򺛕ⴃ䠅.𐸑; [P1, V6]; xn--ukju77frl47r.xn--yl0d; ; ; # ⴃ䠅.
+ᯱ𐹳𐹵𞤚。𝟨Ⴅ; ᯱ𐹳𐹵𞤼.6Ⴅ; [B1, P1, V5, V6]; xn--zzfy954hga2415t.xn--6-h0g; ; ; # ᯱ𐹳𐹵𞤼.6Ⴅ
+ᯱ𐹳𐹵𞤚。6Ⴅ; ᯱ𐹳𐹵𞤼.6Ⴅ; [B1, P1, V5, V6]; xn--zzfy954hga2415t.xn--6-h0g; ; ; # ᯱ𐹳𐹵𞤼.6Ⴅ
+ᯱ𐹳𐹵𞤼。6ⴅ; ᯱ𐹳𐹵𞤼.6ⴅ; [B1, V5]; xn--zzfy954hga2415t.xn--6-kvs; ; ; # ᯱ𐹳𐹵𞤼.6ⴅ
+ᯱ𐹳𐹵𞤚。6ⴅ; ᯱ𐹳𐹵𞤼.6ⴅ; [B1, V5]; xn--zzfy954hga2415t.xn--6-kvs; ; ; # ᯱ𐹳𐹵𞤼.6ⴅ
+xn--zzfy954hga2415t.xn--6-kvs; ᯱ𐹳𐹵𞤼.6ⴅ; [B1, V5]; xn--zzfy954hga2415t.xn--6-kvs; ; ; # ᯱ𐹳𐹵𞤼.6ⴅ
+xn--zzfy954hga2415t.xn--6-h0g; ᯱ𐹳𐹵𞤼.6Ⴅ; [B1, V5, V6]; xn--zzfy954hga2415t.xn--6-h0g; ; ; # ᯱ𐹳𐹵𞤼.6Ⴅ
+ᯱ𐹳𐹵𞤼。𝟨ⴅ; ᯱ𐹳𐹵𞤼.6ⴅ; [B1, V5]; xn--zzfy954hga2415t.xn--6-kvs; ; ; # ᯱ𐹳𐹵𞤼.6ⴅ
+ᯱ𐹳𐹵𞤚。𝟨ⴅ; ᯱ𐹳𐹵𞤼.6ⴅ; [B1, V5]; xn--zzfy954hga2415t.xn--6-kvs; ; ; # ᯱ𐹳𐹵𞤼.6ⴅ
+-。︒; -.︒; [P1, V3, V6]; -.xn--y86c; ; ; # -.︒
+-。。; -..; [V3, X4_2]; ; [V3, A4_2]; ; # -..
+-..; ; [V3, X4_2]; ; [V3, A4_2]; ; # -..
+-.xn--y86c; -.︒; [V3, V6]; -.xn--y86c; ; ; # -.︒
+ߛჀ。-⁵--; ߛჀ.-5--; [B1, B2, B3, P1, V2, V3, V6]; xn--2sb866b.-5--; ; ; # ߛჀ.-5--
+ߛჀ。-5--; ߛჀ.-5--; [B1, B2, B3, P1, V2, V3, V6]; xn--2sb866b.-5--; ; ; # ߛჀ.-5--
+ߛⴠ。-5--; ߛⴠ.-5--; [B1, B2, B3, V2, V3]; xn--2sb691q.-5--; ; ; # ߛⴠ.-5--
+xn--2sb691q.-5--; ߛⴠ.-5--; [B1, B2, B3, V2, V3]; xn--2sb691q.-5--; ; ; # ߛⴠ.-5--
+xn--2sb866b.-5--; ߛჀ.-5--; [B1, B2, B3, V2, V3, V6]; xn--2sb866b.-5--; ; ; # ߛჀ.-5--
+ߛⴠ。-⁵--; ߛⴠ.-5--; [B1, B2, B3, V2, V3]; xn--2sb691q.-5--; ; ; # ߛⴠ.-5--
+≯?󠑕。𐹷𐹻≯𐷒; ≯?󠑕.𐹷𐹻≯𐷒; [B1, P1, V6]; xn--?-ogo25661n.xn--hdh8283gdoaqa; ; ; # ≯?.𐹷𐹻≯
+≯?󠑕。𐹷𐹻≯𐷒; ≯?󠑕.𐹷𐹻≯𐷒; [B1, P1, V6]; xn--?-ogo25661n.xn--hdh8283gdoaqa; ; ; # ≯?.𐹷𐹻≯
+≯?󠑕。𐹷𐹻≯𐷒; ≯?󠑕.𐹷𐹻≯𐷒; [B1, P1, V6]; xn--?-ogo25661n.xn--hdh8283gdoaqa; ; ; # ≯?.𐹷𐹻≯
+≯?󠑕。𐹷𐹻≯𐷒; ≯?󠑕.𐹷𐹻≯𐷒; [B1, P1, V6]; xn--?-ogo25661n.xn--hdh8283gdoaqa; ; ; # ≯?.𐹷𐹻≯
+xn--?-ogo25661n.xn--hdh8283gdoaqa; ≯?󠑕.𐹷𐹻≯𐷒; [B1, P1, V6]; xn--?-ogo25661n.xn--hdh8283gdoaqa; ; ; # ≯?.𐹷𐹻≯
+≯?󠑕.xn--hdh8283gdoaqa; ≯?󠑕.𐹷𐹻≯𐷒; [B1, P1, V6]; xn--?-ogo25661n.xn--hdh8283gdoaqa; ; ; # ≯?.𐹷𐹻≯
+≯?󠑕.xn--hdh8283gdoaqa; ≯?󠑕.𐹷𐹻≯𐷒; [B1, P1, V6]; xn--?-ogo25661n.xn--hdh8283gdoaqa; ; ; # ≯?.𐹷𐹻≯
+≯?󠑕.XN--HDH8283GDOAQA; ≯?󠑕.𐹷𐹻≯𐷒; [B1, P1, V6]; xn--?-ogo25661n.xn--hdh8283gdoaqa; ; ; # ≯?.𐹷𐹻≯
+≯?󠑕.XN--HDH8283GDOAQA; ≯?󠑕.𐹷𐹻≯𐷒; [B1, P1, V6]; xn--?-ogo25661n.xn--hdh8283gdoaqa; ; ; # ≯?.𐹷𐹻≯
+≯?󠑕.Xn--Hdh8283gdoaqa; ≯?󠑕.𐹷𐹻≯𐷒; [B1, P1, V6]; xn--?-ogo25661n.xn--hdh8283gdoaqa; ; ; # ≯?.𐹷𐹻≯
+≯?󠑕.Xn--Hdh8283gdoaqa; ≯?󠑕.𐹷𐹻≯𐷒; [B1, P1, V6]; xn--?-ogo25661n.xn--hdh8283gdoaqa; ; ; # ≯?.𐹷𐹻≯
+㍔ࣦݼ‍。͆򁳊𝅶؄; ルーブルࣦݼ‍.͆򁳊𝅶؄; [B1, B5, B6, C2, P1, V5, V6]; xn--dqb73ec22c9kp8cb1j.xn--kua81ls548d3608b; ; xn--dqb73el09fncab4h.xn--kua81ls548d3608b; [B1, B5, B6, P1, V5, V6] # ルーブルࣦݼ.͆
+ルーブルࣦݼ‍。͆򁳊𝅶؄; ルーブルࣦݼ‍.͆򁳊𝅶؄; [B1, B5, B6, C2, P1, V5, V6]; xn--dqb73ec22c9kp8cb1j.xn--kua81ls548d3608b; ; xn--dqb73el09fncab4h.xn--kua81ls548d3608b; [B1, B5, B6, P1, V5, V6] # ルーブルࣦݼ.͆
+ルーブルࣦݼ‍。͆򁳊𝅶؄; ルーブルࣦݼ‍.͆򁳊𝅶؄; [B1, B5, B6, C2, P1, V5, V6]; xn--dqb73ec22c9kp8cb1j.xn--kua81ls548d3608b; ; xn--dqb73el09fncab4h.xn--kua81ls548d3608b; [B1, B5, B6, P1, V5, V6] # ルーブルࣦݼ.͆
+xn--dqb73el09fncab4h.xn--kua81ls548d3608b; ルーブルࣦݼ.͆򁳊𝅶؄; [B1, B5, B6, V5, V6]; xn--dqb73el09fncab4h.xn--kua81ls548d3608b; ; ; # ルーブルࣦݼ.͆
+xn--dqb73ec22c9kp8cb1j.xn--kua81ls548d3608b; ルーブルࣦݼ‍.͆򁳊𝅶؄; [B1, B5, B6, C2, V5, V6]; xn--dqb73ec22c9kp8cb1j.xn--kua81ls548d3608b; ; ; # ルーブルࣦݼ.͆
+‍.F; ‍.f; [C2]; xn--1ug.f; ; .f; [A4_2] # .f
+‍.f; ; [C2]; xn--1ug.f; ; .f; [A4_2] # .f
+.f; ; [X4_2]; ; [A4_2]; ; # .f
+xn--1ug.f; ‍.f; [C2]; xn--1ug.f; ; ; # .f
+f; ; ; ; ; ; # f
+‍㨲。ß; ‍㨲.ß; [C2]; xn--1ug914h.xn--zca; ; xn--9bm.ss; [] # 㨲.ß
+‍㨲。ß; ‍㨲.ß; [C2]; xn--1ug914h.xn--zca; ; xn--9bm.ss; [] # 㨲.ß
+‍㨲。SS; ‍㨲.ss; [C2]; xn--1ug914h.ss; ; xn--9bm.ss; [] # 㨲.ss
+‍㨲。ss; ‍㨲.ss; [C2]; xn--1ug914h.ss; ; xn--9bm.ss; [] # 㨲.ss
+‍㨲。Ss; ‍㨲.ss; [C2]; xn--1ug914h.ss; ; xn--9bm.ss; [] # 㨲.ss
+xn--9bm.ss; 㨲.ss; ; xn--9bm.ss; ; ; # 㨲.ss
+㨲.ss; ; ; xn--9bm.ss; ; ; # 㨲.ss
+㨲.SS; 㨲.ss; ; xn--9bm.ss; ; ; # 㨲.ss
+㨲.Ss; 㨲.ss; ; xn--9bm.ss; ; ; # 㨲.ss
+xn--1ug914h.ss; ‍㨲.ss; [C2]; xn--1ug914h.ss; ; ; # 㨲.ss
+xn--1ug914h.xn--zca; ‍㨲.ß; [C2]; xn--1ug914h.xn--zca; ; ; # 㨲.ß
+‍㨲。SS; ‍㨲.ss; [C2]; xn--1ug914h.ss; ; xn--9bm.ss; [] # 㨲.ss
+‍㨲。ss; ‍㨲.ss; [C2]; xn--1ug914h.ss; ; xn--9bm.ss; [] # 㨲.ss
+‍㨲。Ss; ‍㨲.ss; [C2]; xn--1ug914h.ss; ; xn--9bm.ss; [] # 㨲.ss
+؅پ。ࢨ; ؅پ.ࢨ; [B1, P1, V6]; xn--nfb6v.xn--xyb; ; ; # پ.ࢨ
+؅پ。ࢨ; ؅پ.ࢨ; [B1, P1, V6]; xn--nfb6v.xn--xyb; ; ; # پ.ࢨ
+xn--nfb6v.xn--xyb; ؅پ.ࢨ; [B1, V6]; xn--nfb6v.xn--xyb; ; ; # پ.ࢨ
+⾑ݓ𞤁。𐹵ڂ; 襾ݓ𞤣.𐹵ڂ; [B1, B5, B6]; xn--6ob9577deqwl.xn--7ib5526k; ; ; # 襾ݓ𞤣.𐹵ڂ
+襾ݓ𞤁。𐹵ڂ; 襾ݓ𞤣.𐹵ڂ; [B1, B5, B6]; xn--6ob9577deqwl.xn--7ib5526k; ; ; # 襾ݓ𞤣.𐹵ڂ
+襾ݓ𞤣。𐹵ڂ; 襾ݓ𞤣.𐹵ڂ; [B1, B5, B6]; xn--6ob9577deqwl.xn--7ib5526k; ; ; # 襾ݓ𞤣.𐹵ڂ
+xn--6ob9577deqwl.xn--7ib5526k; 襾ݓ𞤣.𐹵ڂ; [B1, B5, B6]; xn--6ob9577deqwl.xn--7ib5526k; ; ; # 襾ݓ𞤣.𐹵ڂ
+⾑ݓ𞤣。𐹵ڂ; 襾ݓ𞤣.𐹵ڂ; [B1, B5, B6]; xn--6ob9577deqwl.xn--7ib5526k; ; ; # 襾ݓ𞤣.𐹵ڂ
+񦴻ς-⃫。ݔ-ꡛ; 񦴻ς-⃫.ݔ-ꡛ; [B2, B3, B6, P1, V6]; xn----xmb015tuo34l.xn----53c4874j; ; xn----zmb705tuo34l.xn----53c4874j; # ς-⃫.ݔ-ꡛ
+񦴻ς-⃫。ݔ-ꡛ; 񦴻ς-⃫.ݔ-ꡛ; [B2, B3, B6, P1, V6]; xn----xmb015tuo34l.xn----53c4874j; ; xn----zmb705tuo34l.xn----53c4874j; # ς-⃫.ݔ-ꡛ
+񦴻Σ-⃫。ݔ-ꡛ; 񦴻σ-⃫.ݔ-ꡛ; [B2, B3, B6, P1, V6]; xn----zmb705tuo34l.xn----53c4874j; ; ; # σ-⃫.ݔ-ꡛ
+񦴻σ-⃫。ݔ-ꡛ; 񦴻σ-⃫.ݔ-ꡛ; [B2, B3, B6, P1, V6]; xn----zmb705tuo34l.xn----53c4874j; ; ; # σ-⃫.ݔ-ꡛ
+xn----zmb705tuo34l.xn----53c4874j; 񦴻σ-⃫.ݔ-ꡛ; [B2, B3, B6, V6]; xn----zmb705tuo34l.xn----53c4874j; ; ; # σ-⃫.ݔ-ꡛ
+xn----xmb015tuo34l.xn----53c4874j; 񦴻ς-⃫.ݔ-ꡛ; [B2, B3, B6, V6]; xn----xmb015tuo34l.xn----53c4874j; ; ; # ς-⃫.ݔ-ꡛ
+񦴻Σ-⃫。ݔ-ꡛ; 񦴻σ-⃫.ݔ-ꡛ; [B2, B3, B6, P1, V6]; xn----zmb705tuo34l.xn----53c4874j; ; ; # σ-⃫.ݔ-ꡛ
+񦴻σ-⃫。ݔ-ꡛ; 񦴻σ-⃫.ݔ-ꡛ; [B2, B3, B6, P1, V6]; xn----zmb705tuo34l.xn----53c4874j; ; ; # σ-⃫.ݔ-ꡛ
+‍.􀸨; ‍.􀸨; [C2, P1, V6]; xn--1ug.xn--h327f; ; .xn--h327f; [P1, V6, A4_2] # .
+‍.􀸨; ; [C2, P1, V6]; xn--1ug.xn--h327f; ; .xn--h327f; [P1, V6, A4_2] # .
+.xn--h327f; .􀸨; [V6, X4_2]; .xn--h327f; [V6, A4_2]; ; # .
+xn--1ug.xn--h327f; ‍.􀸨; [C2, V6]; xn--1ug.xn--h327f; ; ; # .
+񣭻񌥁。≠𝟲; 񣭻񌥁.≠6; [P1, V6]; xn--h79w4z99a.xn--6-tfo; ; ; # .≠6
+񣭻񌥁。≠𝟲; 񣭻񌥁.≠6; [P1, V6]; xn--h79w4z99a.xn--6-tfo; ; ; # .≠6
+񣭻񌥁。≠6; 񣭻񌥁.≠6; [P1, V6]; xn--h79w4z99a.xn--6-tfo; ; ; # .≠6
+񣭻񌥁。≠6; 񣭻񌥁.≠6; [P1, V6]; xn--h79w4z99a.xn--6-tfo; ; ; # .≠6
+xn--h79w4z99a.xn--6-tfo; 񣭻񌥁.≠6; [V6]; xn--h79w4z99a.xn--6-tfo; ; ; # .≠6
+󠅊ᡭ‍.𐥡; ᡭ‍.𐥡; [B6, C2, P1, V6]; xn--98e810b.xn--om9c; ; xn--98e.xn--om9c; [P1, V6] # ᡭ.
+xn--98e.xn--om9c; ᡭ.𐥡; [V6]; xn--98e.xn--om9c; ; ; # ᡭ.
+xn--98e810b.xn--om9c; ᡭ‍.𐥡; [B6, C2, V6]; xn--98e810b.xn--om9c; ; ; # ᡭ.
+ీࡕ𐥛𑄴.󭰵; ీࡕ𐥛𑄴.󭰵; [B1, P1, V5, V6]; xn--kwb91r5112avtg.xn--o580f; ; ; # ీࡕ𑄴.
+ీࡕ𐥛𑄴.󭰵; ; [B1, P1, V5, V6]; xn--kwb91r5112avtg.xn--o580f; ; ; # ీࡕ𑄴.
+xn--kwb91r5112avtg.xn--o580f; ీࡕ𐥛𑄴.󭰵; [B1, V5, V6]; xn--kwb91r5112avtg.xn--o580f; ; ; # ీࡕ𑄴.
+𞤮。𑇊‌≯᳦; 𞤮.𑇊‌≯᳦; [B1, C1, P1, V5, V6]; xn--me6h.xn--z6f16kn9b2642b; ; xn--me6h.xn--z6fz8ueq2v; [B1, P1, V5, V6] # 𞤮.𑇊≯᳦
+𞤮。𑇊‌≯᳦; 𞤮.𑇊‌≯᳦; [B1, C1, P1, V5, V6]; xn--me6h.xn--z6f16kn9b2642b; ; xn--me6h.xn--z6fz8ueq2v; [B1, P1, V5, V6] # 𞤮.𑇊≯᳦
+𞤌。𑇊‌≯᳦; 𞤮.𑇊‌≯᳦; [B1, C1, P1, V5, V6]; xn--me6h.xn--z6f16kn9b2642b; ; xn--me6h.xn--z6fz8ueq2v; [B1, P1, V5, V6] # 𞤮.𑇊≯᳦
+𞤌。𑇊‌≯᳦; 𞤮.𑇊‌≯᳦; [B1, C1, P1, V5, V6]; xn--me6h.xn--z6f16kn9b2642b; ; xn--me6h.xn--z6fz8ueq2v; [B1, P1, V5, V6] # 𞤮.𑇊≯᳦
+xn--me6h.xn--z6fz8ueq2v; 𞤮.𑇊≯᳦; [B1, V5, V6]; xn--me6h.xn--z6fz8ueq2v; ; ; # 𞤮.𑇊≯᳦
+xn--me6h.xn--z6f16kn9b2642b; 𞤮.𑇊‌≯᳦; [B1, C1, V5, V6]; xn--me6h.xn--z6f16kn9b2642b; ; ; # 𞤮.𑇊≯᳦
+󠄀𝟕.𞤌񛗓Ⴉ; 7.𞤮񛗓Ⴉ; [B1, B2, B3, P1, V6]; 7.xn--hnd3403vv1vv; ; ; # 7.𞤮Ⴉ
+󠄀7.𞤌񛗓Ⴉ; 7.𞤮񛗓Ⴉ; [B1, B2, B3, P1, V6]; 7.xn--hnd3403vv1vv; ; ; # 7.𞤮Ⴉ
+󠄀7.𞤮񛗓ⴉ; 7.𞤮񛗓ⴉ; [B1, B2, B3, P1, V6]; 7.xn--0kjz523lv1vv; ; ; # 7.𞤮ⴉ
+7.xn--0kjz523lv1vv; 7.𞤮񛗓ⴉ; [B1, B2, B3, V6]; 7.xn--0kjz523lv1vv; ; ; # 7.𞤮ⴉ
+7.xn--hnd3403vv1vv; 7.𞤮񛗓Ⴉ; [B1, B2, B3, V6]; 7.xn--hnd3403vv1vv; ; ; # 7.𞤮Ⴉ
+󠄀𝟕.𞤮񛗓ⴉ; 7.𞤮񛗓ⴉ; [B1, B2, B3, P1, V6]; 7.xn--0kjz523lv1vv; ; ; # 7.𞤮ⴉ
+󠄀7.𞤌񛗓ⴉ; 7.𞤮񛗓ⴉ; [B1, B2, B3, P1, V6]; 7.xn--0kjz523lv1vv; ; ; # 7.𞤮ⴉ
+󠄀𝟕.𞤌񛗓ⴉ; 7.𞤮񛗓ⴉ; [B1, B2, B3, P1, V6]; 7.xn--0kjz523lv1vv; ; ; # 7.𞤮ⴉ
+閃9𝩍。Ↄ٩ࢱ୍; 閃9𝩍.Ↄ٩ࢱ୍; [B5, B6, P1, V6]; xn--9-3j6dk517f.xn--iib28ij3c0t9a; ; ; # 閃9𝩍.Ↄ٩ࢱ୍
+閃9𝩍。ↄ٩ࢱ୍; 閃9𝩍.ↄ٩ࢱ୍; [B5, B6]; xn--9-3j6dk517f.xn--iib28ij3c4t9a; ; ; # 閃9𝩍.ↄ٩ࢱ୍
+xn--9-3j6dk517f.xn--iib28ij3c4t9a; 閃9𝩍.ↄ٩ࢱ୍; [B5, B6]; xn--9-3j6dk517f.xn--iib28ij3c4t9a; ; ; # 閃9𝩍.ↄ٩ࢱ୍
+xn--9-3j6dk517f.xn--iib28ij3c0t9a; 閃9𝩍.Ↄ٩ࢱ୍; [B5, B6, V6]; xn--9-3j6dk517f.xn--iib28ij3c0t9a; ; ; # 閃9𝩍.Ↄ٩ࢱ୍
+꫶ᢏฺ2.𐋢݅ྟ︒; ꫶ᢏฺ2.𐋢݅ྟ︒; [P1, V5, V6]; xn--2-2zf840fk16m.xn--sob093bj62sz9d; ; ; # ꫶ᢏฺ2.𐋢݅ྟ︒
+꫶ᢏฺ2.𐋢݅ྟ。; ꫶ᢏฺ2.𐋢݅ྟ.; [V5]; xn--2-2zf840fk16m.xn--sob093b2m7s.; ; ; # ꫶ᢏฺ2.𐋢݅ྟ.
+xn--2-2zf840fk16m.xn--sob093b2m7s.; ꫶ᢏฺ2.𐋢݅ྟ.; [V5]; xn--2-2zf840fk16m.xn--sob093b2m7s.; ; ; # ꫶ᢏฺ2.𐋢݅ྟ.
+xn--2-2zf840fk16m.xn--sob093bj62sz9d; ꫶ᢏฺ2.𐋢݅ྟ︒; [V5, V6]; xn--2-2zf840fk16m.xn--sob093bj62sz9d; ; ; # ꫶ᢏฺ2.𐋢݅ྟ︒
+󅴧。≠-󠙄⾛; 󅴧.≠-󠙄走; [P1, V6]; xn--gm57d.xn----tfo4949b3664m; ; ; # .≠-走
+󅴧。≠-󠙄⾛; 󅴧.≠-󠙄走; [P1, V6]; xn--gm57d.xn----tfo4949b3664m; ; ; # .≠-走
+󅴧。≠-󠙄走; 󅴧.≠-󠙄走; [P1, V6]; xn--gm57d.xn----tfo4949b3664m; ; ; # .≠-走
+󅴧。≠-󠙄走; 󅴧.≠-󠙄走; [P1, V6]; xn--gm57d.xn----tfo4949b3664m; ; ; # .≠-走
+xn--gm57d.xn----tfo4949b3664m; 󅴧.≠-󠙄走; [V6]; xn--gm57d.xn----tfo4949b3664m; ; ; # .≠-走
+ݮ؄Ⴊ。-≠ᅠ; ݮ؄Ⴊ.-≠ᅠ; [B1, B2, B3, P1, V3, V6]; xn--mfb73ex6r.xn----5bh589i; ; ; # ݮႪ.-≠
+ݮ؄Ⴊ。-≠ᅠ; ݮ؄Ⴊ.-≠ᅠ; [B1, B2, B3, P1, V3, V6]; xn--mfb73ex6r.xn----5bh589i; ; ; # ݮႪ.-≠
+ݮ؄ⴊ。-≠ᅠ; ݮ؄ⴊ.-≠ᅠ; [B1, B2, B3, P1, V3, V6]; xn--mfb73ek93f.xn----5bh589i; ; ; # ݮⴊ.-≠
+ݮ؄ⴊ。-≠ᅠ; ݮ؄ⴊ.-≠ᅠ; [B1, B2, B3, P1, V3, V6]; xn--mfb73ek93f.xn----5bh589i; ; ; # ݮⴊ.-≠
+xn--mfb73ek93f.xn----5bh589i; ݮ؄ⴊ.-≠ᅠ; [B1, B2, B3, V3, V6]; xn--mfb73ek93f.xn----5bh589i; ; ; # ݮⴊ.-≠
+xn--mfb73ex6r.xn----5bh589i; ݮ؄Ⴊ.-≠ᅠ; [B1, B2, B3, V3, V6]; xn--mfb73ex6r.xn----5bh589i; ; ; # ݮႪ.-≠
+ﭏ𐹧𝟒≯。‌; אל𐹧4≯.‌; [B1, B3, B4, C1, P1, V6]; xn--4-zhc0by36txt0w.xn--0ug; ; xn--4-zhc0by36txt0w.; [B3, B4, P1, V6] # אל𐹧4≯.
+ﭏ𐹧𝟒≯。‌; אל𐹧4≯.‌; [B1, B3, B4, C1, P1, V6]; xn--4-zhc0by36txt0w.xn--0ug; ; xn--4-zhc0by36txt0w.; [B3, B4, P1, V6] # אל𐹧4≯.
+אל𐹧4≯。‌; אל𐹧4≯.‌; [B1, B3, B4, C1, P1, V6]; xn--4-zhc0by36txt0w.xn--0ug; ; xn--4-zhc0by36txt0w.; [B3, B4, P1, V6] # אל𐹧4≯.
+אל𐹧4≯。‌; אל𐹧4≯.‌; [B1, B3, B4, C1, P1, V6]; xn--4-zhc0by36txt0w.xn--0ug; ; xn--4-zhc0by36txt0w.; [B3, B4, P1, V6] # אל𐹧4≯.
+xn--4-zhc0by36txt0w.; אל𐹧4≯.; [B3, B4, V6]; xn--4-zhc0by36txt0w.; ; ; # אל𐹧4≯.
+xn--4-zhc0by36txt0w.xn--0ug; אל𐹧4≯.‌; [B1, B3, B4, C1, V6]; xn--4-zhc0by36txt0w.xn--0ug; ; ; # אל𐹧4≯.
+𝟎。甯; 0.甯; ; 0.xn--qny; ; ; # 0.甯
+0。甯; 0.甯; ; 0.xn--qny; ; ; # 0.甯
+0.xn--qny; 0.甯; ; 0.xn--qny; ; ; # 0.甯
+0.甯; ; ; 0.xn--qny; ; ; # 0.甯
+-⾆.꫶; -舌.꫶; [V3, V5]; xn----ef8c.xn--2v9a; ; ; # -舌.꫶
+-舌.꫶; ; [V3, V5]; xn----ef8c.xn--2v9a; ; ; # -舌.꫶
+xn----ef8c.xn--2v9a; -舌.꫶; [V3, V5]; xn----ef8c.xn--2v9a; ; ; # -舌.꫶
+-。ᢘ; -.ᢘ; [V3]; -.xn--ibf; ; ; # -.ᢘ
+-。ᢘ; -.ᢘ; [V3]; -.xn--ibf; ; ; # -.ᢘ
+-.xn--ibf; -.ᢘ; [V3]; -.xn--ibf; ; ; # -.ᢘ
+🂴Ⴋ.≮; ; [P1, V6]; xn--jnd1986v.xn--gdh; ; ; # 🂴Ⴋ.≮
+🂴Ⴋ.≮; 🂴Ⴋ.≮; [P1, V6]; xn--jnd1986v.xn--gdh; ; ; # 🂴Ⴋ.≮
+🂴ⴋ.≮; 🂴ⴋ.≮; [P1, V6]; xn--2kj7565l.xn--gdh; ; ; # 🂴ⴋ.≮
+🂴ⴋ.≮; ; [P1, V6]; xn--2kj7565l.xn--gdh; ; ; # 🂴ⴋ.≮
+xn--2kj7565l.xn--gdh; 🂴ⴋ.≮; [V6]; xn--2kj7565l.xn--gdh; ; ; # 🂴ⴋ.≮
+xn--jnd1986v.xn--gdh; 🂴Ⴋ.≮; [V6]; xn--jnd1986v.xn--gdh; ; ; # 🂴Ⴋ.≮
+璼𝨭。‌󠇟; 璼𝨭.‌; [C1]; xn--gky8837e.xn--0ug; ; xn--gky8837e.; [] # 璼𝨭.
+璼𝨭。‌󠇟; 璼𝨭.‌; [C1]; xn--gky8837e.xn--0ug; ; xn--gky8837e.; [] # 璼𝨭.
+xn--gky8837e.; 璼𝨭.; ; xn--gky8837e.; ; ; # 璼𝨭.
+璼𝨭.; ; ; xn--gky8837e.; ; ; # 璼𝨭.
+xn--gky8837e.xn--0ug; 璼𝨭.‌; [C1]; xn--gky8837e.xn--0ug; ; ; # 璼𝨭.
+٩8񂍽。-5🞥; ٩8񂍽.-5🞥; [B1, P1, V3, V6]; xn--8-qqc97891f.xn---5-rp92a; ; ; # ٩8.-5🞥
+٩8񂍽。-5🞥; ٩8񂍽.-5🞥; [B1, P1, V3, V6]; xn--8-qqc97891f.xn---5-rp92a; ; ; # ٩8.-5🞥
+xn--8-qqc97891f.xn---5-rp92a; ٩8񂍽.-5🞥; [B1, V3, V6]; xn--8-qqc97891f.xn---5-rp92a; ; ; # ٩8.-5🞥
+‌.‌; ; [C1]; xn--0ug.xn--0ug; ; .; [A4_2] # .
+xn--0ug.xn--0ug; ‌.‌; [C1]; xn--0ug.xn--0ug; ; ; # .
+‍튛.ܖ; ; [B1, C2]; xn--1ug4441e.xn--gnb; ; xn--157b.xn--gnb; [] # 튛.ܖ
+‍튛.ܖ; ‍튛.ܖ; [B1, C2]; xn--1ug4441e.xn--gnb; ; xn--157b.xn--gnb; [] # 튛.ܖ
+xn--157b.xn--gnb; 튛.ܖ; ; xn--157b.xn--gnb; ; ; # 튛.ܖ
+튛.ܖ; ; ; xn--157b.xn--gnb; ; ; # 튛.ܖ
+튛.ܖ; 튛.ܖ; ; xn--157b.xn--gnb; ; ; # 튛.ܖ
+xn--1ug4441e.xn--gnb; ‍튛.ܖ; [B1, C2]; xn--1ug4441e.xn--gnb; ; ; # 튛.ܖ
+ᡋ𐹰𞽳.ݹⴞ; ; [B2, B3, B5, B6, P1, V6]; xn--b8e0417jocvf.xn--9pb883q; ; ; # ᡋ𐹰.ݹⴞ
+ᡋ𐹰𞽳.ݹႾ; ; [B2, B3, B5, B6, P1, V6]; xn--b8e0417jocvf.xn--9pb068b; ; ; # ᡋ𐹰.ݹႾ
+xn--b8e0417jocvf.xn--9pb068b; ᡋ𐹰𞽳.ݹႾ; [B2, B3, B5, B6, V6]; xn--b8e0417jocvf.xn--9pb068b; ; ; # ᡋ𐹰.ݹႾ
+xn--b8e0417jocvf.xn--9pb883q; ᡋ𐹰𞽳.ݹⴞ; [B2, B3, B5, B6, V6]; xn--b8e0417jocvf.xn--9pb883q; ; ; # ᡋ𐹰.ݹⴞ
+𐷃٢𝅻𝟧.𐹮𐹬Ⴇ; 𐷃٢𝅻5.𐹮𐹬Ⴇ; [B1, B4, P1, V6]; xn--5-cqc8833rhv7f.xn--fnd3401kfa; ; ; # ٢𝅻5.𐹮𐹬Ⴇ
+𐷃٢𝅻5.𐹮𐹬Ⴇ; ; [B1, B4, P1, V6]; xn--5-cqc8833rhv7f.xn--fnd3401kfa; ; ; # ٢𝅻5.𐹮𐹬Ⴇ
+𐷃٢𝅻5.𐹮𐹬ⴇ; ; [B1, B4, P1, V6]; xn--5-cqc8833rhv7f.xn--ykjz523efa; ; ; # ٢𝅻5.𐹮𐹬ⴇ
+xn--5-cqc8833rhv7f.xn--ykjz523efa; 𐷃٢𝅻5.𐹮𐹬ⴇ; [B1, B4, V6]; xn--5-cqc8833rhv7f.xn--ykjz523efa; ; ; # ٢𝅻5.𐹮𐹬ⴇ
+xn--5-cqc8833rhv7f.xn--fnd3401kfa; 𐷃٢𝅻5.𐹮𐹬Ⴇ; [B1, B4, V6]; xn--5-cqc8833rhv7f.xn--fnd3401kfa; ; ; # ٢𝅻5.𐹮𐹬Ⴇ
+𐷃٢𝅻𝟧.𐹮𐹬ⴇ; 𐷃٢𝅻5.𐹮𐹬ⴇ; [B1, B4, P1, V6]; xn--5-cqc8833rhv7f.xn--ykjz523efa; ; ; # ٢𝅻5.𐹮𐹬ⴇ
+Ⴗ.𑄴ׂꦷ񘃨; Ⴗ.𑄴ׂꦷ񘃨; [P1, V5, V6]; xn--vnd.xn--qdb0605f14ycrms3c; ; ; # Ⴗ.𑄴ׂꦷ
+Ⴗ.𑄴ׂꦷ񘃨; Ⴗ.𑄴ׂꦷ񘃨; [P1, V5, V6]; xn--vnd.xn--qdb0605f14ycrms3c; ; ; # Ⴗ.𑄴ׂꦷ
+Ⴗ.𑄴ׂꦷ񘃨; ; [P1, V5, V6]; xn--vnd.xn--qdb0605f14ycrms3c; ; ; # Ⴗ.𑄴ׂꦷ
+ⴗ.𑄴ׂꦷ񘃨; ; [P1, V5, V6]; xn--flj.xn--qdb0605f14ycrms3c; ; ; # ⴗ.𑄴ׂꦷ
+xn--flj.xn--qdb0605f14ycrms3c; ⴗ.𑄴ׂꦷ񘃨; [V5, V6]; xn--flj.xn--qdb0605f14ycrms3c; ; ; # ⴗ.𑄴ׂꦷ
+xn--vnd.xn--qdb0605f14ycrms3c; Ⴗ.𑄴ׂꦷ񘃨; [V5, V6]; xn--vnd.xn--qdb0605f14ycrms3c; ; ; # Ⴗ.𑄴ׂꦷ
+ⴗ.𑄴ׂꦷ񘃨; ⴗ.𑄴ׂꦷ񘃨; [P1, V5, V6]; xn--flj.xn--qdb0605f14ycrms3c; ; ; # ⴗ.𑄴ׂꦷ
+ⴗ.𑄴ׂꦷ񘃨; ⴗ.𑄴ׂꦷ񘃨; [P1, V5, V6]; xn--flj.xn--qdb0605f14ycrms3c; ; ; # ⴗ.𑄴ׂꦷ
+𝟾𾤘.򇕛٬; 8𾤘.򇕛٬; [B1, B5, B6, P1, V6]; xn--8-kh23b.xn--lib78461i; ; ; # 8.٬
+8𾤘.򇕛٬; ; [B1, B5, B6, P1, V6]; xn--8-kh23b.xn--lib78461i; ; ; # 8.٬
+xn--8-kh23b.xn--lib78461i; 8𾤘.򇕛٬; [B1, B5, B6, V6]; xn--8-kh23b.xn--lib78461i; ; ; # 8.٬
+⒈酫︒。ࣖ; ⒈酫︒.ࣖ; [P1, V5, V6]; xn--tsh4490bfe8c.xn--8zb; ; ; # ⒈酫︒.ࣖ
+1.酫。。ࣖ; 1.酫..ࣖ; [V5, X4_2]; 1.xn--8j4a..xn--8zb; [V5, A4_2]; ; # 1.酫..ࣖ
+1.xn--8j4a..xn--8zb; 1.酫..ࣖ; [V5, X4_2]; 1.xn--8j4a..xn--8zb; [V5, A4_2]; ; # 1.酫..ࣖ
+xn--tsh4490bfe8c.xn--8zb; ⒈酫︒.ࣖ; [V5, V6]; xn--tsh4490bfe8c.xn--8zb; ; ; # ⒈酫︒.ࣖ
+ⷣ‌≮ᩫ.‌ฺ; ; [C1, P1, V5, V6]; xn--uof63xk4bf3s.xn--o4c732g; ; xn--uof548an0j.xn--o4c; [P1, V5, V6] # ⷣ≮ᩫ.ฺ
+ⷣ‌≮ᩫ.‌ฺ; ⷣ‌≮ᩫ.‌ฺ; [C1, P1, V5, V6]; xn--uof63xk4bf3s.xn--o4c732g; ; xn--uof548an0j.xn--o4c; [P1, V5, V6] # ⷣ≮ᩫ.ฺ
+xn--uof548an0j.xn--o4c; ⷣ≮ᩫ.ฺ; [V5, V6]; xn--uof548an0j.xn--o4c; ; ; # ⷣ≮ᩫ.ฺ
+xn--uof63xk4bf3s.xn--o4c732g; ⷣ‌≮ᩫ.‌ฺ; [C1, V5, V6]; xn--uof63xk4bf3s.xn--o4c732g; ; ; # ⷣ≮ᩫ.ฺ
+𞪂。ႷႽ¹‍; 𞪂.ႷႽ1‍; [B6, C2, P1, V6]; xn--co6h.xn--1-h1gs597m; ; xn--co6h.xn--1-h1gs; [P1, V6] # .ႷႽ1
+𞪂。ႷႽ1‍; 𞪂.ႷႽ1‍; [B6, C2, P1, V6]; xn--co6h.xn--1-h1gs597m; ; xn--co6h.xn--1-h1gs; [P1, V6] # .ႷႽ1
+𞪂。ⴗⴝ1‍; 𞪂.ⴗⴝ1‍; [B6, C2, P1, V6]; xn--co6h.xn--1-ugn710dya; ; xn--co6h.xn--1-kwssa; [P1, V6] # .ⴗⴝ1
+𞪂。Ⴗⴝ1‍; 𞪂.Ⴗⴝ1‍; [B6, C2, P1, V6]; xn--co6h.xn--1-h1g398iewm; ; xn--co6h.xn--1-h1g429s; [P1, V6] # .Ⴗⴝ1
+xn--co6h.xn--1-h1g429s; 𞪂.Ⴗⴝ1; [V6]; xn--co6h.xn--1-h1g429s; ; ; # .Ⴗⴝ1
+xn--co6h.xn--1-h1g398iewm; 𞪂.Ⴗⴝ1‍; [B6, C2, V6]; xn--co6h.xn--1-h1g398iewm; ; ; # .Ⴗⴝ1
+xn--co6h.xn--1-kwssa; 𞪂.ⴗⴝ1; [V6]; xn--co6h.xn--1-kwssa; ; ; # .ⴗⴝ1
+xn--co6h.xn--1-ugn710dya; 𞪂.ⴗⴝ1‍; [B6, C2, V6]; xn--co6h.xn--1-ugn710dya; ; ; # .ⴗⴝ1
+xn--co6h.xn--1-h1gs; 𞪂.ႷႽ1; [V6]; xn--co6h.xn--1-h1gs; ; ; # .ႷႽ1
+xn--co6h.xn--1-h1gs597m; 𞪂.ႷႽ1‍; [B6, C2, V6]; xn--co6h.xn--1-h1gs597m; ; ; # .ႷႽ1
+𞪂。ⴗⴝ¹‍; 𞪂.ⴗⴝ1‍; [B6, C2, P1, V6]; xn--co6h.xn--1-ugn710dya; ; xn--co6h.xn--1-kwssa; [P1, V6] # .ⴗⴝ1
+𞪂。Ⴗⴝ¹‍; 𞪂.Ⴗⴝ1‍; [B6, C2, P1, V6]; xn--co6h.xn--1-h1g398iewm; ; xn--co6h.xn--1-h1g429s; [P1, V6] # .Ⴗⴝ1
+𑄴𑄳2.𞳿󠀳-; ; [B1, B3, P1, V3, V5, V6]; xn--2-h87ic.xn----s39r33498d; ; ; # 𑄴𑄳2.-
+xn--2-h87ic.xn----s39r33498d; 𑄴𑄳2.𞳿󠀳-; [B1, B3, V3, V5, V6]; xn--2-h87ic.xn----s39r33498d; ; ; # 𑄴𑄳2.-
+󠕲󟶶٥。񀁁𑄳𞤃ܐ; 󠕲󟶶٥.񀁁𑄳𞤥ܐ; [B1, B5, B6, P1, V6]; xn--eib57614py3ea.xn--9mb5737kqnpfzkwr; ; ; # ٥.𑄳𞤥ܐ
+󠕲󟶶٥。񀁁𑄳𞤃ܐ; 󠕲󟶶٥.񀁁𑄳𞤥ܐ; [B1, B5, B6, P1, V6]; xn--eib57614py3ea.xn--9mb5737kqnpfzkwr; ; ; # ٥.𑄳𞤥ܐ
+󠕲󟶶٥。񀁁𑄳𞤥ܐ; 󠕲󟶶٥.񀁁𑄳𞤥ܐ; [B1, B5, B6, P1, V6]; xn--eib57614py3ea.xn--9mb5737kqnpfzkwr; ; ; # ٥.𑄳𞤥ܐ
+xn--eib57614py3ea.xn--9mb5737kqnpfzkwr; 󠕲󟶶٥.񀁁𑄳𞤥ܐ; [B1, B5, B6, V6]; xn--eib57614py3ea.xn--9mb5737kqnpfzkwr; ; ; # ٥.𑄳𞤥ܐ
+󠕲󟶶٥。񀁁𑄳𞤥ܐ; 󠕲󟶶٥.񀁁𑄳𞤥ܐ; [B1, B5, B6, P1, V6]; xn--eib57614py3ea.xn--9mb5737kqnpfzkwr; ; ; # ٥.𑄳𞤥ܐ
+ܠ򲠽𐹢ុ。ςᢈ🝭‌; ܠ򲠽𐹢ុ.ςᢈ🝭‌; [B2, B6, C1, P1, V6]; xn--qnb616fis0qzt36f.xn--3xa057h6ofgl44c; ; xn--qnb616fis0qzt36f.xn--4xa847hli46a; [B2, B6, P1, V6] # ܠ𐹢ុ.ςᢈ🝭
+ܠ򲠽𐹢ុ。ςᢈ🝭‌; ܠ򲠽𐹢ុ.ςᢈ🝭‌; [B2, B6, C1, P1, V6]; xn--qnb616fis0qzt36f.xn--3xa057h6ofgl44c; ; xn--qnb616fis0qzt36f.xn--4xa847hli46a; [B2, B6, P1, V6] # ܠ𐹢ុ.ςᢈ🝭
+ܠ򲠽𐹢ុ。Σᢈ🝭‌; ܠ򲠽𐹢ុ.σᢈ🝭‌; [B2, B6, C1, P1, V6]; xn--qnb616fis0qzt36f.xn--4xa847h6ofgl44c; ; xn--qnb616fis0qzt36f.xn--4xa847hli46a; [B2, B6, P1, V6] # ܠ𐹢ុ.σᢈ🝭
+ܠ򲠽𐹢ុ。σᢈ🝭‌; ܠ򲠽𐹢ុ.σᢈ🝭‌; [B2, B6, C1, P1, V6]; xn--qnb616fis0qzt36f.xn--4xa847h6ofgl44c; ; xn--qnb616fis0qzt36f.xn--4xa847hli46a; [B2, B6, P1, V6] # ܠ𐹢ុ.σᢈ🝭
+xn--qnb616fis0qzt36f.xn--4xa847hli46a; ܠ򲠽𐹢ុ.σᢈ🝭; [B2, B6, V6]; xn--qnb616fis0qzt36f.xn--4xa847hli46a; ; ; # ܠ𐹢ុ.σᢈ🝭
+xn--qnb616fis0qzt36f.xn--4xa847h6ofgl44c; ܠ򲠽𐹢ុ.σᢈ🝭‌; [B2, B6, C1, V6]; xn--qnb616fis0qzt36f.xn--4xa847h6ofgl44c; ; ; # ܠ𐹢ុ.σᢈ🝭
+xn--qnb616fis0qzt36f.xn--3xa057h6ofgl44c; ܠ򲠽𐹢ុ.ςᢈ🝭‌; [B2, B6, C1, V6]; xn--qnb616fis0qzt36f.xn--3xa057h6ofgl44c; ; ; # ܠ𐹢ុ.ςᢈ🝭
+ܠ򲠽𐹢ុ。Σᢈ🝭‌; ܠ򲠽𐹢ុ.σᢈ🝭‌; [B2, B6, C1, P1, V6]; xn--qnb616fis0qzt36f.xn--4xa847h6ofgl44c; ; xn--qnb616fis0qzt36f.xn--4xa847hli46a; [B2, B6, P1, V6] # ܠ𐹢ុ.σᢈ🝭
+ܠ򲠽𐹢ុ。σᢈ🝭‌; ܠ򲠽𐹢ុ.σᢈ🝭‌; [B2, B6, C1, P1, V6]; xn--qnb616fis0qzt36f.xn--4xa847h6ofgl44c; ; xn--qnb616fis0qzt36f.xn--4xa847hli46a; [B2, B6, P1, V6] # ܠ𐹢ុ.σᢈ🝭
+‍--≮。𐹧; ‍--≮.𐹧; [B1, C2, P1, V6]; xn-----l1tz1k.xn--fo0d; ; xn-----ujv.xn--fo0d; [B1, P1, V3, V6] # --≮.𐹧
+‍--≮。𐹧; ‍--≮.𐹧; [B1, C2, P1, V6]; xn-----l1tz1k.xn--fo0d; ; xn-----ujv.xn--fo0d; [B1, P1, V3, V6] # --≮.𐹧
+xn-----ujv.xn--fo0d; --≮.𐹧; [B1, V3, V6]; xn-----ujv.xn--fo0d; ; ; # --≮.𐹧
+xn-----l1tz1k.xn--fo0d; ‍--≮.𐹧; [B1, C2, V6]; xn-----l1tz1k.xn--fo0d; ; ; # --≮.𐹧
+꠆。𻚏ྰ⒕; ꠆.𻚏ྰ⒕; [P1, V5, V6]; xn--l98a.xn--dgd218hhp28d; ; ; # ꠆.ྰ⒕
+꠆。𻚏ྰ14.; ꠆.𻚏ྰ14.; [P1, V5, V6]; xn--l98a.xn--14-jsj57880f.; ; ; # ꠆.ྰ14.
+xn--l98a.xn--14-jsj57880f.; ꠆.𻚏ྰ14.; [V5, V6]; xn--l98a.xn--14-jsj57880f.; ; ; # ꠆.ྰ14.
+xn--l98a.xn--dgd218hhp28d; ꠆.𻚏ྰ⒕; [V5, V6]; xn--l98a.xn--dgd218hhp28d; ; ; # ꠆.ྰ⒕
+򮉂ڼ.𑆺٩; 򮉂ڼ.𑆺٩; [B1, B5, B6, P1, V5, V6]; xn--vkb92243l.xn--iib9797k; ; ; # ڼ.𑆺٩
+򮉂ڼ.𑆺٩; ; [B1, B5, B6, P1, V5, V6]; xn--vkb92243l.xn--iib9797k; ; ; # ڼ.𑆺٩
+xn--vkb92243l.xn--iib9797k; 򮉂ڼ.𑆺٩; [B1, B5, B6, V5, V6]; xn--vkb92243l.xn--iib9797k; ; ; # ڼ.𑆺٩
+󠁎ې-。𞤴; 󠁎ې-.𞤴; [B1, P1, V3, V6]; xn----mwc72685y.xn--se6h; ; ; # ې-.𞤴
+󠁎ې-。𞤒; 󠁎ې-.𞤴; [B1, P1, V3, V6]; xn----mwc72685y.xn--se6h; ; ; # ې-.𞤴
+xn----mwc72685y.xn--se6h; 󠁎ې-.𞤴; [B1, V3, V6]; xn----mwc72685y.xn--se6h; ; ; # ې-.𞤴
+𝟠4󠇗𝈻.‍𐋵⛧‍; 84𝈻.‍𐋵⛧‍; [C2]; xn--84-s850a.xn--1uga573cfq1w; ; xn--84-s850a.xn--59h6326e; [] # 84𝈻.𐋵⛧
+84󠇗𝈻.‍𐋵⛧‍; 84𝈻.‍𐋵⛧‍; [C2]; xn--84-s850a.xn--1uga573cfq1w; ; xn--84-s850a.xn--59h6326e; [] # 84𝈻.𐋵⛧
+xn--84-s850a.xn--59h6326e; 84𝈻.𐋵⛧; ; xn--84-s850a.xn--59h6326e; ; ; # 84𝈻.𐋵⛧
+84𝈻.𐋵⛧; ; ; xn--84-s850a.xn--59h6326e; ; ; # 84𝈻.𐋵⛧
+xn--84-s850a.xn--1uga573cfq1w; 84𝈻.‍𐋵⛧‍; [C2]; xn--84-s850a.xn--1uga573cfq1w; ; ; # 84𝈻.𐋵⛧
+-؁。ᡪ; -؁.ᡪ; [B1, P1, V3, V6]; xn----tkc.xn--68e; ; ; # -.ᡪ
+-؁。ᡪ; -؁.ᡪ; [B1, P1, V3, V6]; xn----tkc.xn--68e; ; ; # -.ᡪ
+xn----tkc.xn--68e; -؁.ᡪ; [B1, V3, V6]; xn----tkc.xn--68e; ; ; # -.ᡪ
+≮𝟕.謖ß≯; ≮7.謖ß≯; [P1, V6]; xn--7-mgo.xn--zca892oly5e; ; xn--7-mgo.xn--ss-xjvv174c; # ≮7.謖ß≯
+≮𝟕.謖ß≯; ≮7.謖ß≯; [P1, V6]; xn--7-mgo.xn--zca892oly5e; ; xn--7-mgo.xn--ss-xjvv174c; # ≮7.謖ß≯
+≮7.謖ß≯; ; [P1, V6]; xn--7-mgo.xn--zca892oly5e; ; xn--7-mgo.xn--ss-xjvv174c; # ≮7.謖ß≯
+≮7.謖ß≯; ≮7.謖ß≯; [P1, V6]; xn--7-mgo.xn--zca892oly5e; ; xn--7-mgo.xn--ss-xjvv174c; # ≮7.謖ß≯
+≮7.謖SS≯; ≮7.謖ss≯; [P1, V6]; xn--7-mgo.xn--ss-xjvv174c; ; ; # ≮7.謖ss≯
+≮7.謖SS≯; ≮7.謖ss≯; [P1, V6]; xn--7-mgo.xn--ss-xjvv174c; ; ; # ≮7.謖ss≯
+≮7.謖ss≯; ; [P1, V6]; xn--7-mgo.xn--ss-xjvv174c; ; ; # ≮7.謖ss≯
+≮7.謖ss≯; ≮7.謖ss≯; [P1, V6]; xn--7-mgo.xn--ss-xjvv174c; ; ; # ≮7.謖ss≯
+≮7.謖Ss≯; ≮7.謖ss≯; [P1, V6]; xn--7-mgo.xn--ss-xjvv174c; ; ; # ≮7.謖ss≯
+≮7.謖Ss≯; ≮7.謖ss≯; [P1, V6]; xn--7-mgo.xn--ss-xjvv174c; ; ; # ≮7.謖ss≯
+xn--7-mgo.xn--ss-xjvv174c; ≮7.謖ss≯; [V6]; xn--7-mgo.xn--ss-xjvv174c; ; ; # ≮7.謖ss≯
+xn--7-mgo.xn--zca892oly5e; ≮7.謖ß≯; [V6]; xn--7-mgo.xn--zca892oly5e; ; ; # ≮7.謖ß≯
+≮𝟕.謖SS≯; ≮7.謖ss≯; [P1, V6]; xn--7-mgo.xn--ss-xjvv174c; ; ; # ≮7.謖ss≯
+≮𝟕.謖SS≯; ≮7.謖ss≯; [P1, V6]; xn--7-mgo.xn--ss-xjvv174c; ; ; # ≮7.謖ss≯
+≮𝟕.謖ss≯; ≮7.謖ss≯; [P1, V6]; xn--7-mgo.xn--ss-xjvv174c; ; ; # ≮7.謖ss≯
+≮𝟕.謖ss≯; ≮7.謖ss≯; [P1, V6]; xn--7-mgo.xn--ss-xjvv174c; ; ; # ≮7.謖ss≯
+≮𝟕.謖Ss≯; ≮7.謖ss≯; [P1, V6]; xn--7-mgo.xn--ss-xjvv174c; ; ; # ≮7.謖ss≯
+≮𝟕.謖Ss≯; ≮7.謖ss≯; [P1, V6]; xn--7-mgo.xn--ss-xjvv174c; ; ; # ≮7.謖ss≯
+朶Ⴉ𞪡.𝨽ࠥ📻-; ; [B1, B5, B6, P1, V3, V5, V6]; xn--hnd7245bd56p.xn----3gd37096apmwa; ; ; # 朶Ⴉ.𝨽ࠥ📻-
+朶ⴉ𞪡.𝨽ࠥ📻-; ; [B1, B5, B6, P1, V3, V5, V6]; xn--0kjz47pd57t.xn----3gd37096apmwa; ; ; # 朶ⴉ.𝨽ࠥ📻-
+xn--0kjz47pd57t.xn----3gd37096apmwa; 朶ⴉ𞪡.𝨽ࠥ📻-; [B1, B5, B6, V3, V5, V6]; xn--0kjz47pd57t.xn----3gd37096apmwa; ; ; # 朶ⴉ.𝨽ࠥ📻-
+xn--hnd7245bd56p.xn----3gd37096apmwa; 朶Ⴉ𞪡.𝨽ࠥ📻-; [B1, B5, B6, V3, V5, V6]; xn--hnd7245bd56p.xn----3gd37096apmwa; ; ; # 朶Ⴉ.𝨽ࠥ📻-
+𐤎。󑿰‌≮‍; 𐤎.󑿰‌≮‍; [B6, C1, C2, P1, V6]; xn--bk9c.xn--0ugc04p2u638c; ; xn--bk9c.xn--gdhx6802k; [B6, P1, V6] # 𐤎.≮
+𐤎。󑿰‌≮‍; 𐤎.󑿰‌≮‍; [B6, C1, C2, P1, V6]; xn--bk9c.xn--0ugc04p2u638c; ; xn--bk9c.xn--gdhx6802k; [B6, P1, V6] # 𐤎.≮
+xn--bk9c.xn--gdhx6802k; 𐤎.󑿰≮; [B6, V6]; xn--bk9c.xn--gdhx6802k; ; ; # 𐤎.≮
+xn--bk9c.xn--0ugc04p2u638c; 𐤎.󑿰‌≮‍; [B6, C1, C2, V6]; xn--bk9c.xn--0ugc04p2u638c; ; ; # 𐤎.≮
+񭜎⒈。‌𝟤; 񭜎⒈.‌2; [C1, P1, V6]; xn--tsh94183d.xn--2-rgn; ; xn--tsh94183d.2; [P1, V6] # ⒈.2
+񭜎1.。‌2; 񭜎1..‌2; [C1, P1, V6, X4_2]; xn--1-ex54e..xn--2-rgn; [C1, P1, V6, A4_2]; xn--1-ex54e..2; [P1, V6, A4_2] # 1..2
+xn--1-ex54e..2; 񭜎1..2; [V6, X4_2]; xn--1-ex54e..2; [V6, A4_2]; ; # 1..2
+xn--1-ex54e..xn--2-rgn; 񭜎1..‌2; [C1, V6, X4_2]; xn--1-ex54e..xn--2-rgn; [C1, V6, A4_2]; ; # 1..2
+xn--tsh94183d.2; 񭜎⒈.2; [V6]; xn--tsh94183d.2; ; ; # ⒈.2
+xn--tsh94183d.xn--2-rgn; 񭜎⒈.‌2; [C1, V6]; xn--tsh94183d.xn--2-rgn; ; ; # ⒈.2
+󠟊𐹤‍.𐹳󙄵𐹶; 󠟊𐹤‍.𐹳󙄵𐹶; [B1, C2, P1, V6]; xn--1ugy994g7k93g.xn--ro0dga22807v; ; xn--co0d98977c.xn--ro0dga22807v; [B1, P1, V6] # 𐹤.𐹳𐹶
+󠟊𐹤‍.𐹳󙄵𐹶; ; [B1, C2, P1, V6]; xn--1ugy994g7k93g.xn--ro0dga22807v; ; xn--co0d98977c.xn--ro0dga22807v; [B1, P1, V6] # 𐹤.𐹳𐹶
+xn--co0d98977c.xn--ro0dga22807v; 󠟊𐹤.𐹳󙄵𐹶; [B1, V6]; xn--co0d98977c.xn--ro0dga22807v; ; ; # 𐹤.𐹳𐹶
+xn--1ugy994g7k93g.xn--ro0dga22807v; 󠟊𐹤‍.𐹳󙄵𐹶; [B1, C2, V6]; xn--1ugy994g7k93g.xn--ro0dga22807v; ; ; # 𐹤.𐹳𐹶
+𞤴𐹻𑓂𐭝.्︇􉛯; 𞤴𐹻𑓂𐭝.्􉛯; [B1, P1, V5, V6]; xn--609c96c09grp2w.xn--n3b28708s; ; ; # 𞤴𐹻𑓂𐭝.्
+𞤴𐹻𑓂𐭝.्︇􉛯; 𞤴𐹻𑓂𐭝.्􉛯; [B1, P1, V5, V6]; xn--609c96c09grp2w.xn--n3b28708s; ; ; # 𞤴𐹻𑓂𐭝.्
+𞤒𐹻𑓂𐭝.्︇􉛯; 𞤴𐹻𑓂𐭝.्􉛯; [B1, P1, V5, V6]; xn--609c96c09grp2w.xn--n3b28708s; ; ; # 𞤴𐹻𑓂𐭝.्
+xn--609c96c09grp2w.xn--n3b28708s; 𞤴𐹻𑓂𐭝.्􉛯; [B1, V5, V6]; xn--609c96c09grp2w.xn--n3b28708s; ; ; # 𞤴𐹻𑓂𐭝.्
+𞤒𐹻𑓂𐭝.्︇􉛯; 𞤴𐹻𑓂𐭝.्􉛯; [B1, P1, V5, V6]; xn--609c96c09grp2w.xn--n3b28708s; ; ; # 𞤴𐹻𑓂𐭝.्
+٨。𐹠𐹽񗮶; ٨.𐹠𐹽񗮶; [B1, P1, V6]; xn--hib.xn--7n0d2bu9196b; ; ; # ٨.𐹠𐹽
+٨。𐹠𐹽񗮶; ٨.𐹠𐹽񗮶; [B1, P1, V6]; xn--hib.xn--7n0d2bu9196b; ; ; # ٨.𐹠𐹽
+xn--hib.xn--7n0d2bu9196b; ٨.𐹠𐹽񗮶; [B1, V6]; xn--hib.xn--7n0d2bu9196b; ; ; # ٨.𐹠𐹽
+ᅠ񍀜.8򶾵ڜ; ; [B1, P1, V6]; xn--psd85033d.xn--8-otc61545t; ; ; # .8ڜ
+xn--psd85033d.xn--8-otc61545t; ᅠ񍀜.8򶾵ڜ; [B1, V6]; xn--psd85033d.xn--8-otc61545t; ; ; # .8ڜ
+‍‌󠆪。ß𑓃; ‍‌.ß𑓃; [C1, C2]; xn--0ugb.xn--zca0732l; ; .xn--ss-bh7o; [A4_2] # .ß𑓃
+‍‌󠆪。ß𑓃; ‍‌.ß𑓃; [C1, C2]; xn--0ugb.xn--zca0732l; ; .xn--ss-bh7o; [A4_2] # .ß𑓃
+‍‌󠆪。SS𑓃; ‍‌.ss𑓃; [C1, C2]; xn--0ugb.xn--ss-bh7o; ; .xn--ss-bh7o; [A4_2] # .ss𑓃
+‍‌󠆪。ss𑓃; ‍‌.ss𑓃; [C1, C2]; xn--0ugb.xn--ss-bh7o; ; .xn--ss-bh7o; [A4_2] # .ss𑓃
+‍‌󠆪。Ss𑓃; ‍‌.ss𑓃; [C1, C2]; xn--0ugb.xn--ss-bh7o; ; .xn--ss-bh7o; [A4_2] # .ss𑓃
+.xn--ss-bh7o; .ss𑓃; [X4_2]; .xn--ss-bh7o; [A4_2]; ; # .ss𑓃
+xn--0ugb.xn--ss-bh7o; ‍‌.ss𑓃; [C1, C2]; xn--0ugb.xn--ss-bh7o; ; ; # .ss𑓃
+xn--0ugb.xn--zca0732l; ‍‌.ß𑓃; [C1, C2]; xn--0ugb.xn--zca0732l; ; ; # .ß𑓃
+‍‌󠆪。SS𑓃; ‍‌.ss𑓃; [C1, C2]; xn--0ugb.xn--ss-bh7o; ; .xn--ss-bh7o; [A4_2] # .ss𑓃
+‍‌󠆪。ss𑓃; ‍‌.ss𑓃; [C1, C2]; xn--0ugb.xn--ss-bh7o; ; .xn--ss-bh7o; [A4_2] # .ss𑓃
+‍‌󠆪。Ss𑓃; ‍‌.ss𑓃; [C1, C2]; xn--0ugb.xn--ss-bh7o; ; .xn--ss-bh7o; [A4_2] # .ss𑓃
+xn--ss-bh7o; ss𑓃; ; xn--ss-bh7o; ; ; # ss𑓃
+ss𑓃; ; ; xn--ss-bh7o; ; ; # ss𑓃
+SS𑓃; ss𑓃; ; xn--ss-bh7o; ; ; # ss𑓃
+Ss𑓃; ss𑓃; ; xn--ss-bh7o; ; ; # ss𑓃
+︒‌ヶ䒩.ꡪ; ; [C1, P1, V6]; xn--0ug287dj0or48o.xn--gd9a; ; xn--qekw60dns9k.xn--gd9a; [P1, V6] # ︒ヶ䒩.ꡪ
+。‌ヶ䒩.ꡪ; .‌ヶ䒩.ꡪ; [C1, X4_2]; .xn--0ug287dj0o.xn--gd9a; [C1, A4_2]; .xn--qekw60d.xn--gd9a; [A4_2] # .ヶ䒩.ꡪ
+.xn--qekw60d.xn--gd9a; .ヶ䒩.ꡪ; [X4_2]; .xn--qekw60d.xn--gd9a; [A4_2]; ; # .ヶ䒩.ꡪ
+.xn--0ug287dj0o.xn--gd9a; .‌ヶ䒩.ꡪ; [C1, X4_2]; .xn--0ug287dj0o.xn--gd9a; [C1, A4_2]; ; # .ヶ䒩.ꡪ
+xn--qekw60dns9k.xn--gd9a; ︒ヶ䒩.ꡪ; [V6]; xn--qekw60dns9k.xn--gd9a; ; ; # ︒ヶ䒩.ꡪ
+xn--0ug287dj0or48o.xn--gd9a; ︒‌ヶ䒩.ꡪ; [C1, V6]; xn--0ug287dj0or48o.xn--gd9a; ; ; # ︒ヶ䒩.ꡪ
+xn--qekw60d.xn--gd9a; ヶ䒩.ꡪ; ; xn--qekw60d.xn--gd9a; ; ; # ヶ䒩.ꡪ
+ヶ䒩.ꡪ; ; ; xn--qekw60d.xn--gd9a; ; ; # ヶ䒩.ꡪ
+‌⒈𤮍.󢓋᩠; ; [C1, P1, V6]; xn--0ug88o7471d.xn--jof45148n; ; xn--tshw462r.xn--jof45148n; [P1, V6] # ⒈𤮍.᩠
+‌1.𤮍.󢓋᩠; ; [C1, P1, V6]; xn--1-rgn.xn--4x6j.xn--jof45148n; ; 1.xn--4x6j.xn--jof45148n; [P1, V6] # 1.𤮍.᩠
+1.xn--4x6j.xn--jof45148n; 1.𤮍.󢓋᩠; [V6]; 1.xn--4x6j.xn--jof45148n; ; ; # 1.𤮍.᩠
+xn--1-rgn.xn--4x6j.xn--jof45148n; ‌1.𤮍.󢓋᩠; [C1, V6]; xn--1-rgn.xn--4x6j.xn--jof45148n; ; ; # 1.𤮍.᩠
+xn--tshw462r.xn--jof45148n; ⒈𤮍.󢓋᩠; [V6]; xn--tshw462r.xn--jof45148n; ; ; # ⒈𤮍.᩠
+xn--0ug88o7471d.xn--jof45148n; ‌⒈𤮍.󢓋᩠; [C1, V6]; xn--0ug88o7471d.xn--jof45148n; ; ; # ⒈𤮍.᩠
+⒈‌𐫓󠀺。᩠񤰵‍; ⒈‌𐫓󠀺.᩠񤰵‍; [B1, C1, C2, P1, V5, V6]; xn--0ug78ol75wzcx4i.xn--jof95xex98m; ; xn--tsh4435fk263g.xn--jofz5294e; [B1, P1, V5, V6] # ⒈𐫓.᩠
+1.‌𐫓󠀺。᩠񤰵‍; 1.‌𐫓󠀺.᩠񤰵‍; [B1, C1, C2, P1, V5, V6]; 1.xn--0ug8853gk263g.xn--jof95xex98m; ; 1.xn--8w9c40377c.xn--jofz5294e; [B1, B3, P1, V5, V6] # 1.𐫓.᩠
+1.xn--8w9c40377c.xn--jofz5294e; 1.𐫓󠀺.᩠񤰵; [B1, B3, V5, V6]; 1.xn--8w9c40377c.xn--jofz5294e; ; ; # 1.𐫓.᩠
+1.xn--0ug8853gk263g.xn--jof95xex98m; 1.‌𐫓󠀺.᩠񤰵‍; [B1, C1, C2, V5, V6]; 1.xn--0ug8853gk263g.xn--jof95xex98m; ; ; # 1.𐫓.᩠
+xn--tsh4435fk263g.xn--jofz5294e; ⒈𐫓󠀺.᩠񤰵; [B1, V5, V6]; xn--tsh4435fk263g.xn--jofz5294e; ; ; # ⒈𐫓.᩠
+xn--0ug78ol75wzcx4i.xn--jof95xex98m; ⒈‌𐫓󠀺.᩠񤰵‍; [B1, C1, C2, V5, V6]; xn--0ug78ol75wzcx4i.xn--jof95xex98m; ; ; # ⒈𐫓.᩠
+𝅵。𝟫𞀈䬺⒈; 𝅵.9𞀈䬺⒈; [P1, V6]; xn--3f1h.xn--9-ecp936non25a; ; ; # .9𞀈䬺⒈
+𝅵。9𞀈䬺1.; 𝅵.9𞀈䬺1.; [P1, V6]; xn--3f1h.xn--91-030c1650n.; ; ; # .9𞀈䬺1.
+xn--3f1h.xn--91-030c1650n.; 𝅵.9𞀈䬺1.; [V6]; xn--3f1h.xn--91-030c1650n.; ; ; # .9𞀈䬺1.
+xn--3f1h.xn--9-ecp936non25a; 𝅵.9𞀈䬺⒈; [V6]; xn--3f1h.xn--9-ecp936non25a; ; ; # .9𞀈䬺⒈
+򡼺≯。盚ص; 򡼺≯.盚ص; [B5, B6, P1, V6]; xn--hdh30181h.xn--0gb7878c; ; ; # ≯.盚ص
+򡼺≯。盚ص; 򡼺≯.盚ص; [B5, B6, P1, V6]; xn--hdh30181h.xn--0gb7878c; ; ; # ≯.盚ص
+xn--hdh30181h.xn--0gb7878c; 򡼺≯.盚ص; [B5, B6, V6]; xn--hdh30181h.xn--0gb7878c; ; ; # ≯.盚ص
+-񿰭ִ。-󠁊𐢸≯; -񿰭ִ.-󠁊𐢸≯; [B1, P1, V3, V6]; xn----fgc06667m.xn----pgoy615he5y4i; ; ; # -ִ.-≯
+-񿰭ִ。-󠁊𐢸≯; -񿰭ִ.-󠁊𐢸≯; [B1, P1, V3, V6]; xn----fgc06667m.xn----pgoy615he5y4i; ; ; # -ִ.-≯
+xn----fgc06667m.xn----pgoy615he5y4i; -񿰭ִ.-󠁊𐢸≯; [B1, V3, V6]; xn----fgc06667m.xn----pgoy615he5y4i; ; ; # -ִ.-≯
+󿭓᭄‌੍.𐭛񳋔; 󿭓᭄‌੍.𐭛񳋔; [B2, B3, B6, P1, V6]; xn--ybc997f6rd2n772c.xn--409c6100y; ; xn--ybc997fb5881a.xn--409c6100y; [B2, B3, P1, V6] # ᭄੍.𐭛
+󿭓᭄‌੍.𐭛񳋔; ; [B2, B3, B6, P1, V6]; xn--ybc997f6rd2n772c.xn--409c6100y; ; xn--ybc997fb5881a.xn--409c6100y; [B2, B3, P1, V6] # ᭄੍.𐭛
+xn--ybc997fb5881a.xn--409c6100y; 󿭓᭄੍.𐭛񳋔; [B2, B3, V6]; xn--ybc997fb5881a.xn--409c6100y; ; ; # ᭄੍.𐭛
+xn--ybc997f6rd2n772c.xn--409c6100y; 󿭓᭄‌੍.𐭛񳋔; [B2, B3, B6, V6]; xn--ybc997f6rd2n772c.xn--409c6100y; ; ; # ᭄੍.𐭛
+⾇.ٽ𞤴ڻ‍; 舛.ٽ𞤴ڻ‍; [B3, C2]; xn--8c1a.xn--2ib8jv19e6413b; ; xn--8c1a.xn--2ib8jn539l; [] # 舛.ٽ𞤴ڻ
+舛.ٽ𞤴ڻ‍; ; [B3, C2]; xn--8c1a.xn--2ib8jv19e6413b; ; xn--8c1a.xn--2ib8jn539l; [] # 舛.ٽ𞤴ڻ
+舛.ٽ𞤒ڻ‍; 舛.ٽ𞤴ڻ‍; [B3, C2]; xn--8c1a.xn--2ib8jv19e6413b; ; xn--8c1a.xn--2ib8jn539l; [] # 舛.ٽ𞤴ڻ
+xn--8c1a.xn--2ib8jn539l; 舛.ٽ𞤴ڻ; ; xn--8c1a.xn--2ib8jn539l; ; ; # 舛.ٽ𞤴ڻ
+舛.ٽ𞤴ڻ; ; ; xn--8c1a.xn--2ib8jn539l; ; ; # 舛.ٽ𞤴ڻ
+舛.ٽ𞤒ڻ; 舛.ٽ𞤴ڻ; ; xn--8c1a.xn--2ib8jn539l; ; ; # 舛.ٽ𞤴ڻ
+xn--8c1a.xn--2ib8jv19e6413b; 舛.ٽ𞤴ڻ‍; [B3, C2]; xn--8c1a.xn--2ib8jv19e6413b; ; ; # 舛.ٽ𞤴ڻ
+⾇.ٽ𞤒ڻ‍; 舛.ٽ𞤴ڻ‍; [B3, C2]; xn--8c1a.xn--2ib8jv19e6413b; ; xn--8c1a.xn--2ib8jn539l; [] # 舛.ٽ𞤴ڻ
+4򭆥。ݧ≯; 4򭆥.ݧ≯; [B1, B3, P1, V6]; xn--4-xn17i.xn--rpb459k; ; ; # 4.ݧ≯
+4򭆥。ݧ≯; 4򭆥.ݧ≯; [B1, B3, P1, V6]; xn--4-xn17i.xn--rpb459k; ; ; # 4.ݧ≯
+xn--4-xn17i.xn--rpb459k; 4򭆥.ݧ≯; [B1, B3, V6]; xn--4-xn17i.xn--rpb459k; ; ; # 4.ݧ≯
+𲔏𞫨񺿂硲.ڭ; 𲔏𞫨񺿂硲.ڭ; [B5, P1, V6]; xn--lcz1610fn78gk609a.xn--gkb; ; ; # 硲.ڭ
+𲔏𞫨񺿂硲.ڭ; ; [B5, P1, V6]; xn--lcz1610fn78gk609a.xn--gkb; ; ; # 硲.ڭ
+xn--lcz1610fn78gk609a.xn--gkb; 𲔏𞫨񺿂硲.ڭ; [B5, V6]; xn--lcz1610fn78gk609a.xn--gkb; ; ; # 硲.ڭ
+‌.︈٦Ⴆ℮; ‌.٦Ⴆ℮; [B1, C1, P1, V6]; xn--0ug.xn--fib263c0yn; ; .xn--fib263c0yn; [B1, P1, V6, A4_2] # .٦Ⴆ℮
+‌.︈٦ⴆ℮; ‌.٦ⴆ℮; [B1, C1]; xn--0ug.xn--fib628k4li; ; .xn--fib628k4li; [B1, A4_2] # .٦ⴆ℮
+.xn--fib628k4li; .٦ⴆ℮; [B1, X4_2]; .xn--fib628k4li; [B1, A4_2]; ; # .٦ⴆ℮
+xn--0ug.xn--fib628k4li; ‌.٦ⴆ℮; [B1, C1]; xn--0ug.xn--fib628k4li; ; ; # .٦ⴆ℮
+.xn--fib263c0yn; .٦Ⴆ℮; [B1, V6, X4_2]; .xn--fib263c0yn; [B1, V6, A4_2]; ; # .٦Ⴆ℮
+xn--0ug.xn--fib263c0yn; ‌.٦Ⴆ℮; [B1, C1, V6]; xn--0ug.xn--fib263c0yn; ; ; # .٦Ⴆ℮
+ڣ.്‍Ϟ; ڣ.്‍ϟ; [B1, V5]; xn--5jb.xn--xya149bpvp; ; xn--5jb.xn--xya149b; # ڣ.്ϟ
+ڣ.്‍Ϟ; ڣ.്‍ϟ; [B1, V5]; xn--5jb.xn--xya149bpvp; ; xn--5jb.xn--xya149b; # ڣ.്ϟ
+ڣ.്‍ϟ; ; [B1, V5]; xn--5jb.xn--xya149bpvp; ; xn--5jb.xn--xya149b; # ڣ.്ϟ
+xn--5jb.xn--xya149b; ڣ.്ϟ; [B1, V5]; xn--5jb.xn--xya149b; ; ; # ڣ.്ϟ
+xn--5jb.xn--xya149bpvp; ڣ.്‍ϟ; [B1, V5]; xn--5jb.xn--xya149bpvp; ; ; # ڣ.്ϟ
+ڣ.്‍ϟ; ڣ.്‍ϟ; [B1, V5]; xn--5jb.xn--xya149bpvp; ; xn--5jb.xn--xya149b; # ڣ.്ϟ
+‌𞸇𑘿。أ𐮂-腍; ‌ح𑘿.أ𐮂-腍; [B1, B2, B3, C1]; xn--sgb953kmi8o.xn----qmc5075grs9e; ; xn--sgb4140l.xn----qmc5075grs9e; [B2, B3] # ح𑘿.أ𐮂-腍
+‌𞸇𑘿。أ𐮂-腍; ‌ح𑘿.أ𐮂-腍; [B1, B2, B3, C1]; xn--sgb953kmi8o.xn----qmc5075grs9e; ; xn--sgb4140l.xn----qmc5075grs9e; [B2, B3] # ح𑘿.أ𐮂-腍
+‌ح𑘿。أ𐮂-腍; ‌ح𑘿.أ𐮂-腍; [B1, B2, B3, C1]; xn--sgb953kmi8o.xn----qmc5075grs9e; ; xn--sgb4140l.xn----qmc5075grs9e; [B2, B3] # ح𑘿.أ𐮂-腍
+‌ح𑘿。أ𐮂-腍; ‌ح𑘿.أ𐮂-腍; [B1, B2, B3, C1]; xn--sgb953kmi8o.xn----qmc5075grs9e; ; xn--sgb4140l.xn----qmc5075grs9e; [B2, B3] # ح𑘿.أ𐮂-腍
+xn--sgb4140l.xn----qmc5075grs9e; ح𑘿.أ𐮂-腍; [B2, B3]; xn--sgb4140l.xn----qmc5075grs9e; ; ; # ح𑘿.أ𐮂-腍
+xn--sgb953kmi8o.xn----qmc5075grs9e; ‌ح𑘿.أ𐮂-腍; [B1, B2, B3, C1]; xn--sgb953kmi8o.xn----qmc5075grs9e; ; ; # ح𑘿.أ𐮂-腍
+-򭷙٫纛。𝟛񭤇🄅; -򭷙٫纛.3񭤇🄅; [B1, P1, V3, V6]; xn----vqc8143g0tt4i.xn--3-os1sn476y; ; ; # -٫纛.3🄅
+-򭷙٫纛。3񭤇4,; -򭷙٫纛.3񭤇4,; [B1, P1, V3, V6]; xn----vqc8143g0tt4i.xn--34,-8787l; ; ; # -٫纛.34,
+xn----vqc8143g0tt4i.xn--34,-8787l; -򭷙٫纛.3񭤇4,; [B1, P1, V3, V6]; xn----vqc8143g0tt4i.xn--34,-8787l; ; ; # -٫纛.34,
+xn----vqc8143g0tt4i.xn--3-os1sn476y; -򭷙٫纛.3񭤇🄅; [B1, V3, V6]; xn----vqc8143g0tt4i.xn--3-os1sn476y; ; ; # -٫纛.3🄅
+🔔.Ⴂߌ்𐋮; 🔔.Ⴂߌ்𐋮; [B1, B5, P1, V6]; xn--nv8h.xn--nsb46r83e8112a; ; ; # 🔔.Ⴂߌ்𐋮
+🔔.Ⴂߌ்𐋮; ; [B1, B5, P1, V6]; xn--nv8h.xn--nsb46r83e8112a; ; ; # 🔔.Ⴂߌ்𐋮
+🔔.ⴂߌ்𐋮; ; [B1, B5]; xn--nv8h.xn--nsb46rvz1b222p; ; ; # 🔔.ⴂߌ்𐋮
+xn--nv8h.xn--nsb46rvz1b222p; 🔔.ⴂߌ்𐋮; [B1, B5]; xn--nv8h.xn--nsb46rvz1b222p; ; ; # 🔔.ⴂߌ்𐋮
+xn--nv8h.xn--nsb46r83e8112a; 🔔.Ⴂߌ்𐋮; [B1, B5, V6]; xn--nv8h.xn--nsb46r83e8112a; ; ; # 🔔.Ⴂߌ்𐋮
+🔔.ⴂߌ்𐋮; 🔔.ⴂߌ்𐋮; [B1, B5]; xn--nv8h.xn--nsb46rvz1b222p; ; ; # 🔔.ⴂߌ்𐋮
+軥ڳ.-𖬵; ; [B1, B5, B6, V3]; xn--mkb5480e.xn----6u5m; ; ; # 軥ڳ.-𖬵
+xn--mkb5480e.xn----6u5m; 軥ڳ.-𖬵; [B1, B5, B6, V3]; xn--mkb5480e.xn----6u5m; ; ; # 軥ڳ.-𖬵
+𐹤ߊڶ.𐨂-; ; [B1, V3, V5]; xn--pkb56cn614d.xn----974i; ; ; # 𐹤ߊڶ.𐨂-
+xn--pkb56cn614d.xn----974i; 𐹤ߊڶ.𐨂-; [B1, V3, V5]; xn--pkb56cn614d.xn----974i; ; ; # 𐹤ߊڶ.𐨂-
+-󠅱0。៏᷽톇십; -0.៏᷽톇십; [V3, V5]; -0.xn--r4e872ah77nghm; ; ; # -0.៏᷽톇십
+-󠅱0。៏᷽톇십; -0.៏᷽톇십; [V3, V5]; -0.xn--r4e872ah77nghm; ; ; # -0.៏᷽톇십
+-󠅱0。៏᷽톇십; -0.៏᷽톇십; [V3, V5]; -0.xn--r4e872ah77nghm; ; ; # -0.៏᷽톇십
+-󠅱0。៏᷽톇십; -0.៏᷽톇십; [V3, V5]; -0.xn--r4e872ah77nghm; ; ; # -0.៏᷽톇십
+-0.xn--r4e872ah77nghm; -0.៏᷽톇십; [V3, V5]; -0.xn--r4e872ah77nghm; ; ; # -0.៏᷽톇십
+ꡰ︒--。៌靈𐹢񘳮; ꡰ︒--.៌靈𐹢񘳮; [B1, B6, P1, V2, V3, V5, V6]; xn-----bk9hu24z.xn--o4e6836dpxudz0v1c; ; ; # ꡰ︒--.៌靈𐹢
+ꡰ。--。៌靈𐹢񘳮; ꡰ.--.៌靈𐹢񘳮; [B1, P1, V3, V5, V6]; xn--md9a.--.xn--o4e6836dpxudz0v1c; ; ; # ꡰ.--.៌靈𐹢
+xn--md9a.--.xn--o4e6836dpxudz0v1c; ꡰ.--.៌靈𐹢񘳮; [B1, V3, V5, V6]; xn--md9a.--.xn--o4e6836dpxudz0v1c; ; ; # ꡰ.--.៌靈𐹢
+xn-----bk9hu24z.xn--o4e6836dpxudz0v1c; ꡰ︒--.៌靈𐹢񘳮; [B1, B6, V2, V3, V5, V6]; xn-----bk9hu24z.xn--o4e6836dpxudz0v1c; ; ; # ꡰ︒--.៌靈𐹢
+ᅟႿႵრ。୍; ᅟႿႵრ.୍; [P1, V5, V6]; xn--tndt4hvw.xn--9ic; ; ; # ႿႵრ.୍
+ᅟႿႵრ。୍; ᅟႿႵრ.୍; [P1, V5, V6]; xn--tndt4hvw.xn--9ic; ; ; # ႿႵრ.୍
+ᅟⴟⴕრ。୍; ᅟⴟⴕრ.୍; [P1, V5, V6]; xn--1od7wz74eeb.xn--9ic; ; ; # ⴟⴕრ.୍
+ᅟႿႵᲠ。୍; ᅟႿႵრ.୍; [P1, V5, V6]; xn--tndt4hvw.xn--9ic; ; ; # ႿႵრ.୍
+xn--tndt4hvw.xn--9ic; ᅟႿႵრ.୍; [V5, V6]; xn--tndt4hvw.xn--9ic; ; ; # ႿႵრ.୍
+xn--1od7wz74eeb.xn--9ic; ᅟⴟⴕრ.୍; [V5, V6]; xn--1od7wz74eeb.xn--9ic; ; ; # ⴟⴕრ.୍
+ᅟⴟⴕრ。୍; ᅟⴟⴕრ.୍; [P1, V5, V6]; xn--1od7wz74eeb.xn--9ic; ; ; # ⴟⴕრ.୍
+ᅟႿႵᲠ。୍; ᅟႿႵრ.୍; [P1, V5, V6]; xn--tndt4hvw.xn--9ic; ; ; # ႿႵრ.୍
+ᅟႿⴕრ。୍; ᅟႿⴕრ.୍; [P1, V5, V6]; xn--3nd0etsm92g.xn--9ic; ; ; # Ⴟⴕრ.୍
+xn--3nd0etsm92g.xn--9ic; ᅟႿⴕრ.୍; [V5, V6]; xn--3nd0etsm92g.xn--9ic; ; ; # Ⴟⴕრ.୍
+ᅟႿⴕრ。୍; ᅟႿⴕრ.୍; [P1, V5, V6]; xn--3nd0etsm92g.xn--9ic; ; ; # Ⴟⴕრ.୍
+🄃𐹠.٤󠅇; 🄃𐹠.٤; [B1, P1, V6]; xn--7n0d1189a.xn--dib; ; ; # 🄃𐹠.٤
+2,𐹠.٤󠅇; 2,𐹠.٤; [B1, P1, V6]; xn--2,-5g3o.xn--dib; ; ; # 2,𐹠.٤
+xn--2,-5g3o.xn--dib; 2,𐹠.٤; [B1, P1, V6]; xn--2,-5g3o.xn--dib; ; ; # 2,𐹠.٤
+xn--7n0d1189a.xn--dib; 🄃𐹠.٤; [B1, V6]; xn--7n0d1189a.xn--dib; ; ; # 🄃𐹠.٤
+򻲼‌ﱛ.ߒࡈ᯳; 򻲼‌ذٰ.ߒࡈ᯳; [B2, B3, B5, B6, C1, P1, V6]; xn--vgb2kq00fl213y.xn--tsb0vz43c; ; xn--vgb2kp1223g.xn--tsb0vz43c; [B2, B3, B5, B6, P1, V6] # ذٰ.ߒࡈ᯳
+򻲼‌ذٰ.ߒࡈ᯳; ; [B2, B3, B5, B6, C1, P1, V6]; xn--vgb2kq00fl213y.xn--tsb0vz43c; ; xn--vgb2kp1223g.xn--tsb0vz43c; [B2, B3, B5, B6, P1, V6] # ذٰ.ߒࡈ᯳
+xn--vgb2kp1223g.xn--tsb0vz43c; 򻲼ذٰ.ߒࡈ᯳; [B2, B3, B5, B6, V6]; xn--vgb2kp1223g.xn--tsb0vz43c; ; ; # ذٰ.ߒࡈ᯳
+xn--vgb2kq00fl213y.xn--tsb0vz43c; 򻲼‌ذٰ.ߒࡈ᯳; [B2, B3, B5, B6, C1, V6]; xn--vgb2kq00fl213y.xn--tsb0vz43c; ; ; # ذٰ.ߒࡈ᯳
+‍‍𞵪‌。ᡘ𑲭឵; ‍‍𞵪‌.ᡘ𑲭឵; [B1, C1, C2, P1, V6]; xn--0ugba05538b.xn--03e93aq365d; ; xn--l96h.xn--03e93aq365d; [P1, V6] # .ᡘ𑲭
+xn--l96h.xn--03e93aq365d; 𞵪.ᡘ𑲭឵; [V6]; xn--l96h.xn--03e93aq365d; ; ; # .ᡘ𑲭
+xn--0ugba05538b.xn--03e93aq365d; ‍‍𞵪‌.ᡘ𑲭឵; [B1, C1, C2, V6]; xn--0ugba05538b.xn--03e93aq365d; ; ; # .ᡘ𑲭
+𞷻。⚄񗑇𑁿; 𞷻.⚄񗑇𑁿; [B1, P1, V6]; xn--qe7h.xn--c7h2966f7so4a; ; ; # .⚄𑁿
+xn--qe7h.xn--c7h2966f7so4a; 𞷻.⚄񗑇𑁿; [B1, V6]; xn--qe7h.xn--c7h2966f7so4a; ; ; # .⚄𑁿
+꣄≠.𞠨٧; ꣄≠.𞠨٧; [B1, P1, V5, V6]; xn--1chy504c.xn--gib1777v; ; ; # ꣄≠.𞠨٧
+꣄≠.𞠨٧; ꣄≠.𞠨٧; [B1, P1, V5, V6]; xn--1chy504c.xn--gib1777v; ; ; # ꣄≠.𞠨٧
+꣄≠.𞠨٧; ; [B1, P1, V5, V6]; xn--1chy504c.xn--gib1777v; ; ; # ꣄≠.𞠨٧
+꣄≠.𞠨٧; ꣄≠.𞠨٧; [B1, P1, V5, V6]; xn--1chy504c.xn--gib1777v; ; ; # ꣄≠.𞠨٧
+xn--1chy504c.xn--gib1777v; ꣄≠.𞠨٧; [B1, V5, V6]; xn--1chy504c.xn--gib1777v; ; ; # ꣄≠.𞠨٧
+𝟛꣄𝆪。꣪-; 3꣄𝆪.꣪-; [V3, V5]; xn--3-sl4eu679e.xn----xn4e; ; ; # 3꣄𝆪.꣪-
+𝟛꣄𝆪。꣪-; 3꣄𝆪.꣪-; [V3, V5]; xn--3-sl4eu679e.xn----xn4e; ; ; # 3꣄𝆪.꣪-
+3꣄𝆪。꣪-; 3꣄𝆪.꣪-; [V3, V5]; xn--3-sl4eu679e.xn----xn4e; ; ; # 3꣄𝆪.꣪-
+xn--3-sl4eu679e.xn----xn4e; 3꣄𝆪.꣪-; [V3, V5]; xn--3-sl4eu679e.xn----xn4e; ; ; # 3꣄𝆪.꣪-
+ݟᮢ်Ⴇ.4; ; [B1, B2, B3, P1, V6]; xn--jpb846bmjw88a.4; ; ; # ݟᮢ်Ⴇ.4
+ݟᮢ်ⴇ.4; ; [B1, B2, B3]; xn--jpb846bjzj7pr.4; ; ; # ݟᮢ်ⴇ.4
+xn--jpb846bjzj7pr.4; ݟᮢ်ⴇ.4; [B1, B2, B3]; xn--jpb846bjzj7pr.4; ; ; # ݟᮢ်ⴇ.4
+xn--jpb846bmjw88a.4; ݟᮢ်Ⴇ.4; [B1, B2, B3, V6]; xn--jpb846bmjw88a.4; ; ; # ݟᮢ်Ⴇ.4
+ᄹ。໊򠯤󠄞; ᄹ.໊򠯤; [P1, V5, V6]; xn--lrd.xn--s8c05302k; ; ; # ᄹ.໊
+ᄹ。໊򠯤󠄞; ᄹ.໊򠯤; [P1, V5, V6]; xn--lrd.xn--s8c05302k; ; ; # ᄹ.໊
+xn--lrd.xn--s8c05302k; ᄹ.໊򠯤; [V5, V6]; xn--lrd.xn--s8c05302k; ; ; # ᄹ.໊
+Ⴆ򻢩.󠆡︉𞤍; Ⴆ򻢩.𞤯; [P1, V6]; xn--end82983m.xn--ne6h; ; ; # Ⴆ.𞤯
+Ⴆ򻢩.󠆡︉𞤍; Ⴆ򻢩.𞤯; [P1, V6]; xn--end82983m.xn--ne6h; ; ; # Ⴆ.𞤯
+ⴆ򻢩.󠆡︉𞤯; ⴆ򻢩.𞤯; [P1, V6]; xn--xkjw3965g.xn--ne6h; ; ; # ⴆ.𞤯
+xn--xkjw3965g.xn--ne6h; ⴆ򻢩.𞤯; [V6]; xn--xkjw3965g.xn--ne6h; ; ; # ⴆ.𞤯
+xn--end82983m.xn--ne6h; Ⴆ򻢩.𞤯; [V6]; xn--end82983m.xn--ne6h; ; ; # Ⴆ.𞤯
+ⴆ򻢩.󠆡︉𞤯; ⴆ򻢩.𞤯; [P1, V6]; xn--xkjw3965g.xn--ne6h; ; ; # ⴆ.𞤯
+ⴆ򻢩.󠆡︉𞤍; ⴆ򻢩.𞤯; [P1, V6]; xn--xkjw3965g.xn--ne6h; ; ; # ⴆ.𞤯
+ⴆ򻢩.󠆡︉𞤍; ⴆ򻢩.𞤯; [P1, V6]; xn--xkjw3965g.xn--ne6h; ; ; # ⴆ.𞤯
+ßࠋ︒ٻ.帼F∬‌; ßࠋ︒ٻ.帼f∫∫‌; [B5, B6, C1, P1, V6]; xn--zca68zj8ac956c.xn--f-sgn48ga6997e; ; xn--ss-k0d31nu121d.xn--f-tcoa9162d; [B5, B6, P1, V6] # ßࠋ︒ٻ.帼f∫∫
+ßࠋ。ٻ.帼F∫∫‌; ßࠋ.ٻ.帼f∫∫‌; [B5, B6, C1]; xn--zca687a.xn--0ib.xn--f-sgn48ga6997e; ; xn--ss-uze.xn--0ib.xn--f-tcoa9162d; [B5, B6] # ßࠋ.ٻ.帼f∫∫
+ßࠋ。ٻ.帼f∫∫‌; ßࠋ.ٻ.帼f∫∫‌; [B5, B6, C1]; xn--zca687a.xn--0ib.xn--f-sgn48ga6997e; ; xn--ss-uze.xn--0ib.xn--f-tcoa9162d; [B5, B6] # ßࠋ.ٻ.帼f∫∫
+SSࠋ。ٻ.帼F∫∫‌; ssࠋ.ٻ.帼f∫∫‌; [B5, B6, C1]; xn--ss-uze.xn--0ib.xn--f-sgn48ga6997e; ; xn--ss-uze.xn--0ib.xn--f-tcoa9162d; [B5, B6] # ssࠋ.ٻ.帼f∫∫
+ssࠋ。ٻ.帼f∫∫‌; ssࠋ.ٻ.帼f∫∫‌; [B5, B6, C1]; xn--ss-uze.xn--0ib.xn--f-sgn48ga6997e; ; xn--ss-uze.xn--0ib.xn--f-tcoa9162d; [B5, B6] # ssࠋ.ٻ.帼f∫∫
+Ssࠋ。ٻ.帼F∫∫‌; ssࠋ.ٻ.帼f∫∫‌; [B5, B6, C1]; xn--ss-uze.xn--0ib.xn--f-sgn48ga6997e; ; xn--ss-uze.xn--0ib.xn--f-tcoa9162d; [B5, B6] # ssࠋ.ٻ.帼f∫∫
+xn--ss-uze.xn--0ib.xn--f-tcoa9162d; ssࠋ.ٻ.帼f∫∫; [B5, B6]; xn--ss-uze.xn--0ib.xn--f-tcoa9162d; ; ; # ssࠋ.ٻ.帼f∫∫
+xn--ss-uze.xn--0ib.xn--f-sgn48ga6997e; ssࠋ.ٻ.帼f∫∫‌; [B5, B6, C1]; xn--ss-uze.xn--0ib.xn--f-sgn48ga6997e; ; ; # ssࠋ.ٻ.帼f∫∫
+xn--zca687a.xn--0ib.xn--f-sgn48ga6997e; ßࠋ.ٻ.帼f∫∫‌; [B5, B6, C1]; xn--zca687a.xn--0ib.xn--f-sgn48ga6997e; ; ; # ßࠋ.ٻ.帼f∫∫
+ßࠋ︒ٻ.帼f∬‌; ßࠋ︒ٻ.帼f∫∫‌; [B5, B6, C1, P1, V6]; xn--zca68zj8ac956c.xn--f-sgn48ga6997e; ; xn--ss-k0d31nu121d.xn--f-tcoa9162d; [B5, B6, P1, V6] # ßࠋ︒ٻ.帼f∫∫
+SSࠋ︒ٻ.帼F∬‌; ssࠋ︒ٻ.帼f∫∫‌; [B5, B6, C1, P1, V6]; xn--ss-k0d31nu121d.xn--f-sgn48ga6997e; ; xn--ss-k0d31nu121d.xn--f-tcoa9162d; [B5, B6, P1, V6] # ssࠋ︒ٻ.帼f∫∫
+ssࠋ︒ٻ.帼f∬‌; ssࠋ︒ٻ.帼f∫∫‌; [B5, B6, C1, P1, V6]; xn--ss-k0d31nu121d.xn--f-sgn48ga6997e; ; xn--ss-k0d31nu121d.xn--f-tcoa9162d; [B5, B6, P1, V6] # ssࠋ︒ٻ.帼f∫∫
+Ssࠋ︒ٻ.帼F∬‌; ssࠋ︒ٻ.帼f∫∫‌; [B5, B6, C1, P1, V6]; xn--ss-k0d31nu121d.xn--f-sgn48ga6997e; ; xn--ss-k0d31nu121d.xn--f-tcoa9162d; [B5, B6, P1, V6] # ssࠋ︒ٻ.帼f∫∫
+xn--ss-k0d31nu121d.xn--f-tcoa9162d; ssࠋ︒ٻ.帼f∫∫; [B5, B6, V6]; xn--ss-k0d31nu121d.xn--f-tcoa9162d; ; ; # ssࠋ︒ٻ.帼f∫∫
+xn--ss-k0d31nu121d.xn--f-sgn48ga6997e; ssࠋ︒ٻ.帼f∫∫‌; [B5, B6, C1, V6]; xn--ss-k0d31nu121d.xn--f-sgn48ga6997e; ; ; # ssࠋ︒ٻ.帼f∫∫
+xn--zca68zj8ac956c.xn--f-sgn48ga6997e; ßࠋ︒ٻ.帼f∫∫‌; [B5, B6, C1, V6]; xn--zca68zj8ac956c.xn--f-sgn48ga6997e; ; ; # ßࠋ︒ٻ.帼f∫∫
+󘪗。𐹴𞨌‍; 󘪗.𐹴𞨌‍; [B1, C2, P1, V6]; xn--8l83e.xn--1ug4105gsxwf; ; xn--8l83e.xn--so0dw168a; [B1, P1, V6] # .𐹴
+󘪗。𐹴𞨌‍; 󘪗.𐹴𞨌‍; [B1, C2, P1, V6]; xn--8l83e.xn--1ug4105gsxwf; ; xn--8l83e.xn--so0dw168a; [B1, P1, V6] # .𐹴
+xn--8l83e.xn--so0dw168a; 󘪗.𐹴𞨌; [B1, V6]; xn--8l83e.xn--so0dw168a; ; ; # .𐹴
+xn--8l83e.xn--1ug4105gsxwf; 󘪗.𐹴𞨌‍; [B1, C2, V6]; xn--8l83e.xn--1ug4105gsxwf; ; ; # .𐹴
+񗛨.򅟢𝟨꣄; 񗛨.򅟢6꣄; [P1, V6]; xn--mi60a.xn--6-sl4es8023c; ; ; # .6꣄
+񗛨.򅟢6꣄; ; [P1, V6]; xn--mi60a.xn--6-sl4es8023c; ; ; # .6꣄
+xn--mi60a.xn--6-sl4es8023c; 񗛨.򅟢6꣄; [V6]; xn--mi60a.xn--6-sl4es8023c; ; ; # .6꣄
+᪲ﶎ。-۹ႱႨ; ᪲مخج.-۹ႱႨ; [B1, P1, V3, V5, V6]; xn--rgbd2e831i.xn----zyc155e9a; ; ; # ᪲مخج.-۹ႱႨ
+᪲مخج。-۹ႱႨ; ᪲مخج.-۹ႱႨ; [B1, P1, V3, V5, V6]; xn--rgbd2e831i.xn----zyc155e9a; ; ; # ᪲مخج.-۹ႱႨ
+᪲مخج。-۹ⴑⴈ; ᪲مخج.-۹ⴑⴈ; [B1, V3, V5]; xn--rgbd2e831i.xn----zyc3430a9a; ; ; # ᪲مخج.-۹ⴑⴈ
+xn--rgbd2e831i.xn----zyc3430a9a; ᪲مخج.-۹ⴑⴈ; [B1, V3, V5]; xn--rgbd2e831i.xn----zyc3430a9a; ; ; # ᪲مخج.-۹ⴑⴈ
+xn--rgbd2e831i.xn----zyc155e9a; ᪲مخج.-۹ႱႨ; [B1, V3, V5, V6]; xn--rgbd2e831i.xn----zyc155e9a; ; ; # ᪲مخج.-۹ႱႨ
+᪲ﶎ。-۹ⴑⴈ; ᪲مخج.-۹ⴑⴈ; [B1, V3, V5]; xn--rgbd2e831i.xn----zyc3430a9a; ; ; # ᪲مخج.-۹ⴑⴈ
+᪲مخج。-۹Ⴑⴈ; ᪲مخج.-۹Ⴑⴈ; [B1, P1, V3, V5, V6]; xn--rgbd2e831i.xn----zyc875efr3a; ; ; # ᪲مخج.-۹Ⴑⴈ
+xn--rgbd2e831i.xn----zyc875efr3a; ᪲مخج.-۹Ⴑⴈ; [B1, V3, V5, V6]; xn--rgbd2e831i.xn----zyc875efr3a; ; ; # ᪲مخج.-۹Ⴑⴈ
+᪲ﶎ。-۹Ⴑⴈ; ᪲مخج.-۹Ⴑⴈ; [B1, P1, V3, V5, V6]; xn--rgbd2e831i.xn----zyc875efr3a; ; ; # ᪲مخج.-۹Ⴑⴈ
+𞤤.-ࢣ︒; 𞤤.-ࢣ︒; [B1, P1, V3, V6]; xn--ce6h.xn----cod7069p; ; ; # 𞤤.-ࢣ︒
+𞤤.-ࢣ。; 𞤤.-ࢣ.; [B1, V3]; xn--ce6h.xn----cod.; ; ; # 𞤤.-ࢣ.
+𞤂.-ࢣ。; 𞤤.-ࢣ.; [B1, V3]; xn--ce6h.xn----cod.; ; ; # 𞤤.-ࢣ.
+xn--ce6h.xn----cod.; 𞤤.-ࢣ.; [B1, V3]; xn--ce6h.xn----cod.; ; ; # 𞤤.-ࢣ.
+𞤂.-ࢣ︒; 𞤤.-ࢣ︒; [B1, P1, V3, V6]; xn--ce6h.xn----cod7069p; ; ; # 𞤤.-ࢣ︒
+xn--ce6h.xn----cod7069p; 𞤤.-ࢣ︒; [B1, V3, V6]; xn--ce6h.xn----cod7069p; ; ; # 𞤤.-ࢣ︒
+‌𐺨.࡙--; ; [B1, C1, V3, V5]; xn--0ug7905g.xn-----h6e; ; xn--9p0d.xn-----h6e; [B1, V3, V5] # 𐺨.࡙--
+xn--9p0d.xn-----h6e; 𐺨.࡙--; [B1, V3, V5]; xn--9p0d.xn-----h6e; ; ; # 𐺨.࡙--
+xn--0ug7905g.xn-----h6e; ‌𐺨.࡙--; [B1, C1, V3, V5]; xn--0ug7905g.xn-----h6e; ; ; # 𐺨.࡙--
+𐋸󮘋Ⴢ.Ⴁ; ; [P1, V6]; xn--6nd5215jr2u0h.xn--8md; ; ; # 𐋸Ⴢ.Ⴁ
+𐋸󮘋ⴢ.ⴁ; ; [P1, V6]; xn--qlj1559dr224h.xn--skj; ; ; # 𐋸ⴢ.ⴁ
+𐋸󮘋Ⴢ.ⴁ; ; [P1, V6]; xn--6nd5215jr2u0h.xn--skj; ; ; # 𐋸Ⴢ.ⴁ
+xn--6nd5215jr2u0h.xn--skj; 𐋸󮘋Ⴢ.ⴁ; [V6]; xn--6nd5215jr2u0h.xn--skj; ; ; # 𐋸Ⴢ.ⴁ
+xn--qlj1559dr224h.xn--skj; 𐋸󮘋ⴢ.ⴁ; [V6]; xn--qlj1559dr224h.xn--skj; ; ; # 𐋸ⴢ.ⴁ
+xn--6nd5215jr2u0h.xn--8md; 𐋸󮘋Ⴢ.Ⴁ; [V6]; xn--6nd5215jr2u0h.xn--8md; ; ; # 𐋸Ⴢ.Ⴁ
+񗑿꠆₄򩞆。𲩧󠒹ς; 񗑿꠆4򩞆.𲩧󠒹ς; [P1, V6]; xn--4-w93ej7463a9io5a.xn--3xa51142bk3f0d; ; xn--4-w93ej7463a9io5a.xn--4xa31142bk3f0d; # ꠆4.ς
+񗑿꠆4򩞆。𲩧󠒹ς; 񗑿꠆4򩞆.𲩧󠒹ς; [P1, V6]; xn--4-w93ej7463a9io5a.xn--3xa51142bk3f0d; ; xn--4-w93ej7463a9io5a.xn--4xa31142bk3f0d; # ꠆4.ς
+񗑿꠆4򩞆。𲩧󠒹Σ; 񗑿꠆4򩞆.𲩧󠒹σ; [P1, V6]; xn--4-w93ej7463a9io5a.xn--4xa31142bk3f0d; ; ; # ꠆4.σ
+񗑿꠆4򩞆。𲩧󠒹σ; 񗑿꠆4򩞆.𲩧󠒹σ; [P1, V6]; xn--4-w93ej7463a9io5a.xn--4xa31142bk3f0d; ; ; # ꠆4.σ
+xn--4-w93ej7463a9io5a.xn--4xa31142bk3f0d; 񗑿꠆4򩞆.𲩧󠒹σ; [V6]; xn--4-w93ej7463a9io5a.xn--4xa31142bk3f0d; ; ; # ꠆4.σ
+xn--4-w93ej7463a9io5a.xn--3xa51142bk3f0d; 񗑿꠆4򩞆.𲩧󠒹ς; [V6]; xn--4-w93ej7463a9io5a.xn--3xa51142bk3f0d; ; ; # ꠆4.ς
+񗑿꠆₄򩞆。𲩧󠒹Σ; 񗑿꠆4򩞆.𲩧󠒹σ; [P1, V6]; xn--4-w93ej7463a9io5a.xn--4xa31142bk3f0d; ; ; # ꠆4.σ
+񗑿꠆₄򩞆。𲩧󠒹σ; 񗑿꠆4򩞆.𲩧󠒹σ; [P1, V6]; xn--4-w93ej7463a9io5a.xn--4xa31142bk3f0d; ; ; # ꠆4.σ
+󠆀ܣ。ᷴݵ; ܣ.ᷴݵ; [B1, V5]; xn--tnb.xn--5pb136i; ; ; # ܣ.ᷴݵ
+xn--tnb.xn--5pb136i; ܣ.ᷴݵ; [B1, V5]; xn--tnb.xn--5pb136i; ; ; # ܣ.ᷴݵ
+𐹱ࡂ𝪨。𬼖Ⴑ‍; 𐹱ࡂ𝪨.𬼖Ⴑ‍; [B1, B6, C2, P1, V6]; xn--0vb1535kdb6e.xn--pnd879eqy33c; ; xn--0vb1535kdb6e.xn--pnd93707a; [B1, P1, V6] # 𐹱ࡂ𝪨.𬼖Ⴑ
+𐹱ࡂ𝪨。𬼖Ⴑ‍; 𐹱ࡂ𝪨.𬼖Ⴑ‍; [B1, B6, C2, P1, V6]; xn--0vb1535kdb6e.xn--pnd879eqy33c; ; xn--0vb1535kdb6e.xn--pnd93707a; [B1, P1, V6] # 𐹱ࡂ𝪨.𬼖Ⴑ
+𐹱ࡂ𝪨。𬼖ⴑ‍; 𐹱ࡂ𝪨.𬼖ⴑ‍; [B1, B6, C2]; xn--0vb1535kdb6e.xn--1ug742c5714c; ; xn--0vb1535kdb6e.xn--8kjz186s; [B1] # 𐹱ࡂ𝪨.𬼖ⴑ
+xn--0vb1535kdb6e.xn--8kjz186s; 𐹱ࡂ𝪨.𬼖ⴑ; [B1]; xn--0vb1535kdb6e.xn--8kjz186s; ; ; # 𐹱ࡂ𝪨.𬼖ⴑ
+xn--0vb1535kdb6e.xn--1ug742c5714c; 𐹱ࡂ𝪨.𬼖ⴑ‍; [B1, B6, C2]; xn--0vb1535kdb6e.xn--1ug742c5714c; ; ; # 𐹱ࡂ𝪨.𬼖ⴑ
+xn--0vb1535kdb6e.xn--pnd93707a; 𐹱ࡂ𝪨.𬼖Ⴑ; [B1, V6]; xn--0vb1535kdb6e.xn--pnd93707a; ; ; # 𐹱ࡂ𝪨.𬼖Ⴑ
+xn--0vb1535kdb6e.xn--pnd879eqy33c; 𐹱ࡂ𝪨.𬼖Ⴑ‍; [B1, B6, C2, V6]; xn--0vb1535kdb6e.xn--pnd879eqy33c; ; ; # 𐹱ࡂ𝪨.𬼖Ⴑ
+𐹱ࡂ𝪨。𬼖ⴑ‍; 𐹱ࡂ𝪨.𬼖ⴑ‍; [B1, B6, C2]; xn--0vb1535kdb6e.xn--1ug742c5714c; ; xn--0vb1535kdb6e.xn--8kjz186s; [B1] # 𐹱ࡂ𝪨.𬼖ⴑ
+᜔𐭪󠙘‍。-𐹴; ᜔𐭪󠙘‍.-𐹴; [B1, C2, P1, V3, V5, V6]; xn--fze807bso0spy14i.xn----c36i; ; xn--fze4126jujt0g.xn----c36i; [B1, P1, V3, V5, V6] # ᜔𐭪.-𐹴
+᜔𐭪󠙘‍。-𐹴; ᜔𐭪󠙘‍.-𐹴; [B1, C2, P1, V3, V5, V6]; xn--fze807bso0spy14i.xn----c36i; ; xn--fze4126jujt0g.xn----c36i; [B1, P1, V3, V5, V6] # ᜔𐭪.-𐹴
+xn--fze4126jujt0g.xn----c36i; ᜔𐭪󠙘.-𐹴; [B1, V3, V5, V6]; xn--fze4126jujt0g.xn----c36i; ; ; # ᜔𐭪.-𐹴
+xn--fze807bso0spy14i.xn----c36i; ᜔𐭪󠙘‍.-𐹴; [B1, C2, V3, V5, V6]; xn--fze807bso0spy14i.xn----c36i; ; ; # ᜔𐭪.-𐹴
+𾢬。ܩ︒쯙𝟧; 𾢬.ܩ︒쯙5; [B2, P1, V6]; xn--t92s.xn--5-p1c0712mm8rb; ; ; # .ܩ︒쯙5
+𾢬。ܩ︒쯙𝟧; 𾢬.ܩ︒쯙5; [B2, P1, V6]; xn--t92s.xn--5-p1c0712mm8rb; ; ; # .ܩ︒쯙5
+𾢬。ܩ。쯙5; 𾢬.ܩ.쯙5; [P1, V6]; xn--t92s.xn--znb.xn--5-y88f; ; ; # .ܩ.쯙5
+𾢬。ܩ。쯙5; 𾢬.ܩ.쯙5; [P1, V6]; xn--t92s.xn--znb.xn--5-y88f; ; ; # .ܩ.쯙5
+xn--t92s.xn--znb.xn--5-y88f; 𾢬.ܩ.쯙5; [V6]; xn--t92s.xn--znb.xn--5-y88f; ; ; # .ܩ.쯙5
+xn--t92s.xn--5-p1c0712mm8rb; 𾢬.ܩ︒쯙5; [B2, V6]; xn--t92s.xn--5-p1c0712mm8rb; ; ; # .ܩ︒쯙5
+𞤟-。ݢ≮뻐; 𞥁-.ݢ≮뻐; [B2, B3, P1, V3, V6]; xn----1j8r.xn--mpb269krv4i; ; ; # 𞥁-.ݢ≮뻐
+𞤟-。ݢ≮뻐; 𞥁-.ݢ≮뻐; [B2, B3, P1, V3, V6]; xn----1j8r.xn--mpb269krv4i; ; ; # 𞥁-.ݢ≮뻐
+𞥁-。ݢ≮뻐; 𞥁-.ݢ≮뻐; [B2, B3, P1, V3, V6]; xn----1j8r.xn--mpb269krv4i; ; ; # 𞥁-.ݢ≮뻐
+𞥁-。ݢ≮뻐; 𞥁-.ݢ≮뻐; [B2, B3, P1, V3, V6]; xn----1j8r.xn--mpb269krv4i; ; ; # 𞥁-.ݢ≮뻐
+xn----1j8r.xn--mpb269krv4i; 𞥁-.ݢ≮뻐; [B2, B3, V3, V6]; xn----1j8r.xn--mpb269krv4i; ; ; # 𞥁-.ݢ≮뻐
+𞥩-򊫠.ࢴ≠; 𞥩-򊫠.ࢴ≠; [B2, B3, P1, V6]; xn----cm8rp3609a.xn--9yb852k; ; ; # -.ࢴ≠
+𞥩-򊫠.ࢴ≠; 𞥩-򊫠.ࢴ≠; [B2, B3, P1, V6]; xn----cm8rp3609a.xn--9yb852k; ; ; # -.ࢴ≠
+𞥩-򊫠.ࢴ≠; ; [B2, B3, P1, V6]; xn----cm8rp3609a.xn--9yb852k; ; ; # -.ࢴ≠
+𞥩-򊫠.ࢴ≠; 𞥩-򊫠.ࢴ≠; [B2, B3, P1, V6]; xn----cm8rp3609a.xn--9yb852k; ; ; # -.ࢴ≠
+xn----cm8rp3609a.xn--9yb852k; 𞥩-򊫠.ࢴ≠; [B2, B3, V6]; xn----cm8rp3609a.xn--9yb852k; ; ; # -.ࢴ≠
+-񅂏ςႼ.١; -񅂏ςႼ.١; [B1, P1, V3, V6]; xn----ymb080hun11i.xn--9hb; ; xn----0mb770hun11i.xn--9hb; # -ςႼ.١
+-񅂏ςႼ.١; ; [B1, P1, V3, V6]; xn----ymb080hun11i.xn--9hb; ; xn----0mb770hun11i.xn--9hb; # -ςႼ.١
+-񅂏ςⴜ.١; ; [B1, P1, V3, V6]; xn----ymb2782aov12f.xn--9hb; ; xn----0mb9682aov12f.xn--9hb; # -ςⴜ.١
+-񅂏ΣႼ.١; -񅂏σႼ.١; [B1, P1, V3, V6]; xn----0mb770hun11i.xn--9hb; ; ; # -σႼ.١
+-񅂏σⴜ.١; ; [B1, P1, V3, V6]; xn----0mb9682aov12f.xn--9hb; ; ; # -σⴜ.١
+-񅂏Σⴜ.١; -񅂏σⴜ.١; [B1, P1, V3, V6]; xn----0mb9682aov12f.xn--9hb; ; ; # -σⴜ.١
+xn----0mb9682aov12f.xn--9hb; -񅂏σⴜ.١; [B1, V3, V6]; xn----0mb9682aov12f.xn--9hb; ; ; # -σⴜ.١
+xn----0mb770hun11i.xn--9hb; -񅂏σႼ.١; [B1, V3, V6]; xn----0mb770hun11i.xn--9hb; ; ; # -σႼ.١
+xn----ymb2782aov12f.xn--9hb; -񅂏ςⴜ.١; [B1, V3, V6]; xn----ymb2782aov12f.xn--9hb; ; ; # -ςⴜ.١
+xn----ymb080hun11i.xn--9hb; -񅂏ςႼ.١; [B1, V3, V6]; xn----ymb080hun11i.xn--9hb; ; ; # -ςႼ.١
+-񅂏ςⴜ.١; -񅂏ςⴜ.١; [B1, P1, V3, V6]; xn----ymb2782aov12f.xn--9hb; ; xn----0mb9682aov12f.xn--9hb; # -ςⴜ.١
+-񅂏ΣႼ.١; -񅂏σႼ.١; [B1, P1, V3, V6]; xn----0mb770hun11i.xn--9hb; ; ; # -σႼ.١
+-񅂏σⴜ.١; -񅂏σⴜ.١; [B1, P1, V3, V6]; xn----0mb9682aov12f.xn--9hb; ; ; # -σⴜ.١
+-񅂏Σⴜ.١; -񅂏σⴜ.١; [B1, P1, V3, V6]; xn----0mb9682aov12f.xn--9hb; ; ; # -σⴜ.١
+៊.‍𝟮𑀿; ៊.‍2𑀿; [C2, V5]; xn--m4e.xn--2-tgnv469h; ; xn--m4e.xn--2-ku7i; [V5] # ៊.2𑀿
+៊.‍2𑀿; ; [C2, V5]; xn--m4e.xn--2-tgnv469h; ; xn--m4e.xn--2-ku7i; [V5] # ៊.2𑀿
+xn--m4e.xn--2-ku7i; ៊.2𑀿; [V5]; xn--m4e.xn--2-ku7i; ; ; # ៊.2𑀿
+xn--m4e.xn--2-tgnv469h; ៊.‍2𑀿; [C2, V5]; xn--m4e.xn--2-tgnv469h; ; ; # ៊.2𑀿
+≯𝟖。᩠𐫓򟇑; ≯8.᩠𐫓򟇑; [B1, P1, V5, V6]; xn--8-ogo.xn--jof5303iv1z5d; ; ; # ≯8.᩠𐫓
+≯𝟖。᩠𐫓򟇑; ≯8.᩠𐫓򟇑; [B1, P1, V5, V6]; xn--8-ogo.xn--jof5303iv1z5d; ; ; # ≯8.᩠𐫓
+≯8。᩠𐫓򟇑; ≯8.᩠𐫓򟇑; [B1, P1, V5, V6]; xn--8-ogo.xn--jof5303iv1z5d; ; ; # ≯8.᩠𐫓
+≯8。᩠𐫓򟇑; ≯8.᩠𐫓򟇑; [B1, P1, V5, V6]; xn--8-ogo.xn--jof5303iv1z5d; ; ; # ≯8.᩠𐫓
+xn--8-ogo.xn--jof5303iv1z5d; ≯8.᩠𐫓򟇑; [B1, V5, V6]; xn--8-ogo.xn--jof5303iv1z5d; ; ; # ≯8.᩠𐫓
+𑲫Ↄ٤。‌; 𑲫Ↄ٤.‌; [B1, C1, P1, V5, V6]; xn--dib999kcy1p.xn--0ug; ; xn--dib999kcy1p.; [B1, P1, V5, V6] # 𑲫Ↄ٤.
+𑲫Ↄ٤。‌; 𑲫Ↄ٤.‌; [B1, C1, P1, V5, V6]; xn--dib999kcy1p.xn--0ug; ; xn--dib999kcy1p.; [B1, P1, V5, V6] # 𑲫Ↄ٤.
+𑲫ↄ٤。‌; 𑲫ↄ٤.‌; [B1, C1, V5]; xn--dib100l8x1p.xn--0ug; ; xn--dib100l8x1p.; [B1, V5] # 𑲫ↄ٤.
+xn--dib100l8x1p.; 𑲫ↄ٤.; [B1, V5]; xn--dib100l8x1p.; ; ; # 𑲫ↄ٤.
+xn--dib100l8x1p.xn--0ug; 𑲫ↄ٤.‌; [B1, C1, V5]; xn--dib100l8x1p.xn--0ug; ; ; # 𑲫ↄ٤.
+xn--dib999kcy1p.; 𑲫Ↄ٤.; [B1, V5, V6]; xn--dib999kcy1p.; ; ; # 𑲫Ↄ٤.
+xn--dib999kcy1p.xn--0ug; 𑲫Ↄ٤.‌; [B1, C1, V5, V6]; xn--dib999kcy1p.xn--0ug; ; ; # 𑲫Ↄ٤.
+𑲫ↄ٤。‌; 𑲫ↄ٤.‌; [B1, C1, V5]; xn--dib100l8x1p.xn--0ug; ; xn--dib100l8x1p.; [B1, V5] # 𑲫ↄ٤.
+ఀ𝟵‍ﲝ.‍ݐ⒈; ఀ9‍بح.‍ݐ⒈; [B1, C2, P1, V5, V6]; xn--9-1mcp570dl51a.xn--3ob977jmfd; ; xn--9-1mcp570d.xn--3ob470m; [B1, P1, V5, V6] # ఀ9بح.ݐ⒈
+ఀ9‍بح.‍ݐ1.; ; [B1, C2, V5]; xn--9-1mcp570dl51a.xn--1-x3c211q.; ; xn--9-1mcp570d.xn--1-x3c.; [B1, V5] # ఀ9بح.ݐ1.
+xn--9-1mcp570d.xn--1-x3c.; ఀ9بح.ݐ1.; [B1, V5]; xn--9-1mcp570d.xn--1-x3c.; ; ; # ఀ9بح.ݐ1.
+xn--9-1mcp570dl51a.xn--1-x3c211q.; ఀ9‍بح.‍ݐ1.; [B1, C2, V5]; xn--9-1mcp570dl51a.xn--1-x3c211q.; ; ; # ఀ9بح.ݐ1.
+xn--9-1mcp570d.xn--3ob470m; ఀ9بح.ݐ⒈; [B1, V5, V6]; xn--9-1mcp570d.xn--3ob470m; ; ; # ఀ9بح.ݐ⒈
+xn--9-1mcp570dl51a.xn--3ob977jmfd; ఀ9‍بح.‍ݐ⒈; [B1, C2, V5, V6]; xn--9-1mcp570dl51a.xn--3ob977jmfd; ; ; # ఀ9بح.ݐ⒈
+꫶。嬶ß葽; ꫶.嬶ß葽; [V5]; xn--2v9a.xn--zca7637b14za; ; xn--2v9a.xn--ss-q40dp97m; # ꫶.嬶ß葽
+꫶。嬶SS葽; ꫶.嬶ss葽; [V5]; xn--2v9a.xn--ss-q40dp97m; ; ; # ꫶.嬶ss葽
+꫶。嬶ss葽; ꫶.嬶ss葽; [V5]; xn--2v9a.xn--ss-q40dp97m; ; ; # ꫶.嬶ss葽
+꫶。嬶Ss葽; ꫶.嬶ss葽; [V5]; xn--2v9a.xn--ss-q40dp97m; ; ; # ꫶.嬶ss葽
+xn--2v9a.xn--ss-q40dp97m; ꫶.嬶ss葽; [V5]; xn--2v9a.xn--ss-q40dp97m; ; ; # ꫶.嬶ss葽
+xn--2v9a.xn--zca7637b14za; ꫶.嬶ß葽; [V5]; xn--2v9a.xn--zca7637b14za; ; ; # ꫶.嬶ß葽
+𑚶⒈。񞻡𐹺; 𑚶⒈.񞻡𐹺; [B5, B6, P1, V5, V6]; xn--tshz969f.xn--yo0d5914s; ; ; # 𑚶⒈.𐹺
+𑚶1.。񞻡𐹺; 𑚶1..񞻡𐹺; [B5, B6, P1, V5, V6, X4_2]; xn--1-3j0j..xn--yo0d5914s; [B5, B6, P1, V5, V6, A4_2]; ; # 𑚶1..𐹺
+xn--1-3j0j..xn--yo0d5914s; 𑚶1..񞻡𐹺; [B5, B6, V5, V6, X4_2]; xn--1-3j0j..xn--yo0d5914s; [B5, B6, V5, V6, A4_2]; ; # 𑚶1..𐹺
+xn--tshz969f.xn--yo0d5914s; 𑚶⒈.񞻡𐹺; [B5, B6, V5, V6]; xn--tshz969f.xn--yo0d5914s; ; ; # 𑚶⒈.𐹺
+𑜤︒≮.񚕽ט𞾩; 𑜤︒≮.񚕽ט𞾩; [B1, B5, B6, P1, V5, V6]; xn--gdh5267fdzpa.xn--deb0091w5q9u; ; ; # 𑜤︒≮.ט
+𑜤︒≮.񚕽ט𞾩; 𑜤︒≮.񚕽ט𞾩; [B1, B5, B6, P1, V5, V6]; xn--gdh5267fdzpa.xn--deb0091w5q9u; ; ; # 𑜤︒≮.ט
+𑜤。≮.񚕽ט𞾩; 𑜤.≮.񚕽ט𞾩; [B1, B3, B5, B6, P1, V5, V6]; xn--ci2d.xn--gdh.xn--deb0091w5q9u; ; ; # 𑜤.≮.ט
+𑜤。≮.񚕽ט𞾩; 𑜤.≮.񚕽ט𞾩; [B1, B3, B5, B6, P1, V5, V6]; xn--ci2d.xn--gdh.xn--deb0091w5q9u; ; ; # 𑜤.≮.ט
+xn--ci2d.xn--gdh.xn--deb0091w5q9u; 𑜤.≮.񚕽ט𞾩; [B1, B3, B5, B6, V5, V6]; xn--ci2d.xn--gdh.xn--deb0091w5q9u; ; ; # 𑜤.≮.ט
+xn--gdh5267fdzpa.xn--deb0091w5q9u; 𑜤︒≮.񚕽ט𞾩; [B1, B5, B6, V5, V6]; xn--gdh5267fdzpa.xn--deb0091w5q9u; ; ; # 𑜤︒≮.ט
+󠆋؃񏦤.⇁ς򏋈򺇥; ؃񏦤.⇁ς򏋈򺇥; [B1, P1, V6]; xn--lfb04106d.xn--3xa174mxv16m8moq; ; xn--lfb04106d.xn--4xa964mxv16m8moq; # .⇁ς
+󠆋؃񏦤.⇁Σ򏋈򺇥; ؃񏦤.⇁σ򏋈򺇥; [B1, P1, V6]; xn--lfb04106d.xn--4xa964mxv16m8moq; ; ; # .⇁σ
+󠆋؃񏦤.⇁σ򏋈򺇥; ؃񏦤.⇁σ򏋈򺇥; [B1, P1, V6]; xn--lfb04106d.xn--4xa964mxv16m8moq; ; ; # .⇁σ
+xn--lfb04106d.xn--4xa964mxv16m8moq; ؃񏦤.⇁σ򏋈򺇥; [B1, V6]; xn--lfb04106d.xn--4xa964mxv16m8moq; ; ; # .⇁σ
+xn--lfb04106d.xn--3xa174mxv16m8moq; ؃񏦤.⇁ς򏋈򺇥; [B1, V6]; xn--lfb04106d.xn--3xa174mxv16m8moq; ; ; # .⇁ς
+ς𑐽𵢈𑜫。𞬩‌𐫄; ς𑐽𵢈𑜫.𞬩‌𐫄; [C1, P1, V6]; xn--3xa4260lk3b8z15g.xn--0ug4653g2xzf; ; xn--4xa2260lk3b8z15g.xn--tw9ct349a; [P1, V6] # ς𑐽𑜫.𐫄
+ς𑐽𵢈𑜫。𞬩‌𐫄; ς𑐽𵢈𑜫.𞬩‌𐫄; [C1, P1, V6]; xn--3xa4260lk3b8z15g.xn--0ug4653g2xzf; ; xn--4xa2260lk3b8z15g.xn--tw9ct349a; [P1, V6] # ς𑐽𑜫.𐫄
+Σ𑐽𵢈𑜫。𞬩‌𐫄; σ𑐽𵢈𑜫.𞬩‌𐫄; [C1, P1, V6]; xn--4xa2260lk3b8z15g.xn--0ug4653g2xzf; ; xn--4xa2260lk3b8z15g.xn--tw9ct349a; [P1, V6] # σ𑐽𑜫.𐫄
+σ𑐽𵢈𑜫。𞬩‌𐫄; σ𑐽𵢈𑜫.𞬩‌𐫄; [C1, P1, V6]; xn--4xa2260lk3b8z15g.xn--0ug4653g2xzf; ; xn--4xa2260lk3b8z15g.xn--tw9ct349a; [P1, V6] # σ𑐽𑜫.𐫄
+xn--4xa2260lk3b8z15g.xn--tw9ct349a; σ𑐽𵢈𑜫.𞬩𐫄; [V6]; xn--4xa2260lk3b8z15g.xn--tw9ct349a; ; ; # σ𑐽𑜫.𐫄
+xn--4xa2260lk3b8z15g.xn--0ug4653g2xzf; σ𑐽𵢈𑜫.𞬩‌𐫄; [C1, V6]; xn--4xa2260lk3b8z15g.xn--0ug4653g2xzf; ; ; # σ𑐽𑜫.𐫄
+xn--3xa4260lk3b8z15g.xn--0ug4653g2xzf; ς𑐽𵢈𑜫.𞬩‌𐫄; [C1, V6]; xn--3xa4260lk3b8z15g.xn--0ug4653g2xzf; ; ; # ς𑐽𑜫.𐫄
+Σ𑐽𵢈𑜫。𞬩‌𐫄; σ𑐽𵢈𑜫.𞬩‌𐫄; [C1, P1, V6]; xn--4xa2260lk3b8z15g.xn--0ug4653g2xzf; ; xn--4xa2260lk3b8z15g.xn--tw9ct349a; [P1, V6] # σ𑐽𑜫.𐫄
+σ𑐽𵢈𑜫。𞬩‌𐫄; σ𑐽𵢈𑜫.𞬩‌𐫄; [C1, P1, V6]; xn--4xa2260lk3b8z15g.xn--0ug4653g2xzf; ; xn--4xa2260lk3b8z15g.xn--tw9ct349a; [P1, V6] # σ𑐽𑜫.𐫄
+-򵏽。-ﱌݛ; -򵏽.-نحݛ; [B1, P1, V3, V6]; xn----o452j.xn----cnc8e38c; ; ; # -.-نحݛ
+-򵏽。-نحݛ; -򵏽.-نحݛ; [B1, P1, V3, V6]; xn----o452j.xn----cnc8e38c; ; ; # -.-نحݛ
+xn----o452j.xn----cnc8e38c; -򵏽.-نحݛ; [B1, V3, V6]; xn----o452j.xn----cnc8e38c; ; ; # -.-نحݛ
+⺢򇺅𝟤。‍🚷; ⺢򇺅2.‍🚷; [C2, P1, V6]; xn--2-4jtr4282f.xn--1ugz946p; ; xn--2-4jtr4282f.xn--m78h; [P1, V6] # ⺢2.🚷
+⺢򇺅2。‍🚷; ⺢򇺅2.‍🚷; [C2, P1, V6]; xn--2-4jtr4282f.xn--1ugz946p; ; xn--2-4jtr4282f.xn--m78h; [P1, V6] # ⺢2.🚷
+xn--2-4jtr4282f.xn--m78h; ⺢򇺅2.🚷; [V6]; xn--2-4jtr4282f.xn--m78h; ; ; # ⺢2.🚷
+xn--2-4jtr4282f.xn--1ugz946p; ⺢򇺅2.‍🚷; [C2, V6]; xn--2-4jtr4282f.xn--1ugz946p; ; ; # ⺢2.🚷
+೸‍ⷾ𐹲。򤐶; ೸‍ⷾ𐹲.򤐶; [B5, B6, C2, P1, V6]; xn--hvc488g69j402t.xn--3e36c; ; xn--hvc220of37m.xn--3e36c; [B5, B6, P1, V6] # ⷾ𐹲.
+೸‍ⷾ𐹲。򤐶; ೸‍ⷾ𐹲.򤐶; [B5, B6, C2, P1, V6]; xn--hvc488g69j402t.xn--3e36c; ; xn--hvc220of37m.xn--3e36c; [B5, B6, P1, V6] # ⷾ𐹲.
+xn--hvc220of37m.xn--3e36c; ೸ⷾ𐹲.򤐶; [B5, B6, V6]; xn--hvc220of37m.xn--3e36c; ; ; # ⷾ𐹲.
+xn--hvc488g69j402t.xn--3e36c; ೸‍ⷾ𐹲.򤐶; [B5, B6, C2, V6]; xn--hvc488g69j402t.xn--3e36c; ; ; # ⷾ𐹲.
+𐹢.Ⴍ₉⁸; 𐹢.Ⴍ98; [B1, P1, V6]; xn--9n0d.xn--98-7ek; ; ; # 𐹢.Ⴍ98
+𐹢.Ⴍ98; ; [B1, P1, V6]; xn--9n0d.xn--98-7ek; ; ; # 𐹢.Ⴍ98
+𐹢.ⴍ98; ; [B1]; xn--9n0d.xn--98-u61a; ; ; # 𐹢.ⴍ98
+xn--9n0d.xn--98-u61a; 𐹢.ⴍ98; [B1]; xn--9n0d.xn--98-u61a; ; ; # 𐹢.ⴍ98
+xn--9n0d.xn--98-7ek; 𐹢.Ⴍ98; [B1, V6]; xn--9n0d.xn--98-7ek; ; ; # 𐹢.Ⴍ98
+𐹢.ⴍ₉⁸; 𐹢.ⴍ98; [B1]; xn--9n0d.xn--98-u61a; ; ; # 𐹢.ⴍ98
+‌͏。ß࣢⒚≯; ‌.ß࣢⒚≯; [B1, B5, B6, C1, P1, V6]; xn--0ug.xn--zca612bx9vo5b; ; .xn--ss-9if872xjjc; [B5, B6, P1, V6, A4_2] # .ß⒚≯
+‌͏。ß࣢⒚≯; ‌.ß࣢⒚≯; [B1, B5, B6, C1, P1, V6]; xn--0ug.xn--zca612bx9vo5b; ; .xn--ss-9if872xjjc; [B5, B6, P1, V6, A4_2] # .ß⒚≯
+‌͏。ß࣢19.≯; ‌.ß࣢19.≯; [B1, B5, C1, P1, V6]; xn--0ug.xn--19-fia813f.xn--hdh; ; .xn--ss19-w0i.xn--hdh; [B1, B5, P1, V6, A4_2] # .ß19.≯
+‌͏。ß࣢19.≯; ‌.ß࣢19.≯; [B1, B5, C1, P1, V6]; xn--0ug.xn--19-fia813f.xn--hdh; ; .xn--ss19-w0i.xn--hdh; [B1, B5, P1, V6, A4_2] # .ß19.≯
+‌͏。SS࣢19.≯; ‌.ss࣢19.≯; [B1, B5, C1, P1, V6]; xn--0ug.xn--ss19-w0i.xn--hdh; ; .xn--ss19-w0i.xn--hdh; [B1, B5, P1, V6, A4_2] # .ss19.≯
+‌͏。SS࣢19.≯; ‌.ss࣢19.≯; [B1, B5, C1, P1, V6]; xn--0ug.xn--ss19-w0i.xn--hdh; ; .xn--ss19-w0i.xn--hdh; [B1, B5, P1, V6, A4_2] # .ss19.≯
+‌͏。ss࣢19.≯; ‌.ss࣢19.≯; [B1, B5, C1, P1, V6]; xn--0ug.xn--ss19-w0i.xn--hdh; ; .xn--ss19-w0i.xn--hdh; [B1, B5, P1, V6, A4_2] # .ss19.≯
+‌͏。ss࣢19.≯; ‌.ss࣢19.≯; [B1, B5, C1, P1, V6]; xn--0ug.xn--ss19-w0i.xn--hdh; ; .xn--ss19-w0i.xn--hdh; [B1, B5, P1, V6, A4_2] # .ss19.≯
+‌͏。Ss࣢19.≯; ‌.ss࣢19.≯; [B1, B5, C1, P1, V6]; xn--0ug.xn--ss19-w0i.xn--hdh; ; .xn--ss19-w0i.xn--hdh; [B1, B5, P1, V6, A4_2] # .ss19.≯
+‌͏。Ss࣢19.≯; ‌.ss࣢19.≯; [B1, B5, C1, P1, V6]; xn--0ug.xn--ss19-w0i.xn--hdh; ; .xn--ss19-w0i.xn--hdh; [B1, B5, P1, V6, A4_2] # .ss19.≯
+.xn--ss19-w0i.xn--hdh; .ss࣢19.≯; [B1, B5, V6, X4_2]; .xn--ss19-w0i.xn--hdh; [B1, B5, V6, A4_2]; ; # .ss19.≯
+xn--0ug.xn--ss19-w0i.xn--hdh; ‌.ss࣢19.≯; [B1, B5, C1, V6]; xn--0ug.xn--ss19-w0i.xn--hdh; ; ; # .ss19.≯
+xn--0ug.xn--19-fia813f.xn--hdh; ‌.ß࣢19.≯; [B1, B5, C1, V6]; xn--0ug.xn--19-fia813f.xn--hdh; ; ; # .ß19.≯
+‌͏。SS࣢⒚≯; ‌.ss࣢⒚≯; [B1, B5, B6, C1, P1, V6]; xn--0ug.xn--ss-9if872xjjc; ; .xn--ss-9if872xjjc; [B5, B6, P1, V6, A4_2] # .ss⒚≯
+‌͏。SS࣢⒚≯; ‌.ss࣢⒚≯; [B1, B5, B6, C1, P1, V6]; xn--0ug.xn--ss-9if872xjjc; ; .xn--ss-9if872xjjc; [B5, B6, P1, V6, A4_2] # .ss⒚≯
+‌͏。ss࣢⒚≯; ‌.ss࣢⒚≯; [B1, B5, B6, C1, P1, V6]; xn--0ug.xn--ss-9if872xjjc; ; .xn--ss-9if872xjjc; [B5, B6, P1, V6, A4_2] # .ss⒚≯
+‌͏。ss࣢⒚≯; ‌.ss࣢⒚≯; [B1, B5, B6, C1, P1, V6]; xn--0ug.xn--ss-9if872xjjc; ; .xn--ss-9if872xjjc; [B5, B6, P1, V6, A4_2] # .ss⒚≯
+‌͏。Ss࣢⒚≯; ‌.ss࣢⒚≯; [B1, B5, B6, C1, P1, V6]; xn--0ug.xn--ss-9if872xjjc; ; .xn--ss-9if872xjjc; [B5, B6, P1, V6, A4_2] # .ss⒚≯
+‌͏。Ss࣢⒚≯; ‌.ss࣢⒚≯; [B1, B5, B6, C1, P1, V6]; xn--0ug.xn--ss-9if872xjjc; ; .xn--ss-9if872xjjc; [B5, B6, P1, V6, A4_2] # .ss⒚≯
+.xn--ss-9if872xjjc; .ss࣢⒚≯; [B5, B6, V6, X4_2]; .xn--ss-9if872xjjc; [B5, B6, V6, A4_2]; ; # .ss⒚≯
+xn--0ug.xn--ss-9if872xjjc; ‌.ss࣢⒚≯; [B1, B5, B6, C1, V6]; xn--0ug.xn--ss-9if872xjjc; ; ; # .ss⒚≯
+xn--0ug.xn--zca612bx9vo5b; ‌.ß࣢⒚≯; [B1, B5, B6, C1, V6]; xn--0ug.xn--zca612bx9vo5b; ; ; # .ß⒚≯
+‌𞥍ᡌ.𣃔; ‌𞥍ᡌ.𣃔; [B1, C1, P1, V6]; xn--c8e180bqz13b.xn--od1j; ; xn--c8e5919u.xn--od1j; [B2, B3, P1, V6] # ᡌ.𣃔
+‌𞥍ᡌ.𣃔; ; [B1, C1, P1, V6]; xn--c8e180bqz13b.xn--od1j; ; xn--c8e5919u.xn--od1j; [B2, B3, P1, V6] # ᡌ.𣃔
+xn--c8e5919u.xn--od1j; 𞥍ᡌ.𣃔; [B2, B3, V6]; xn--c8e5919u.xn--od1j; ; ; # ᡌ.𣃔
+xn--c8e180bqz13b.xn--od1j; ‌𞥍ᡌ.𣃔; [B1, C1, V6]; xn--c8e180bqz13b.xn--od1j; ; ; # ᡌ.𣃔
+ߐ򜬝-񡢬。ྠႻ𞷏𝆬; ߐ򜬝-񡢬.ྠႻ𞷏𝆬; [B1, B2, B3, P1, V5, V6]; xn----8bd11730jefvw.xn--wfd08cd265hgsxa; ; ; # ߐ-.ྠႻ𝆬
+ߐ򜬝-񡢬。ྠⴛ𞷏𝆬; ߐ򜬝-񡢬.ྠⴛ𞷏𝆬; [B1, B2, B3, P1, V5, V6]; xn----8bd11730jefvw.xn--wfd802mpm20agsxa; ; ; # ߐ-.ྠⴛ𝆬
+xn----8bd11730jefvw.xn--wfd802mpm20agsxa; ߐ򜬝-񡢬.ྠⴛ𞷏𝆬; [B1, B2, B3, V5, V6]; xn----8bd11730jefvw.xn--wfd802mpm20agsxa; ; ; # ߐ-.ྠⴛ𝆬
+xn----8bd11730jefvw.xn--wfd08cd265hgsxa; ߐ򜬝-񡢬.ྠႻ𞷏𝆬; [B1, B2, B3, V5, V6]; xn----8bd11730jefvw.xn--wfd08cd265hgsxa; ; ; # ߐ-.ྠႻ𝆬
+𝨥。⫟𑈾; 𝨥.⫟𑈾; [V5]; xn--n82h.xn--63iw010f; ; ; # 𝨥.⫟𑈾
+xn--n82h.xn--63iw010f; 𝨥.⫟𑈾; [V5]; xn--n82h.xn--63iw010f; ; ; # 𝨥.⫟𑈾
+⾛ݓ.Ⴕ𞠬؄‍; 走ݓ.Ⴕ𞠬؄‍; [B5, B6, C2, P1, V6]; xn--6ob9779d.xn--mfb785czmm0y85b; ; xn--6ob9779d.xn--mfb785ck569a; [B5, B6, P1, V6] # 走ݓ.Ⴕ𞠬
+走ݓ.Ⴕ𞠬؄‍; ; [B5, B6, C2, P1, V6]; xn--6ob9779d.xn--mfb785czmm0y85b; ; xn--6ob9779d.xn--mfb785ck569a; [B5, B6, P1, V6] # 走ݓ.Ⴕ𞠬
+走ݓ.ⴕ𞠬؄‍; ; [B5, B6, C2, P1, V6]; xn--6ob9779d.xn--mfb444k5gjt754b; ; xn--6ob9779d.xn--mfb511rxu80a; [B5, B6, P1, V6] # 走ݓ.ⴕ𞠬
+xn--6ob9779d.xn--mfb511rxu80a; 走ݓ.ⴕ𞠬؄; [B5, B6, V6]; xn--6ob9779d.xn--mfb511rxu80a; ; ; # 走ݓ.ⴕ𞠬
+xn--6ob9779d.xn--mfb444k5gjt754b; 走ݓ.ⴕ𞠬؄‍; [B5, B6, C2, V6]; xn--6ob9779d.xn--mfb444k5gjt754b; ; ; # 走ݓ.ⴕ𞠬
+xn--6ob9779d.xn--mfb785ck569a; 走ݓ.Ⴕ𞠬؄; [B5, B6, V6]; xn--6ob9779d.xn--mfb785ck569a; ; ; # 走ݓ.Ⴕ𞠬
+xn--6ob9779d.xn--mfb785czmm0y85b; 走ݓ.Ⴕ𞠬؄‍; [B5, B6, C2, V6]; xn--6ob9779d.xn--mfb785czmm0y85b; ; ; # 走ݓ.Ⴕ𞠬
+⾛ݓ.ⴕ𞠬؄‍; 走ݓ.ⴕ𞠬؄‍; [B5, B6, C2, P1, V6]; xn--6ob9779d.xn--mfb444k5gjt754b; ; xn--6ob9779d.xn--mfb511rxu80a; [B5, B6, P1, V6] # 走ݓ.ⴕ𞠬
+-ᢗ‌🄄.𑜢; ; [C1, P1, V3, V5, V6]; xn----pck312bx563c.xn--9h2d; ; xn----pck1820x.xn--9h2d; [P1, V3, V5, V6] # -ᢗ🄄.𑜢
+-ᢗ‌3,.𑜢; ; [C1, P1, V3, V5, V6]; xn---3,-3eu051c.xn--9h2d; ; xn---3,-3eu.xn--9h2d; [P1, V3, V5, V6] # -ᢗ3,.𑜢
+xn---3,-3eu.xn--9h2d; -ᢗ3,.𑜢; [P1, V3, V5, V6]; xn---3,-3eu.xn--9h2d; ; ; # -ᢗ3,.𑜢
+xn---3,-3eu051c.xn--9h2d; -ᢗ‌3,.𑜢; [C1, P1, V3, V5, V6]; xn---3,-3eu051c.xn--9h2d; ; ; # -ᢗ3,.𑜢
+xn----pck1820x.xn--9h2d; -ᢗ🄄.𑜢; [V3, V5, V6]; xn----pck1820x.xn--9h2d; ; ; # -ᢗ🄄.𑜢
+xn----pck312bx563c.xn--9h2d; -ᢗ‌🄄.𑜢; [C1, V3, V5, V6]; xn----pck312bx563c.xn--9h2d; ; ; # -ᢗ🄄.𑜢
+≠𐸁𹏁‌.Ⴚ򳄠; ; [B1, C1, P1, V6]; xn--0ug83gn618a21ov.xn--ynd49496l; ; xn--1ch2293gv3nr.xn--ynd49496l; [B1, P1, V6] # ≠.Ⴚ
+≠𐸁𹏁‌.Ⴚ򳄠; ≠𐸁𹏁‌.Ⴚ򳄠; [B1, C1, P1, V6]; xn--0ug83gn618a21ov.xn--ynd49496l; ; xn--1ch2293gv3nr.xn--ynd49496l; [B1, P1, V6] # ≠.Ⴚ
+≠𐸁𹏁‌.ⴚ򳄠; ≠𐸁𹏁‌.ⴚ򳄠; [B1, C1, P1, V6]; xn--0ug83gn618a21ov.xn--ilj23531g; ; xn--1ch2293gv3nr.xn--ilj23531g; [B1, P1, V6] # ≠.ⴚ
+≠𐸁𹏁‌.ⴚ򳄠; ; [B1, C1, P1, V6]; xn--0ug83gn618a21ov.xn--ilj23531g; ; xn--1ch2293gv3nr.xn--ilj23531g; [B1, P1, V6] # ≠.ⴚ
+xn--1ch2293gv3nr.xn--ilj23531g; ≠𐸁𹏁.ⴚ򳄠; [B1, V6]; xn--1ch2293gv3nr.xn--ilj23531g; ; ; # ≠.ⴚ
+xn--0ug83gn618a21ov.xn--ilj23531g; ≠𐸁𹏁‌.ⴚ򳄠; [B1, C1, V6]; xn--0ug83gn618a21ov.xn--ilj23531g; ; ; # ≠.ⴚ
+xn--1ch2293gv3nr.xn--ynd49496l; ≠𐸁𹏁.Ⴚ򳄠; [B1, V6]; xn--1ch2293gv3nr.xn--ynd49496l; ; ; # ≠.Ⴚ
+xn--0ug83gn618a21ov.xn--ynd49496l; ≠𐸁𹏁‌.Ⴚ򳄠; [B1, C1, V6]; xn--0ug83gn618a21ov.xn--ynd49496l; ; ; # ≠.Ⴚ
+٩。󠇀𑇊; ٩.𑇊; [B1, B3, B6, V5]; xn--iib.xn--6d1d; ; ; # ٩.𑇊
+٩。󠇀𑇊; ٩.𑇊; [B1, B3, B6, V5]; xn--iib.xn--6d1d; ; ; # ٩.𑇊
+xn--iib.xn--6d1d; ٩.𑇊; [B1, B3, B6, V5]; xn--iib.xn--6d1d; ; ; # ٩.𑇊
+ႆ𞶀≯⒍。-; ႆ𞶀≯⒍.-; [B1, P1, V3, V5, V6]; xn--hmd482gqqb8730g.-; ; ; # ႆ≯⒍.-
+ႆ𞶀≯⒍。-; ႆ𞶀≯⒍.-; [B1, P1, V3, V5, V6]; xn--hmd482gqqb8730g.-; ; ; # ႆ≯⒍.-
+ႆ𞶀≯6.。-; ႆ𞶀≯6..-; [B1, P1, V3, V5, V6, X4_2]; xn--6-oyg968k7h74b..-; [B1, P1, V3, V5, V6, A4_2]; ; # ႆ≯6..-
+ႆ𞶀≯6.。-; ႆ𞶀≯6..-; [B1, P1, V3, V5, V6, X4_2]; xn--6-oyg968k7h74b..-; [B1, P1, V3, V5, V6, A4_2]; ; # ႆ≯6..-
+xn--6-oyg968k7h74b..-; ႆ𞶀≯6..-; [B1, V3, V5, V6, X4_2]; xn--6-oyg968k7h74b..-; [B1, V3, V5, V6, A4_2]; ; # ႆ≯6..-
+xn--hmd482gqqb8730g.-; ႆ𞶀≯⒍.-; [B1, V3, V5, V6]; xn--hmd482gqqb8730g.-; ; ; # ႆ≯⒍.-
+឴.쮇-; ; [P1, V3, V5, V6]; xn--z3e.xn----938f; ; ; # .쮇-
+឴.쮇-; ឴.쮇-; [P1, V3, V5, V6]; xn--z3e.xn----938f; ; ; # .쮇-
+xn--z3e.xn----938f; ឴.쮇-; [V3, V5, V6]; xn--z3e.xn----938f; ; ; # .쮇-
+‌𑓂。⒈-􀪛; ‌𑓂.⒈-􀪛; [C1, P1, V6]; xn--0ugy057g.xn----dcp29674o; ; xn--wz1d.xn----dcp29674o; [P1, V5, V6] # 𑓂.⒈-
+‌𑓂。1.-􀪛; ‌𑓂.1.-􀪛; [C1, P1, V3, V6]; xn--0ugy057g.1.xn----rg03o; ; xn--wz1d.1.xn----rg03o; [P1, V3, V5, V6] # 𑓂.1.-
+xn--wz1d.1.xn----rg03o; 𑓂.1.-􀪛; [V3, V5, V6]; xn--wz1d.1.xn----rg03o; ; ; # 𑓂.1.-
+xn--0ugy057g.1.xn----rg03o; ‌𑓂.1.-􀪛; [C1, V3, V6]; xn--0ugy057g.1.xn----rg03o; ; ; # 𑓂.1.-
+xn--wz1d.xn----dcp29674o; 𑓂.⒈-􀪛; [V5, V6]; xn--wz1d.xn----dcp29674o; ; ; # 𑓂.⒈-
+xn--0ugy057g.xn----dcp29674o; ‌𑓂.⒈-􀪛; [C1, V6]; xn--0ugy057g.xn----dcp29674o; ; ; # 𑓂.⒈-
+⒈ﺮ‌。⃩🖞‌𖬴; ⒈ر‌.⃩🖞‌𖬴; [B1, C1, P1, V5, V6]; xn--wgb253kmfd.xn--0ugz6a8040fty5d; ; xn--wgb746m.xn--c1g6021kg18c; [B1, P1, V5, V6] # ⒈ر.⃩🖞𖬴
+1.ر‌。⃩🖞‌𖬴; 1.ر‌.⃩🖞‌𖬴; [B1, B3, C1, V5]; 1.xn--wgb253k.xn--0ugz6a8040fty5d; ; 1.xn--wgb.xn--c1g6021kg18c; [B1, V5] # 1.ر.⃩🖞𖬴
+1.xn--wgb.xn--c1g6021kg18c; 1.ر.⃩🖞𖬴; [B1, V5]; 1.xn--wgb.xn--c1g6021kg18c; ; ; # 1.ر.⃩🖞𖬴
+1.xn--wgb253k.xn--0ugz6a8040fty5d; 1.ر‌.⃩🖞‌𖬴; [B1, B3, C1, V5]; 1.xn--wgb253k.xn--0ugz6a8040fty5d; ; ; # 1.ر.⃩🖞𖬴
+xn--wgb746m.xn--c1g6021kg18c; ⒈ر.⃩🖞𖬴; [B1, V5, V6]; xn--wgb746m.xn--c1g6021kg18c; ; ; # ⒈ر.⃩🖞𖬴
+xn--wgb253kmfd.xn--0ugz6a8040fty5d; ⒈ر‌.⃩🖞‌𖬴; [B1, C1, V5, V6]; xn--wgb253kmfd.xn--0ugz6a8040fty5d; ; ; # ⒈ر.⃩🖞𖬴
+󌭇。𝟐ᮨߔ; 󌭇.2ᮨߔ; [B1, P1, V6]; xn--xm89d.xn--2-icd143m; ; ; # .2ᮨߔ
+󌭇。2ᮨߔ; 󌭇.2ᮨߔ; [B1, P1, V6]; xn--xm89d.xn--2-icd143m; ; ; # .2ᮨߔ
+xn--xm89d.xn--2-icd143m; 󌭇.2ᮨߔ; [B1, V6]; xn--xm89d.xn--2-icd143m; ; ; # .2ᮨߔ
+ﶏ򫳺.ς‍𐹷; مخم򫳺.ς‍𐹷; [B2, B3, B5, B6, C2, P1, V6]; xn--tgb9bb64691z.xn--3xa006lrp7n; ; xn--tgb9bb64691z.xn--4xa6667k; [B2, B3, B5, B6, P1, V6] # مخم.ς𐹷
+مخم򫳺.ς‍𐹷; ; [B2, B3, B5, B6, C2, P1, V6]; xn--tgb9bb64691z.xn--3xa006lrp7n; ; xn--tgb9bb64691z.xn--4xa6667k; [B2, B3, B5, B6, P1, V6] # مخم.ς𐹷
+مخم򫳺.Σ‍𐹷; مخم򫳺.σ‍𐹷; [B2, B3, B5, B6, C2, P1, V6]; xn--tgb9bb64691z.xn--4xa895lrp7n; ; xn--tgb9bb64691z.xn--4xa6667k; [B2, B3, B5, B6, P1, V6] # مخم.σ𐹷
+مخم򫳺.σ‍𐹷; ; [B2, B3, B5, B6, C2, P1, V6]; xn--tgb9bb64691z.xn--4xa895lrp7n; ; xn--tgb9bb64691z.xn--4xa6667k; [B2, B3, B5, B6, P1, V6] # مخم.σ𐹷
+xn--tgb9bb64691z.xn--4xa6667k; مخم򫳺.σ𐹷; [B2, B3, B5, B6, V6]; xn--tgb9bb64691z.xn--4xa6667k; ; ; # مخم.σ𐹷
+xn--tgb9bb64691z.xn--4xa895lrp7n; مخم򫳺.σ‍𐹷; [B2, B3, B5, B6, C2, V6]; xn--tgb9bb64691z.xn--4xa895lrp7n; ; ; # مخم.σ𐹷
+xn--tgb9bb64691z.xn--3xa006lrp7n; مخم򫳺.ς‍𐹷; [B2, B3, B5, B6, C2, V6]; xn--tgb9bb64691z.xn--3xa006lrp7n; ; ; # مخم.ς𐹷
+ﶏ򫳺.Σ‍𐹷; مخم򫳺.σ‍𐹷; [B2, B3, B5, B6, C2, P1, V6]; xn--tgb9bb64691z.xn--4xa895lrp7n; ; xn--tgb9bb64691z.xn--4xa6667k; [B2, B3, B5, B6, P1, V6] # مخم.σ𐹷
+ﶏ򫳺.σ‍𐹷; مخم򫳺.σ‍𐹷; [B2, B3, B5, B6, C2, P1, V6]; xn--tgb9bb64691z.xn--4xa895lrp7n; ; xn--tgb9bb64691z.xn--4xa6667k; [B2, B3, B5, B6, P1, V6] # مخم.σ𐹷
+⒎ہ؅。꫶۵𐇽; ⒎ہ؅.꫶۵𐇽; [B1, P1, V5, V6]; xn--nfb98ai25e.xn--imb3805fxt8b; ; ; # ⒎ہ.꫶۵𐇽
+7.ہ؅。꫶۵𐇽; 7.ہ؅.꫶۵𐇽; [B1, P1, V5, V6]; 7.xn--nfb98a.xn--imb3805fxt8b; ; ; # 7.ہ.꫶۵𐇽
+7.xn--nfb98a.xn--imb3805fxt8b; 7.ہ؅.꫶۵𐇽; [B1, V5, V6]; 7.xn--nfb98a.xn--imb3805fxt8b; ; ; # 7.ہ.꫶۵𐇽
+xn--nfb98ai25e.xn--imb3805fxt8b; ⒎ہ؅.꫶۵𐇽; [B1, V5, V6]; xn--nfb98ai25e.xn--imb3805fxt8b; ; ; # ⒎ہ.꫶۵𐇽
+-ᡥ᠆󍲭。؅ᩝ𐹡; -ᡥ᠆󍲭.؅ᩝ𐹡; [B1, P1, V3, V6]; xn----f3j6s87156i.xn--nfb035hoo2p; ; ; # -ᡥ᠆.ᩝ𐹡
+xn----f3j6s87156i.xn--nfb035hoo2p; -ᡥ᠆󍲭.؅ᩝ𐹡; [B1, V3, V6]; xn----f3j6s87156i.xn--nfb035hoo2p; ; ; # -ᡥ᠆.ᩝ𐹡
+‍.ڽ٣֖; ; [B1, C2]; xn--1ug.xn--hcb32bni; ; .xn--hcb32bni; [A4_2] # .ڽ٣֖
+.xn--hcb32bni; .ڽ٣֖; [X4_2]; .xn--hcb32bni; [A4_2]; ; # .ڽ٣֖
+xn--1ug.xn--hcb32bni; ‍.ڽ٣֖; [B1, C2]; xn--1ug.xn--hcb32bni; ; ; # .ڽ٣֖
+xn--hcb32bni; ڽ٣֖; ; xn--hcb32bni; ; ; # ڽ٣֖
+ڽ٣֖; ; ; xn--hcb32bni; ; ; # ڽ٣֖
+㒧۱.Ⴚٸ‍; 㒧۱.Ⴚيٴ‍; [B5, B6, C2, P1, V6]; xn--emb715u.xn--mhb8f817ao2p; ; xn--emb715u.xn--mhb8f817a; [B5, B6, P1, V6] # 㒧۱.Ⴚيٴ
+㒧۱.Ⴚيٴ‍; ; [B5, B6, C2, P1, V6]; xn--emb715u.xn--mhb8f817ao2p; ; xn--emb715u.xn--mhb8f817a; [B5, B6, P1, V6] # 㒧۱.Ⴚيٴ
+㒧۱.ⴚيٴ‍; ; [B5, B6, C2]; xn--emb715u.xn--mhb8f960g03l; ; xn--emb715u.xn--mhb8fy26k; [B5, B6] # 㒧۱.ⴚيٴ
+xn--emb715u.xn--mhb8fy26k; 㒧۱.ⴚيٴ; [B5, B6]; xn--emb715u.xn--mhb8fy26k; ; ; # 㒧۱.ⴚيٴ
+xn--emb715u.xn--mhb8f960g03l; 㒧۱.ⴚيٴ‍; [B5, B6, C2]; xn--emb715u.xn--mhb8f960g03l; ; ; # 㒧۱.ⴚيٴ
+xn--emb715u.xn--mhb8f817a; 㒧۱.Ⴚيٴ; [B5, B6, V6]; xn--emb715u.xn--mhb8f817a; ; ; # 㒧۱.Ⴚيٴ
+xn--emb715u.xn--mhb8f817ao2p; 㒧۱.Ⴚيٴ‍; [B5, B6, C2, V6]; xn--emb715u.xn--mhb8f817ao2p; ; ; # 㒧۱.Ⴚيٴ
+㒧۱.ⴚٸ‍; 㒧۱.ⴚيٴ‍; [B5, B6, C2]; xn--emb715u.xn--mhb8f960g03l; ; xn--emb715u.xn--mhb8fy26k; [B5, B6] # 㒧۱.ⴚيٴ
+ྔꡋ-.-𖬴; ྔꡋ-.-𖬴; [V3, V5]; xn----ukg9938i.xn----4u5m; ; ; # ྔꡋ-.-𖬴
+ྔꡋ-.-𖬴; ; [V3, V5]; xn----ukg9938i.xn----4u5m; ; ; # ྔꡋ-.-𖬴
+xn----ukg9938i.xn----4u5m; ྔꡋ-.-𖬴; [V3, V5]; xn----ukg9938i.xn----4u5m; ; ; # ྔꡋ-.-𖬴
+񿒳-⋢‌.标-; 񿒳-⋢‌.标-; [C1, P1, V3, V6]; xn----sgn90kn5663a.xn----qj7b; ; xn----9mo67451g.xn----qj7b; [P1, V3, V6] # -⋢.标-
+񿒳-⋢‌.标-; 񿒳-⋢‌.标-; [C1, P1, V3, V6]; xn----sgn90kn5663a.xn----qj7b; ; xn----9mo67451g.xn----qj7b; [P1, V3, V6] # -⋢.标-
+񿒳-⋢‌.标-; ; [C1, P1, V3, V6]; xn----sgn90kn5663a.xn----qj7b; ; xn----9mo67451g.xn----qj7b; [P1, V3, V6] # -⋢.标-
+񿒳-⋢‌.标-; 񿒳-⋢‌.标-; [C1, P1, V3, V6]; xn----sgn90kn5663a.xn----qj7b; ; xn----9mo67451g.xn----qj7b; [P1, V3, V6] # -⋢.标-
+xn----9mo67451g.xn----qj7b; 񿒳-⋢.标-; [V3, V6]; xn----9mo67451g.xn----qj7b; ; ; # -⋢.标-
+xn----sgn90kn5663a.xn----qj7b; 񿒳-⋢‌.标-; [C1, V3, V6]; xn----sgn90kn5663a.xn----qj7b; ; ; # -⋢.标-
+ٱ.ςߜ; ٱ.ςߜ; [B5, B6]; xn--qib.xn--3xa41s; ; xn--qib.xn--4xa21s; # ٱ.ςߜ
+ٱ.ςߜ; ; [B5, B6]; xn--qib.xn--3xa41s; ; xn--qib.xn--4xa21s; # ٱ.ςߜ
+ٱ.Σߜ; ٱ.σߜ; [B5, B6]; xn--qib.xn--4xa21s; ; ; # ٱ.σߜ
+ٱ.σߜ; ; [B5, B6]; xn--qib.xn--4xa21s; ; ; # ٱ.σߜ
+xn--qib.xn--4xa21s; ٱ.σߜ; [B5, B6]; xn--qib.xn--4xa21s; ; ; # ٱ.σߜ
+xn--qib.xn--3xa41s; ٱ.ςߜ; [B5, B6]; xn--qib.xn--3xa41s; ; ; # ٱ.ςߜ
+ٱ.Σߜ; ٱ.σߜ; [B5, B6]; xn--qib.xn--4xa21s; ; ; # ٱ.σߜ
+ٱ.σߜ; ٱ.σߜ; [B5, B6]; xn--qib.xn--4xa21s; ; ; # ٱ.σߜ
+񼈶؅.ࣁ‍𑑂𱼱; 񼈶؅.ࣁ‍𑑂𱼱; [B2, B3, B5, B6, C2, P1, V6]; xn--nfb17942h.xn--nzb240jv06otevq; ; xn--nfb17942h.xn--nzb6708kx3pn; [B2, B3, B5, B6, P1, V6] # .ࣁ𑑂
+񼈶؅.ࣁ‍𑑂𱼱; ; [B2, B3, B5, B6, C2, P1, V6]; xn--nfb17942h.xn--nzb240jv06otevq; ; xn--nfb17942h.xn--nzb6708kx3pn; [B2, B3, B5, B6, P1, V6] # .ࣁ𑑂
+xn--nfb17942h.xn--nzb6708kx3pn; 񼈶؅.ࣁ𑑂𱼱; [B2, B3, B5, B6, V6]; xn--nfb17942h.xn--nzb6708kx3pn; ; ; # .ࣁ𑑂
+xn--nfb17942h.xn--nzb240jv06otevq; 񼈶؅.ࣁ‍𑑂𱼱; [B2, B3, B5, B6, C2, V6]; xn--nfb17942h.xn--nzb240jv06otevq; ; ; # .ࣁ𑑂
+𐹾𐋩𞵜。᯲; 𐹾𐋩𞵜.᯲; [B1, P1, V5, V6]; xn--d97cn8rn44p.xn--0zf; ; ; # 𐹾𐋩.᯲
+𐹾𐋩𞵜。᯲; 𐹾𐋩𞵜.᯲; [B1, P1, V5, V6]; xn--d97cn8rn44p.xn--0zf; ; ; # 𐹾𐋩.᯲
+xn--d97cn8rn44p.xn--0zf; 𐹾𐋩𞵜.᯲; [B1, V5, V6]; xn--d97cn8rn44p.xn--0zf; ; ; # 𐹾𐋩.᯲
+6ᅠᰳ󠸧.򟜊锰ܬς; ; [B1, B5, P1, V6]; xn--6-5bh476ewr517a.xn--3xa16ohw6pk078g; ; xn--6-5bh476ewr517a.xn--4xa95ohw6pk078g; # 6ᰳ.锰ܬς
+6ᅠᰳ󠸧.򟜊锰ܬΣ; 6ᅠᰳ󠸧.򟜊锰ܬσ; [B1, B5, P1, V6]; xn--6-5bh476ewr517a.xn--4xa95ohw6pk078g; ; ; # 6ᰳ.锰ܬσ
+6ᅠᰳ󠸧.򟜊锰ܬσ; ; [B1, B5, P1, V6]; xn--6-5bh476ewr517a.xn--4xa95ohw6pk078g; ; ; # 6ᰳ.锰ܬσ
+xn--6-5bh476ewr517a.xn--4xa95ohw6pk078g; 6ᅠᰳ󠸧.򟜊锰ܬσ; [B1, B5, V6]; xn--6-5bh476ewr517a.xn--4xa95ohw6pk078g; ; ; # 6ᰳ.锰ܬσ
+xn--6-5bh476ewr517a.xn--3xa16ohw6pk078g; 6ᅠᰳ󠸧.򟜊锰ܬς; [B1, B5, V6]; xn--6-5bh476ewr517a.xn--3xa16ohw6pk078g; ; ; # 6ᰳ.锰ܬς
+ڳ︄񅎦𝟽。𐹽; ڳ񅎦7.𐹽; [B1, B2, P1, V6]; xn--7-yuc34665f.xn--1o0d; ; ; # ڳ7.𐹽
+ڳ︄񅎦7。𐹽; ڳ񅎦7.𐹽; [B1, B2, P1, V6]; xn--7-yuc34665f.xn--1o0d; ; ; # ڳ7.𐹽
+xn--7-yuc34665f.xn--1o0d; ڳ񅎦7.𐹽; [B1, B2, V6]; xn--7-yuc34665f.xn--1o0d; ; ; # ڳ7.𐹽
+𞮧.‌⫞; 𞮧.‌⫞; [B1, C1, P1, V6]; xn--pw6h.xn--0ug283b; ; xn--pw6h.xn--53i; [B1, P1, V6] # .⫞
+𞮧.‌⫞; ; [B1, C1, P1, V6]; xn--pw6h.xn--0ug283b; ; xn--pw6h.xn--53i; [B1, P1, V6] # .⫞
+xn--pw6h.xn--53i; 𞮧.⫞; [B1, V6]; xn--pw6h.xn--53i; ; ; # .⫞
+xn--pw6h.xn--0ug283b; 𞮧.‌⫞; [B1, C1, V6]; xn--pw6h.xn--0ug283b; ; ; # .⫞
+-񕉴.۠ᢚ-; ; [P1, V3, V5, V6]; xn----qi38c.xn----jxc827k; ; ; # -.۠ᢚ-
+xn----qi38c.xn----jxc827k; -񕉴.۠ᢚ-; [V3, V5, V6]; xn----qi38c.xn----jxc827k; ; ; # -.۠ᢚ-
+⌁‍𑄴.‌𝟩٬; ⌁‍𑄴.‌7٬; [B1, C1, C2]; xn--1ug38i2093a.xn--7-xqc297q; ; xn--nhh5394g.xn--7-xqc; [B1] # ⌁𑄴.7٬
+⌁‍𑄴.‌7٬; ; [B1, C1, C2]; xn--1ug38i2093a.xn--7-xqc297q; ; xn--nhh5394g.xn--7-xqc; [B1] # ⌁𑄴.7٬
+xn--nhh5394g.xn--7-xqc; ⌁𑄴.7٬; [B1]; xn--nhh5394g.xn--7-xqc; ; ; # ⌁𑄴.7٬
+xn--1ug38i2093a.xn--7-xqc297q; ⌁‍𑄴.‌7٬; [B1, C1, C2]; xn--1ug38i2093a.xn--7-xqc297q; ; ; # ⌁𑄴.7٬
+︒ﴅืﻼ。岓᯲󠾃ᡂ; ︒صىืلا.岓᯲󠾃ᡂ; [B1, P1, V6]; xn--mgb1a7bt462hf267a.xn--17e10qe61f9r71s; ; ; # ︒صىืلا.岓᯲ᡂ
+。صىืلا。岓᯲󠾃ᡂ; .صىืلا.岓᯲󠾃ᡂ; [P1, V6, X4_2]; .xn--mgb1a7bt462h.xn--17e10qe61f9r71s; [P1, V6, A4_2]; ; # .صىืلا.岓᯲ᡂ
+.xn--mgb1a7bt462h.xn--17e10qe61f9r71s; .صىืلا.岓᯲󠾃ᡂ; [V6, X4_2]; .xn--mgb1a7bt462h.xn--17e10qe61f9r71s; [V6, A4_2]; ; # .صىืلا.岓᯲ᡂ
+xn--mgb1a7bt462hf267a.xn--17e10qe61f9r71s; ︒صىืلا.岓᯲󠾃ᡂ; [B1, V6]; xn--mgb1a7bt462hf267a.xn--17e10qe61f9r71s; ; ; # ︒صىืلا.岓᯲ᡂ
+𐹨。8𑁆; 𐹨.8𑁆; [B1]; xn--go0d.xn--8-yu7i; ; ; # 𐹨.8𑁆
+xn--go0d.xn--8-yu7i; 𐹨.8𑁆; [B1]; xn--go0d.xn--8-yu7i; ; ; # 𐹨.8𑁆
+𞀕ൃ.ꡚࣺ𐹰ൄ; 𞀕ൃ.ꡚࣺ𐹰ൄ; [B1, B3, B5, B6, V5]; xn--mxc5210v.xn--90b01t8u2p1ltd; ; ; # 𞀕ൃ.ꡚࣺ𐹰ൄ
+𞀕ൃ.ꡚࣺ𐹰ൄ; ; [B1, B3, B5, B6, V5]; xn--mxc5210v.xn--90b01t8u2p1ltd; ; ; # 𞀕ൃ.ꡚࣺ𐹰ൄ
+xn--mxc5210v.xn--90b01t8u2p1ltd; 𞀕ൃ.ꡚࣺ𐹰ൄ; [B1, B3, B5, B6, V5]; xn--mxc5210v.xn--90b01t8u2p1ltd; ; ; # 𞀕ൃ.ꡚࣺ𐹰ൄ
+󆩏𐦹̃。󠍅; 󆩏𐦹̃.󠍅; [B1, B5, B6, P1, V6]; xn--nsa1265kp9z9e.xn--xt36e; ; ; # ̃.
+󆩏𐦹̃。󠍅; 󆩏𐦹̃.󠍅; [B1, B5, B6, P1, V6]; xn--nsa1265kp9z9e.xn--xt36e; ; ; # ̃.
+xn--nsa1265kp9z9e.xn--xt36e; 󆩏𐦹̃.󠍅; [B1, B5, B6, V6]; xn--nsa1265kp9z9e.xn--xt36e; ; ; # ̃.
+ᢌ.-࡚; ᢌ.-࡚; [V3]; xn--59e.xn----5jd; ; ; # ᢌ.-࡚
+ᢌ.-࡚; ; [V3]; xn--59e.xn----5jd; ; ; # ᢌ.-࡚
+xn--59e.xn----5jd; ᢌ.-࡚; [V3]; xn--59e.xn----5jd; ; ; # ᢌ.-࡚
+𥛛𑘶。𐹬𐲸்; 𥛛𑘶.𐹬𐲸்; [B1, P1, V6]; xn--jb2dj685c.xn--xmc5562kmcb; ; ; # 𥛛𑘶.𐹬்
+𥛛𑘶。𐹬𐲸்; 𥛛𑘶.𐹬𐲸்; [B1, P1, V6]; xn--jb2dj685c.xn--xmc5562kmcb; ; ; # 𥛛𑘶.𐹬்
+xn--jb2dj685c.xn--xmc5562kmcb; 𥛛𑘶.𐹬𐲸்; [B1, V6]; xn--jb2dj685c.xn--xmc5562kmcb; ; ; # 𥛛𑘶.𐹬்
+Ⴐݿ.‌; Ⴐݿ.‌; [B1, B5, B6, C1, P1, V6]; xn--gqb918b.xn--0ug; ; xn--gqb918b.; [B5, B6, P1, V6] # Ⴐݿ.
+Ⴐݿ.‌; ; [B1, B5, B6, C1, P1, V6]; xn--gqb918b.xn--0ug; ; xn--gqb918b.; [B5, B6, P1, V6] # Ⴐݿ.
+ⴐݿ.‌; ; [B1, B5, B6, C1]; xn--gqb743q.xn--0ug; ; xn--gqb743q.; [B5, B6] # ⴐݿ.
+xn--gqb743q.; ⴐݿ.; [B5, B6]; xn--gqb743q.; ; ; # ⴐݿ.
+xn--gqb743q.xn--0ug; ⴐݿ.‌; [B1, B5, B6, C1]; xn--gqb743q.xn--0ug; ; ; # ⴐݿ.
+xn--gqb918b.; Ⴐݿ.; [B5, B6, V6]; xn--gqb918b.; ; ; # Ⴐݿ.
+xn--gqb918b.xn--0ug; Ⴐݿ.‌; [B1, B5, B6, C1, V6]; xn--gqb918b.xn--0ug; ; ; # Ⴐݿ.
+ⴐݿ.‌; ⴐݿ.‌; [B1, B5, B6, C1]; xn--gqb743q.xn--0ug; ; xn--gqb743q.; [B5, B6] # ⴐݿ.
+🄅𑲞-⒈。‍ᠩڥ; 🄅𑲞-⒈.‍ᠩڥ; [B1, C2, P1, V6]; xn----ecp8796hjtvg.xn--7jb180gexf; ; xn----ecp8796hjtvg.xn--7jb180g; [B1, B5, B6, P1, V6] # 🄅𑲞-⒈.ᠩڥ
+4,𑲞-1.。‍ᠩڥ; 4,𑲞-1..‍ᠩڥ; [B1, C2, P1, V6, X4_2]; xn--4,-1-w401a..xn--7jb180gexf; [B1, C2, P1, V6, A4_2]; xn--4,-1-w401a..xn--7jb180g; [B1, B5, B6, P1, V6, A4_2] # 4,𑲞-1..ᠩڥ
+xn--4,-1-w401a..xn--7jb180g; 4,𑲞-1..ᠩڥ; [B1, B5, B6, P1, V6, X4_2]; xn--4,-1-w401a..xn--7jb180g; [B1, B5, B6, P1, V6, A4_2]; ; # 4,𑲞-1..ᠩڥ
+xn--4,-1-w401a..xn--7jb180gexf; 4,𑲞-1..‍ᠩڥ; [B1, C2, P1, V6, X4_2]; xn--4,-1-w401a..xn--7jb180gexf; [B1, C2, P1, V6, A4_2]; ; # 4,𑲞-1..ᠩڥ
+xn----ecp8796hjtvg.xn--7jb180g; 🄅𑲞-⒈.ᠩڥ; [B1, B5, B6, V6]; xn----ecp8796hjtvg.xn--7jb180g; ; ; # 🄅𑲞-⒈.ᠩڥ
+xn----ecp8796hjtvg.xn--7jb180gexf; 🄅𑲞-⒈.‍ᠩڥ; [B1, C2, V6]; xn----ecp8796hjtvg.xn--7jb180gexf; ; ; # 🄅𑲞-⒈.ᠩڥ
+񗀤。𞤪򮿋; 񗀤.𞤪򮿋; [B2, B3, P1, V6]; xn--4240a.xn--ie6h83808a; ; ; # .𞤪
+񗀤。𞤈򮿋; 񗀤.𞤪򮿋; [B2, B3, P1, V6]; xn--4240a.xn--ie6h83808a; ; ; # .𞤪
+xn--4240a.xn--ie6h83808a; 񗀤.𞤪򮿋; [B2, B3, V6]; xn--4240a.xn--ie6h83808a; ; ; # .𞤪
+ׁ۲。𐮊٬𝨊鄨; ׁ۲.𐮊٬𝨊鄨; [B1, B2, B3, V5]; xn--pdb42d.xn--lib6412enztdwv6h; ; ; # ׁ۲.𐮊٬𝨊鄨
+ׁ۲。𐮊٬𝨊鄨; ׁ۲.𐮊٬𝨊鄨; [B1, B2, B3, V5]; xn--pdb42d.xn--lib6412enztdwv6h; ; ; # ׁ۲.𐮊٬𝨊鄨
+xn--pdb42d.xn--lib6412enztdwv6h; ׁ۲.𐮊٬𝨊鄨; [B1, B2, B3, V5]; xn--pdb42d.xn--lib6412enztdwv6h; ; ; # ׁ۲.𐮊٬𝨊鄨
+𞭳-ꡁ。ᩩ்-; 𞭳-ꡁ.ᩩ்-; [B1, B2, B3, P1, V3, V5, V6]; xn----be4e4276f.xn----lze333i; ; ; # -ꡁ.ᩩ்-
+xn----be4e4276f.xn----lze333i; 𞭳-ꡁ.ᩩ்-; [B1, B2, B3, V3, V5, V6]; xn----be4e4276f.xn----lze333i; ; ; # -ꡁ.ᩩ்-
+္-𚮭🞢.ß; ္-𚮭🞢.ß; [P1, V5, V6]; xn----9tg11172akr8b.xn--zca; ; xn----9tg11172akr8b.ss; # ္-🞢.ß
+္-𚮭🞢.ß; ; [P1, V5, V6]; xn----9tg11172akr8b.xn--zca; ; xn----9tg11172akr8b.ss; # ္-🞢.ß
+္-𚮭🞢.SS; ္-𚮭🞢.ss; [P1, V5, V6]; xn----9tg11172akr8b.ss; ; ; # ္-🞢.ss
+္-𚮭🞢.ss; ; [P1, V5, V6]; xn----9tg11172akr8b.ss; ; ; # ္-🞢.ss
+္-𚮭🞢.Ss; ္-𚮭🞢.ss; [P1, V5, V6]; xn----9tg11172akr8b.ss; ; ; # ္-🞢.ss
+xn----9tg11172akr8b.ss; ္-𚮭🞢.ss; [V5, V6]; xn----9tg11172akr8b.ss; ; ; # ္-🞢.ss
+xn----9tg11172akr8b.xn--zca; ္-𚮭🞢.ß; [V5, V6]; xn----9tg11172akr8b.xn--zca; ; ; # ္-🞢.ß
+္-𚮭🞢.SS; ္-𚮭🞢.ss; [P1, V5, V6]; xn----9tg11172akr8b.ss; ; ; # ္-🞢.ss
+္-𚮭🞢.ss; ္-𚮭🞢.ss; [P1, V5, V6]; xn----9tg11172akr8b.ss; ; ; # ္-🞢.ss
+္-𚮭🞢.Ss; ္-𚮭🞢.ss; [P1, V5, V6]; xn----9tg11172akr8b.ss; ; ; # ္-🞢.ss
+ﳲ-‌。Ⴟ‌␣; ـَّ-‌.Ⴟ‌␣; [B3, B6, C1, P1, V6]; xn----eoc6bm0504a.xn--3nd849e05c; ; xn----eoc6bm.xn--3nd240h; [B3, B6, P1, V3, V6] # ـَّ-.Ⴟ␣
+ـَّ-‌。Ⴟ‌␣; ـَّ-‌.Ⴟ‌␣; [B3, B6, C1, P1, V6]; xn----eoc6bm0504a.xn--3nd849e05c; ; xn----eoc6bm.xn--3nd240h; [B3, B6, P1, V3, V6] # ـَّ-.Ⴟ␣
+ـَّ-‌。ⴟ‌␣; ـَّ-‌.ⴟ‌␣; [B3, B6, C1]; xn----eoc6bm0504a.xn--0ug13nd0j; ; xn----eoc6bm.xn--xph904a; [B3, B6, V3] # ـَّ-.ⴟ␣
+xn----eoc6bm.xn--xph904a; ـَّ-.ⴟ␣; [B3, B6, V3]; xn----eoc6bm.xn--xph904a; ; ; # ـَّ-.ⴟ␣
+xn----eoc6bm0504a.xn--0ug13nd0j; ـَّ-‌.ⴟ‌␣; [B3, B6, C1]; xn----eoc6bm0504a.xn--0ug13nd0j; ; ; # ـَّ-.ⴟ␣
+xn----eoc6bm.xn--3nd240h; ـَّ-.Ⴟ␣; [B3, B6, V3, V6]; xn----eoc6bm.xn--3nd240h; ; ; # ـَّ-.Ⴟ␣
+xn----eoc6bm0504a.xn--3nd849e05c; ـَّ-‌.Ⴟ‌␣; [B3, B6, C1, V6]; xn----eoc6bm0504a.xn--3nd849e05c; ; ; # ـَّ-.Ⴟ␣
+ﳲ-‌。ⴟ‌␣; ـَّ-‌.ⴟ‌␣; [B3, B6, C1]; xn----eoc6bm0504a.xn--0ug13nd0j; ; xn----eoc6bm.xn--xph904a; [B3, B6, V3] # ـَّ-.ⴟ␣
+്-‍‌。񥞧₅≠; ്-‍‌.񥞧5≠; [C1, C2, P1, V5, V6]; xn----jmf215lda.xn--5-ufo50192e; ; xn----jmf.xn--5-ufo50192e; [P1, V3, V5, V6] # ്-.5≠
+്-‍‌。񥞧₅≠; ്-‍‌.񥞧5≠; [C1, C2, P1, V5, V6]; xn----jmf215lda.xn--5-ufo50192e; ; xn----jmf.xn--5-ufo50192e; [P1, V3, V5, V6] # ്-.5≠
+്-‍‌。񥞧5≠; ്-‍‌.񥞧5≠; [C1, C2, P1, V5, V6]; xn----jmf215lda.xn--5-ufo50192e; ; xn----jmf.xn--5-ufo50192e; [P1, V3, V5, V6] # ്-.5≠
+്-‍‌。񥞧5≠; ്-‍‌.񥞧5≠; [C1, C2, P1, V5, V6]; xn----jmf215lda.xn--5-ufo50192e; ; xn----jmf.xn--5-ufo50192e; [P1, V3, V5, V6] # ്-.5≠
+xn----jmf.xn--5-ufo50192e; ്-.񥞧5≠; [V3, V5, V6]; xn----jmf.xn--5-ufo50192e; ; ; # ്-.5≠
+xn----jmf215lda.xn--5-ufo50192e; ്-‍‌.񥞧5≠; [C1, C2, V5, V6]; xn----jmf215lda.xn--5-ufo50192e; ; ; # ്-.5≠
+锣。੍󠘻󠚆; 锣.੍󠘻󠚆; [P1, V5, V6]; xn--gc5a.xn--ybc83044ppga; ; ; # 锣.੍
+xn--gc5a.xn--ybc83044ppga; 锣.੍󠘻󠚆; [V5, V6]; xn--gc5a.xn--ybc83044ppga; ; ; # 锣.੍
+ؽ𑈾.ى‍꤫; ؽ𑈾.ى‍꤫; [B3, C2]; xn--8gb2338k.xn--lhb603k060h; ; xn--8gb2338k.xn--lhb0154f; [] # ؽ𑈾.ى꤫
+ؽ𑈾.ى‍꤫; ; [B3, C2]; xn--8gb2338k.xn--lhb603k060h; ; xn--8gb2338k.xn--lhb0154f; [] # ؽ𑈾.ى꤫
+xn--8gb2338k.xn--lhb0154f; ؽ𑈾.ى꤫; ; xn--8gb2338k.xn--lhb0154f; ; ; # ؽ𑈾.ى꤫
+ؽ𑈾.ى꤫; ; ; xn--8gb2338k.xn--lhb0154f; ; ; # ؽ𑈾.ى꤫
+xn--8gb2338k.xn--lhb603k060h; ؽ𑈾.ى‍꤫; [B3, C2]; xn--8gb2338k.xn--lhb603k060h; ; ; # ؽ𑈾.ى꤫
+٦⁴Ⴅ.ࢽ‌; ٦4Ⴅ.ࢽ‌; [B1, B3, C1, P1, V6]; xn--4-kqc489e.xn--jzb840j; ; xn--4-kqc489e.xn--jzb; [B1, P1, V6] # ٦4Ⴅ.ࢽ
+٦4Ⴅ.ࢽ‌; ; [B1, B3, C1, P1, V6]; xn--4-kqc489e.xn--jzb840j; ; xn--4-kqc489e.xn--jzb; [B1, P1, V6] # ٦4Ⴅ.ࢽ
+٦4ⴅ.ࢽ‌; ; [B1, B3, C1]; xn--4-kqc6770a.xn--jzb840j; ; xn--4-kqc6770a.xn--jzb; [B1] # ٦4ⴅ.ࢽ
+xn--4-kqc6770a.xn--jzb; ٦4ⴅ.ࢽ; [B1]; xn--4-kqc6770a.xn--jzb; ; ; # ٦4ⴅ.ࢽ
+xn--4-kqc6770a.xn--jzb840j; ٦4ⴅ.ࢽ‌; [B1, B3, C1]; xn--4-kqc6770a.xn--jzb840j; ; ; # ٦4ⴅ.ࢽ
+xn--4-kqc489e.xn--jzb; ٦4Ⴅ.ࢽ; [B1, V6]; xn--4-kqc489e.xn--jzb; ; ; # ٦4Ⴅ.ࢽ
+xn--4-kqc489e.xn--jzb840j; ٦4Ⴅ.ࢽ‌; [B1, B3, C1, V6]; xn--4-kqc489e.xn--jzb840j; ; ; # ٦4Ⴅ.ࢽ
+٦⁴ⴅ.ࢽ‌; ٦4ⴅ.ࢽ‌; [B1, B3, C1]; xn--4-kqc6770a.xn--jzb840j; ; xn--4-kqc6770a.xn--jzb; [B1] # ٦4ⴅ.ࢽ
+ჁႱ6̘。ßᬃ; ჁႱ6̘.ßᬃ; [P1, V6]; xn--6-8cb555h2b.xn--zca894k; ; xn--6-8cb555h2b.xn--ss-2vq; # ჁႱ6̘.ßᬃ
+ⴡⴑ6̘。ßᬃ; ⴡⴑ6̘.ßᬃ; ; xn--6-8cb7433a2ba.xn--zca894k; ; xn--6-8cb7433a2ba.xn--ss-2vq; # ⴡⴑ6̘.ßᬃ
+ჁႱ6̘。SSᬃ; ჁႱ6̘.ssᬃ; [P1, V6]; xn--6-8cb555h2b.xn--ss-2vq; ; ; # ჁႱ6̘.ssᬃ
+ⴡⴑ6̘。ssᬃ; ⴡⴑ6̘.ssᬃ; ; xn--6-8cb7433a2ba.xn--ss-2vq; ; ; # ⴡⴑ6̘.ssᬃ
+Ⴡⴑ6̘。Ssᬃ; Ⴡⴑ6̘.ssᬃ; [P1, V6]; xn--6-8cb306hms1a.xn--ss-2vq; ; ; # Ⴡⴑ6̘.ssᬃ
+xn--6-8cb306hms1a.xn--ss-2vq; Ⴡⴑ6̘.ssᬃ; [V6]; xn--6-8cb306hms1a.xn--ss-2vq; ; ; # Ⴡⴑ6̘.ssᬃ
+xn--6-8cb7433a2ba.xn--ss-2vq; ⴡⴑ6̘.ssᬃ; ; xn--6-8cb7433a2ba.xn--ss-2vq; ; ; # ⴡⴑ6̘.ssᬃ
+ⴡⴑ6̘.ssᬃ; ; ; xn--6-8cb7433a2ba.xn--ss-2vq; ; ; # ⴡⴑ6̘.ssᬃ
+ჁႱ6̘.SSᬃ; ჁႱ6̘.ssᬃ; [P1, V6]; xn--6-8cb555h2b.xn--ss-2vq; ; ; # ჁႱ6̘.ssᬃ
+Ⴡⴑ6̘.Ssᬃ; Ⴡⴑ6̘.ssᬃ; [P1, V6]; xn--6-8cb306hms1a.xn--ss-2vq; ; ; # Ⴡⴑ6̘.ssᬃ
+xn--6-8cb555h2b.xn--ss-2vq; ჁႱ6̘.ssᬃ; [V6]; xn--6-8cb555h2b.xn--ss-2vq; ; ; # ჁႱ6̘.ssᬃ
+xn--6-8cb7433a2ba.xn--zca894k; ⴡⴑ6̘.ßᬃ; ; xn--6-8cb7433a2ba.xn--zca894k; ; ; # ⴡⴑ6̘.ßᬃ
+ⴡⴑ6̘.ßᬃ; ; ; xn--6-8cb7433a2ba.xn--zca894k; ; xn--6-8cb7433a2ba.xn--ss-2vq; # ⴡⴑ6̘.ßᬃ
+xn--6-8cb555h2b.xn--zca894k; ჁႱ6̘.ßᬃ; [V6]; xn--6-8cb555h2b.xn--zca894k; ; ; # ჁႱ6̘.ßᬃ
+򋡐。≯𑋪; 򋡐.≯𑋪; [P1, V6]; xn--eo08b.xn--hdh3385g; ; ; # .≯𑋪
+򋡐。≯𑋪; 򋡐.≯𑋪; [P1, V6]; xn--eo08b.xn--hdh3385g; ; ; # .≯𑋪
+򋡐。≯𑋪; 򋡐.≯𑋪; [P1, V6]; xn--eo08b.xn--hdh3385g; ; ; # .≯𑋪
+򋡐。≯𑋪; 򋡐.≯𑋪; [P1, V6]; xn--eo08b.xn--hdh3385g; ; ; # .≯𑋪
+xn--eo08b.xn--hdh3385g; 򋡐.≯𑋪; [V6]; xn--eo08b.xn--hdh3385g; ; ; # .≯𑋪
+ٚ۲。‌-᯳࣢; ٚ۲.‌-᯳࣢; [B1, C1, P1, V5, V6]; xn--2hb81a.xn----xrd657l30d; ; xn--2hb81a.xn----xrd657l; [B1, P1, V3, V5, V6] # ٚ۲.-᯳
+xn--2hb81a.xn----xrd657l; ٚ۲.-᯳࣢; [B1, V3, V5, V6]; xn--2hb81a.xn----xrd657l; ; ; # ٚ۲.-᯳
+xn--2hb81a.xn----xrd657l30d; ٚ۲.‌-᯳࣢; [B1, C1, V5, V6]; xn--2hb81a.xn----xrd657l30d; ; ; # ٚ۲.-᯳
+󠄏𖬴󠲽。ᅠ; 𖬴󠲽.ᅠ; [P1, V5, V6]; xn--619ep9154c.xn--cl7c; ; ; # 𖬴.
+󠄏𖬴󠲽。ᅠ; 𖬴󠲽.ᅠ; [P1, V5, V6]; xn--619ep9154c.xn--psd; ; ; # 𖬴.
+xn--619ep9154c.xn--psd; 𖬴󠲽.ᅠ; [V5, V6]; xn--619ep9154c.xn--psd; ; ; # 𖬴.
+xn--619ep9154c.xn--cl7c; 𖬴󠲽.ᅠ; [V5, V6]; xn--619ep9154c.xn--cl7c; ; ; # 𖬴.
+ß⒈ݠ힮.􉖲󠅄؅򉔯; ß⒈ݠ힮.􉖲؅򉔯; [B5, P1, V6]; xn--zca444a0s1ao12n.xn--nfb09923ifkyyb; ; xn--ss-6ke9690a0g1q.xn--nfb09923ifkyyb; # ß⒈ݠ.
+ß1.ݠ힮.􉖲󠅄؅򉔯; ß1.ݠ힮.􉖲؅򉔯; [B2, B3, B5, P1, V6]; xn--1-pfa.xn--kpb6677h.xn--nfb09923ifkyyb; ; ss1.xn--kpb6677h.xn--nfb09923ifkyyb; # ß1.ݠ.
+SS1.ݠ힮.􉖲󠅄؅򉔯; ss1.ݠ힮.􉖲؅򉔯; [B2, B3, B5, P1, V6]; ss1.xn--kpb6677h.xn--nfb09923ifkyyb; ; ; # ss1.ݠ.
+ss1.ݠ힮.􉖲󠅄؅򉔯; ss1.ݠ힮.􉖲؅򉔯; [B2, B3, B5, P1, V6]; ss1.xn--kpb6677h.xn--nfb09923ifkyyb; ; ; # ss1.ݠ.
+Ss1.ݠ힮.􉖲󠅄؅򉔯; ss1.ݠ힮.􉖲؅򉔯; [B2, B3, B5, P1, V6]; ss1.xn--kpb6677h.xn--nfb09923ifkyyb; ; ; # ss1.ݠ.
+ss1.xn--kpb6677h.xn--nfb09923ifkyyb; ss1.ݠ힮.􉖲؅򉔯; [B2, B3, B5, V6]; ss1.xn--kpb6677h.xn--nfb09923ifkyyb; ; ; # ss1.ݠ.
+xn--1-pfa.xn--kpb6677h.xn--nfb09923ifkyyb; ß1.ݠ힮.􉖲؅򉔯; [B2, B3, B5, V6]; xn--1-pfa.xn--kpb6677h.xn--nfb09923ifkyyb; ; ; # ß1.ݠ.
+SS⒈ݠ힮.􉖲󠅄؅򉔯; ss⒈ݠ힮.􉖲؅򉔯; [B5, P1, V6]; xn--ss-6ke9690a0g1q.xn--nfb09923ifkyyb; ; ; # ss⒈ݠ.
+ss⒈ݠ힮.􉖲󠅄؅򉔯; ss⒈ݠ힮.􉖲؅򉔯; [B5, P1, V6]; xn--ss-6ke9690a0g1q.xn--nfb09923ifkyyb; ; ; # ss⒈ݠ.
+Ss⒈ݠ힮.􉖲󠅄؅򉔯; ss⒈ݠ힮.􉖲؅򉔯; [B5, P1, V6]; xn--ss-6ke9690a0g1q.xn--nfb09923ifkyyb; ; ; # ss⒈ݠ.
+xn--ss-6ke9690a0g1q.xn--nfb09923ifkyyb; ss⒈ݠ힮.􉖲؅򉔯; [B5, V6]; xn--ss-6ke9690a0g1q.xn--nfb09923ifkyyb; ; ; # ss⒈ݠ.
+xn--zca444a0s1ao12n.xn--nfb09923ifkyyb; ß⒈ݠ힮.􉖲؅򉔯; [B5, V6]; xn--zca444a0s1ao12n.xn--nfb09923ifkyyb; ; ; # ß⒈ݠ.
+󠭔.𐋱₂; 󠭔.𐋱2; [P1, V6]; xn--vi56e.xn--2-w91i; ; ; # .𐋱2
+󠭔.𐋱2; ; [P1, V6]; xn--vi56e.xn--2-w91i; ; ; # .𐋱2
+xn--vi56e.xn--2-w91i; 󠭔.𐋱2; [V6]; xn--vi56e.xn--2-w91i; ; ; # .𐋱2
+ܖे。-ßڥ‌; ܖे.-ßڥ‌; [B1, C1, V3]; xn--gnb63i.xn----qfa845bhx4a; ; xn--gnb63i.xn---ss-4ef; [B1, V3] # ܖे.-ßڥ
+ܖे。-SSڥ‌; ܖे.-ssڥ‌; [B1, C1, V3]; xn--gnb63i.xn---ss-4ef9263a; ; xn--gnb63i.xn---ss-4ef; [B1, V3] # ܖे.-ssڥ
+ܖे。-ssڥ‌; ܖे.-ssڥ‌; [B1, C1, V3]; xn--gnb63i.xn---ss-4ef9263a; ; xn--gnb63i.xn---ss-4ef; [B1, V3] # ܖे.-ssڥ
+ܖे。-Ssڥ‌; ܖे.-ssڥ‌; [B1, C1, V3]; xn--gnb63i.xn---ss-4ef9263a; ; xn--gnb63i.xn---ss-4ef; [B1, V3] # ܖे.-ssڥ
+xn--gnb63i.xn---ss-4ef; ܖे.-ssڥ; [B1, V3]; xn--gnb63i.xn---ss-4ef; ; ; # ܖे.-ssڥ
+xn--gnb63i.xn---ss-4ef9263a; ܖे.-ssڥ‌; [B1, C1, V3]; xn--gnb63i.xn---ss-4ef9263a; ; ; # ܖे.-ssڥ
+xn--gnb63i.xn----qfa845bhx4a; ܖे.-ßڥ‌; [B1, C1, V3]; xn--gnb63i.xn----qfa845bhx4a; ; ; # ܖे.-ßڥ
+ᮩ‍ت񡚈.᳕䷉Ⴡ; ᮩ‍ت񡚈.᳕䷉Ⴡ; [B1, C2, P1, V5, V6]; xn--pgb911imgdrw34r.xn--5nd792dgv3b; ; xn--pgb911izv33i.xn--5nd792dgv3b; [B1, P1, V5, V6] # ᮩت.᳕䷉Ⴡ
+ᮩ‍ت񡚈.᳕䷉Ⴡ; ; [B1, C2, P1, V5, V6]; xn--pgb911imgdrw34r.xn--5nd792dgv3b; ; xn--pgb911izv33i.xn--5nd792dgv3b; [B1, P1, V5, V6] # ᮩت.᳕䷉Ⴡ
+ᮩ‍ت񡚈.᳕䷉ⴡ; ; [B1, C2, P1, V5, V6]; xn--pgb911imgdrw34r.xn--i6f270etuy; ; xn--pgb911izv33i.xn--i6f270etuy; [B1, P1, V5, V6] # ᮩت.᳕䷉ⴡ
+xn--pgb911izv33i.xn--i6f270etuy; ᮩت񡚈.᳕䷉ⴡ; [B1, V5, V6]; xn--pgb911izv33i.xn--i6f270etuy; ; ; # ᮩت.᳕䷉ⴡ
+xn--pgb911imgdrw34r.xn--i6f270etuy; ᮩ‍ت񡚈.᳕䷉ⴡ; [B1, C2, V5, V6]; xn--pgb911imgdrw34r.xn--i6f270etuy; ; ; # ᮩت.᳕䷉ⴡ
+xn--pgb911izv33i.xn--5nd792dgv3b; ᮩت񡚈.᳕䷉Ⴡ; [B1, V5, V6]; xn--pgb911izv33i.xn--5nd792dgv3b; ; ; # ᮩت.᳕䷉Ⴡ
+xn--pgb911imgdrw34r.xn--5nd792dgv3b; ᮩ‍ت񡚈.᳕䷉Ⴡ; [B1, C2, V5, V6]; xn--pgb911imgdrw34r.xn--5nd792dgv3b; ; ; # ᮩت.᳕䷉Ⴡ
+ᮩ‍ت񡚈.᳕䷉ⴡ; ᮩ‍ت񡚈.᳕䷉ⴡ; [B1, C2, P1, V5, V6]; xn--pgb911imgdrw34r.xn--i6f270etuy; ; xn--pgb911izv33i.xn--i6f270etuy; [B1, P1, V5, V6] # ᮩت.᳕䷉ⴡ
+⶿.ß‍; ; [C2, P1, V6]; xn--7pj.xn--zca870n; ; xn--7pj.ss; [P1, V6] # .ß
+⶿.SS‍; ⶿.ss‍; [C2, P1, V6]; xn--7pj.xn--ss-n1t; ; xn--7pj.ss; [P1, V6] # .ss
+⶿.ss‍; ; [C2, P1, V6]; xn--7pj.xn--ss-n1t; ; xn--7pj.ss; [P1, V6] # .ss
+⶿.Ss‍; ⶿.ss‍; [C2, P1, V6]; xn--7pj.xn--ss-n1t; ; xn--7pj.ss; [P1, V6] # .ss
+xn--7pj.ss; ⶿.ss; [V6]; xn--7pj.ss; ; ; # .ss
+xn--7pj.xn--ss-n1t; ⶿.ss‍; [C2, V6]; xn--7pj.xn--ss-n1t; ; ; # .ss
+xn--7pj.xn--zca870n; ⶿.ß‍; [C2, V6]; xn--7pj.xn--zca870n; ; ; # .ß
+᯳︒.ت≯ꡂ; ; [B2, B3, B6, P1, V5, V6]; xn--1zf8957g.xn--pgb885lry5g; ; ; # ᯳︒.ت≯ꡂ
+᯳︒.ت≯ꡂ; ᯳︒.ت≯ꡂ; [B2, B3, B6, P1, V5, V6]; xn--1zf8957g.xn--pgb885lry5g; ; ; # ᯳︒.ت≯ꡂ
+᯳。.ت≯ꡂ; ᯳..ت≯ꡂ; [B2, B3, P1, V5, V6, X4_2]; xn--1zf..xn--pgb885lry5g; [B2, B3, P1, V5, V6, A4_2]; ; # ᯳..ت≯ꡂ
+᯳。.ت≯ꡂ; ᯳..ت≯ꡂ; [B2, B3, P1, V5, V6, X4_2]; xn--1zf..xn--pgb885lry5g; [B2, B3, P1, V5, V6, A4_2]; ; # ᯳..ت≯ꡂ
+xn--1zf..xn--pgb885lry5g; ᯳..ت≯ꡂ; [B2, B3, V5, V6, X4_2]; xn--1zf..xn--pgb885lry5g; [B2, B3, V5, V6, A4_2]; ; # ᯳..ت≯ꡂ
+xn--1zf8957g.xn--pgb885lry5g; ᯳︒.ت≯ꡂ; [B2, B3, B6, V5, V6]; xn--1zf8957g.xn--pgb885lry5g; ; ; # ᯳︒.ت≯ꡂ
+≮≠񏻃。-𫠆ڷ𐹪; ≮≠񏻃.-𫠆ڷ𐹪; [B1, P1, V3, V6]; xn--1ch1a29470f.xn----7uc5363rc1rn; ; ; # ≮≠.-𫠆ڷ𐹪
+≮≠񏻃。-𫠆ڷ𐹪; ≮≠񏻃.-𫠆ڷ𐹪; [B1, P1, V3, V6]; xn--1ch1a29470f.xn----7uc5363rc1rn; ; ; # ≮≠.-𫠆ڷ𐹪
+≮≠񏻃。-𫠆ڷ𐹪; ≮≠񏻃.-𫠆ڷ𐹪; [B1, P1, V3, V6]; xn--1ch1a29470f.xn----7uc5363rc1rn; ; ; # ≮≠.-𫠆ڷ𐹪
+≮≠񏻃。-𫠆ڷ𐹪; ≮≠񏻃.-𫠆ڷ𐹪; [B1, P1, V3, V6]; xn--1ch1a29470f.xn----7uc5363rc1rn; ; ; # ≮≠.-𫠆ڷ𐹪
+xn--1ch1a29470f.xn----7uc5363rc1rn; ≮≠񏻃.-𫠆ڷ𐹪; [B1, V3, V6]; xn--1ch1a29470f.xn----7uc5363rc1rn; ; ; # ≮≠.-𫠆ڷ𐹪
+𐹡ݷ。ꡂ; 𐹡ݷ.ꡂ; [B1]; xn--7pb5275k.xn--bc9a; ; ; # 𐹡ݷ.ꡂ
+xn--7pb5275k.xn--bc9a; 𐹡ݷ.ꡂ; [B1]; xn--7pb5275k.xn--bc9a; ; ; # 𐹡ݷ.ꡂ
+Ⴉ𝆅񔻅ؙ.ß𐧦𐹳ݵ; ; [B5, B6, P1, V6]; xn--7fb125cjv87a7xvz.xn--zca684a699vf2d; ; xn--7fb125cjv87a7xvz.xn--ss-zme7575xp0e; # Ⴉؙ𝆅.ß𐧦𐹳ݵ
+ⴉ𝆅񔻅ؙ.ß𐧦𐹳ݵ; ; [B5, B6, P1, V6]; xn--7fb940rwt3z7xvz.xn--zca684a699vf2d; ; xn--7fb940rwt3z7xvz.xn--ss-zme7575xp0e; # ⴉؙ𝆅.ß𐧦𐹳ݵ
+Ⴉ𝆅񔻅ؙ.SS𐧦𐹳ݵ; Ⴉ𝆅񔻅ؙ.ss𐧦𐹳ݵ; [B5, B6, P1, V6]; xn--7fb125cjv87a7xvz.xn--ss-zme7575xp0e; ; ; # Ⴉؙ𝆅.ss𐧦𐹳ݵ
+ⴉ𝆅񔻅ؙ.ss𐧦𐹳ݵ; ; [B5, B6, P1, V6]; xn--7fb940rwt3z7xvz.xn--ss-zme7575xp0e; ; ; # ⴉؙ𝆅.ss𐧦𐹳ݵ
+Ⴉ𝆅񔻅ؙ.Ss𐧦𐹳ݵ; Ⴉ𝆅񔻅ؙ.ss𐧦𐹳ݵ; [B5, B6, P1, V6]; xn--7fb125cjv87a7xvz.xn--ss-zme7575xp0e; ; ; # Ⴉؙ𝆅.ss𐧦𐹳ݵ
+xn--7fb125cjv87a7xvz.xn--ss-zme7575xp0e; Ⴉ𝆅񔻅ؙ.ss𐧦𐹳ݵ; [B5, B6, V6]; xn--7fb125cjv87a7xvz.xn--ss-zme7575xp0e; ; ; # Ⴉؙ𝆅.ss𐧦𐹳ݵ
+xn--7fb940rwt3z7xvz.xn--ss-zme7575xp0e; ⴉ𝆅񔻅ؙ.ss𐧦𐹳ݵ; [B5, B6, V6]; xn--7fb940rwt3z7xvz.xn--ss-zme7575xp0e; ; ; # ⴉؙ𝆅.ss𐧦𐹳ݵ
+xn--7fb940rwt3z7xvz.xn--zca684a699vf2d; ⴉ𝆅񔻅ؙ.ß𐧦𐹳ݵ; [B5, B6, V6]; xn--7fb940rwt3z7xvz.xn--zca684a699vf2d; ; ; # ⴉؙ𝆅.ß𐧦𐹳ݵ
+xn--7fb125cjv87a7xvz.xn--zca684a699vf2d; Ⴉ𝆅񔻅ؙ.ß𐧦𐹳ݵ; [B5, B6, V6]; xn--7fb125cjv87a7xvz.xn--zca684a699vf2d; ; ; # Ⴉؙ𝆅.ß𐧦𐹳ݵ
+‍ك𐧾↙.񊽡; ; [B1, C2, P1, V6]; xn--fhb713k87ag053c.xn--7s4w; ; xn--fhb011lnp8n.xn--7s4w; [B3, P1, V6] # ك𐧾↙.
+xn--fhb011lnp8n.xn--7s4w; ك𐧾↙.񊽡; [B3, V6]; xn--fhb011lnp8n.xn--7s4w; ; ; # ك𐧾↙.
+xn--fhb713k87ag053c.xn--7s4w; ‍ك𐧾↙.񊽡; [B1, C2, V6]; xn--fhb713k87ag053c.xn--7s4w; ; ; # ك𐧾↙.
+梉。‌; 梉.‌; [C1]; xn--7zv.xn--0ug; ; xn--7zv.; [] # 梉.
+xn--7zv.; 梉.; ; xn--7zv.; ; ; # 梉.
+梉.; ; ; xn--7zv.; ; ; # 梉.
+xn--7zv.xn--0ug; 梉.‌; [C1]; xn--7zv.xn--0ug; ; ; # 梉.
+ꡣ-≠.‍𞤗𐅢Ↄ; ꡣ-≠.‍𞤹𐅢Ↄ; [B1, B6, C2, P1, V6]; xn----ufo9661d.xn--1ug79cm620c71sh; ; xn----ufo9661d.xn--q5g0929fhm4f; [B2, B3, B6, P1, V6] # ꡣ-≠.𞤹𐅢Ↄ
+ꡣ-≠.‍𞤗𐅢Ↄ; ꡣ-≠.‍𞤹𐅢Ↄ; [B1, B6, C2, P1, V6]; xn----ufo9661d.xn--1ug79cm620c71sh; ; xn----ufo9661d.xn--q5g0929fhm4f; [B2, B3, B6, P1, V6] # ꡣ-≠.𞤹𐅢Ↄ
+ꡣ-≠.‍𞤹𐅢ↄ; ꡣ-≠.‍𞤹𐅢ↄ; [B1, B6, C2, P1, V6]; xn----ufo9661d.xn--1ug99cj620c71sh; ; xn----ufo9661d.xn--r5gy929fhm4f; [B2, B3, B6, P1, V6] # ꡣ-≠.𞤹𐅢ↄ
+ꡣ-≠.‍𞤹𐅢ↄ; ; [B1, B6, C2, P1, V6]; xn----ufo9661d.xn--1ug99cj620c71sh; ; xn----ufo9661d.xn--r5gy929fhm4f; [B2, B3, B6, P1, V6] # ꡣ-≠.𞤹𐅢ↄ
+ꡣ-≠.‍𞤗𐅢ↄ; ꡣ-≠.‍𞤹𐅢ↄ; [B1, B6, C2, P1, V6]; xn----ufo9661d.xn--1ug99cj620c71sh; ; xn----ufo9661d.xn--r5gy929fhm4f; [B2, B3, B6, P1, V6] # ꡣ-≠.𞤹𐅢ↄ
+ꡣ-≠.‍𞤗𐅢ↄ; ꡣ-≠.‍𞤹𐅢ↄ; [B1, B6, C2, P1, V6]; xn----ufo9661d.xn--1ug99cj620c71sh; ; xn----ufo9661d.xn--r5gy929fhm4f; [B2, B3, B6, P1, V6] # ꡣ-≠.𞤹𐅢ↄ
+xn----ufo9661d.xn--r5gy929fhm4f; ꡣ-≠.𞤹𐅢ↄ; [B2, B3, B6, V6]; xn----ufo9661d.xn--r5gy929fhm4f; ; ; # ꡣ-≠.𞤹𐅢ↄ
+xn----ufo9661d.xn--1ug99cj620c71sh; ꡣ-≠.‍𞤹𐅢ↄ; [B1, B6, C2, V6]; xn----ufo9661d.xn--1ug99cj620c71sh; ; ; # ꡣ-≠.𞤹𐅢ↄ
+xn----ufo9661d.xn--q5g0929fhm4f; ꡣ-≠.𞤹𐅢Ↄ; [B2, B3, B6, V6]; xn----ufo9661d.xn--q5g0929fhm4f; ; ; # ꡣ-≠.𞤹𐅢Ↄ
+xn----ufo9661d.xn--1ug79cm620c71sh; ꡣ-≠.‍𞤹𐅢Ↄ; [B1, B6, C2, V6]; xn----ufo9661d.xn--1ug79cm620c71sh; ; ; # ꡣ-≠.𞤹𐅢Ↄ
+ς⒐𝆫⸵。𐱢🄊𝟳; ς⒐𝆫⸵.𐱢🄊7; [B6, P1, V6]; xn--3xa019nwtghi25b.xn--7-075iy877c; ; xn--4xa809nwtghi25b.xn--7-075iy877c; # ς⒐𝆫⸵.🄊7
+ς9.𝆫⸵。𐱢9,7; ς9.𝆫⸵.𐱢9,7; [B1, P1, V5, V6]; xn--9-xmb.xn--ltj1535k.xn--9,7-r67t; ; xn--9-zmb.xn--ltj1535k.xn--9,7-r67t; # ς9.𝆫⸵.9,7
+Σ9.𝆫⸵。𐱢9,7; σ9.𝆫⸵.𐱢9,7; [B1, P1, V5, V6]; xn--9-zmb.xn--ltj1535k.xn--9,7-r67t; ; ; # σ9.𝆫⸵.9,7
+σ9.𝆫⸵。𐱢9,7; σ9.𝆫⸵.𐱢9,7; [B1, P1, V5, V6]; xn--9-zmb.xn--ltj1535k.xn--9,7-r67t; ; ; # σ9.𝆫⸵.9,7
+xn--9-zmb.xn--ltj1535k.xn--9,7-r67t; σ9.𝆫⸵.𐱢9,7; [B1, P1, V5, V6]; xn--9-zmb.xn--ltj1535k.xn--9,7-r67t; ; ; # σ9.𝆫⸵.9,7
+xn--9-xmb.xn--ltj1535k.xn--9,7-r67t; ς9.𝆫⸵.𐱢9,7; [B1, P1, V5, V6]; xn--9-xmb.xn--ltj1535k.xn--9,7-r67t; ; ; # ς9.𝆫⸵.9,7
+Σ⒐𝆫⸵。𐱢🄊𝟳; σ⒐𝆫⸵.𐱢🄊7; [B6, P1, V6]; xn--4xa809nwtghi25b.xn--7-075iy877c; ; ; # σ⒐𝆫⸵.🄊7
+σ⒐𝆫⸵。𐱢🄊𝟳; σ⒐𝆫⸵.𐱢🄊7; [B6, P1, V6]; xn--4xa809nwtghi25b.xn--7-075iy877c; ; ; # σ⒐𝆫⸵.🄊7
+xn--4xa809nwtghi25b.xn--7-075iy877c; σ⒐𝆫⸵.𐱢🄊7; [B6, V6]; xn--4xa809nwtghi25b.xn--7-075iy877c; ; ; # σ⒐𝆫⸵.🄊7
+xn--3xa019nwtghi25b.xn--7-075iy877c; ς⒐𝆫⸵.𐱢🄊7; [B6, V6]; xn--3xa019nwtghi25b.xn--7-075iy877c; ; ; # ς⒐𝆫⸵.🄊7
+ࡓ.‌ß; ࡓ.‌ß; [B1, C1]; xn--iwb.xn--zca570n; ; xn--iwb.ss; [] # ࡓ.ß
+ࡓ.‌ß; ; [B1, C1]; xn--iwb.xn--zca570n; ; xn--iwb.ss; [] # ࡓ.ß
+ࡓ.‌SS; ࡓ.‌ss; [B1, C1]; xn--iwb.xn--ss-i1t; ; xn--iwb.ss; [] # ࡓ.ss
+ࡓ.‌ss; ; [B1, C1]; xn--iwb.xn--ss-i1t; ; xn--iwb.ss; [] # ࡓ.ss
+xn--iwb.ss; ࡓ.ss; ; xn--iwb.ss; ; ; # ࡓ.ss
+ࡓ.ss; ; ; xn--iwb.ss; ; ; # ࡓ.ss
+ࡓ.SS; ࡓ.ss; ; xn--iwb.ss; ; ; # ࡓ.ss
+xn--iwb.xn--ss-i1t; ࡓ.‌ss; [B1, C1]; xn--iwb.xn--ss-i1t; ; ; # ࡓ.ss
+xn--iwb.xn--zca570n; ࡓ.‌ß; [B1, C1]; xn--iwb.xn--zca570n; ; ; # ࡓ.ß
+ࡓ.‌SS; ࡓ.‌ss; [B1, C1]; xn--iwb.xn--ss-i1t; ; xn--iwb.ss; [] # ࡓ.ss
+ࡓ.‌ss; ࡓ.‌ss; [B1, C1]; xn--iwb.xn--ss-i1t; ; xn--iwb.ss; [] # ࡓ.ss
+ࡓ.‌Ss; ࡓ.‌ss; [B1, C1]; xn--iwb.xn--ss-i1t; ; xn--iwb.ss; [] # ࡓ.ss
+ࡓ.‌Ss; ࡓ.‌ss; [B1, C1]; xn--iwb.xn--ss-i1t; ; xn--iwb.ss; [] # ࡓ.ss
+񯶣-.‍ݎꥍ󠻨; ; [B1, B6, C2, P1, V3, V6]; xn----s116e.xn--1ob387jy90hq459k; ; xn----s116e.xn--1ob6504fmf40i; [B3, B6, P1, V3, V6] # -.ݎꥍ
+xn----s116e.xn--1ob6504fmf40i; 񯶣-.ݎꥍ󠻨; [B3, B6, V3, V6]; xn----s116e.xn--1ob6504fmf40i; ; ; # -.ݎꥍ
+xn----s116e.xn--1ob387jy90hq459k; 񯶣-.‍ݎꥍ󠻨; [B1, B6, C2, V3, V6]; xn----s116e.xn--1ob387jy90hq459k; ; ; # -.ݎꥍ
+䃚蟥-。-񽒘⒈; 䃚蟥-.-񽒘⒈; [P1, V3, V6]; xn----n50a258u.xn----ecp33805f; ; ; # 䃚蟥-.-⒈
+䃚蟥-。-񽒘1.; 䃚蟥-.-񽒘1.; [P1, V3, V6]; xn----n50a258u.xn---1-up07j.; ; ; # 䃚蟥-.-1.
+xn----n50a258u.xn---1-up07j.; 䃚蟥-.-񽒘1.; [V3, V6]; xn----n50a258u.xn---1-up07j.; ; ; # 䃚蟥-.-1.
+xn----n50a258u.xn----ecp33805f; 䃚蟥-.-񽒘⒈; [V3, V6]; xn----n50a258u.xn----ecp33805f; ; ; # 䃚蟥-.-⒈
+𐹸䚵-ꡡ。⺇; 𐹸䚵-ꡡ.⺇; [B1]; xn----bm3an932a1l5d.xn--xvj; ; ; # 𐹸䚵-ꡡ.⺇
+xn----bm3an932a1l5d.xn--xvj; 𐹸䚵-ꡡ.⺇; [B1]; xn----bm3an932a1l5d.xn--xvj; ; ; # 𐹸䚵-ꡡ.⺇
+𑄳。᫜𐹻; 𑄳.᫜𐹻; [B1, B3, B5, B6, P1, V5, V6]; xn--v80d.xn--2rf1154i; ; ; # 𑄳.𐹻
+xn--v80d.xn--2rf1154i; 𑄳.᫜𐹻; [B1, B3, B5, B6, V5, V6]; xn--v80d.xn--2rf1154i; ; ; # 𑄳.𐹻
+≮𐹻.⒎𑂵ں؂; ; [B1, P1, V6]; xn--gdhx904g.xn--kfb18a325efm3s; ; ; # ≮𐹻.⒎𑂵ں
+≮𐹻.⒎𑂵ں؂; ≮𐹻.⒎𑂵ں؂; [B1, P1, V6]; xn--gdhx904g.xn--kfb18a325efm3s; ; ; # ≮𐹻.⒎𑂵ں
+≮𐹻.7.𑂵ں؂; ; [B1, P1, V5, V6]; xn--gdhx904g.7.xn--kfb18an307d; ; ; # ≮𐹻.7.𑂵ں
+≮𐹻.7.𑂵ں؂; ≮𐹻.7.𑂵ں؂; [B1, P1, V5, V6]; xn--gdhx904g.7.xn--kfb18an307d; ; ; # ≮𐹻.7.𑂵ں
+xn--gdhx904g.7.xn--kfb18an307d; ≮𐹻.7.𑂵ں؂; [B1, V5, V6]; xn--gdhx904g.7.xn--kfb18an307d; ; ; # ≮𐹻.7.𑂵ں
+xn--gdhx904g.xn--kfb18a325efm3s; ≮𐹻.⒎𑂵ں؂; [B1, V6]; xn--gdhx904g.xn--kfb18a325efm3s; ; ; # ≮𐹻.⒎𑂵ں
+ᢔ≠􋉂.‍𐋢; ; [C2, P1, V6]; xn--ebf031cf7196a.xn--1ug9540g; ; xn--ebf031cf7196a.xn--587c; [P1, V6] # ᢔ≠.𐋢
+ᢔ≠􋉂.‍𐋢; ᢔ≠􋉂.‍𐋢; [C2, P1, V6]; xn--ebf031cf7196a.xn--1ug9540g; ; xn--ebf031cf7196a.xn--587c; [P1, V6] # ᢔ≠.𐋢
+xn--ebf031cf7196a.xn--587c; ᢔ≠􋉂.𐋢; [V6]; xn--ebf031cf7196a.xn--587c; ; ; # ᢔ≠.𐋢
+xn--ebf031cf7196a.xn--1ug9540g; ᢔ≠􋉂.‍𐋢; [C2, V6]; xn--ebf031cf7196a.xn--1ug9540g; ; ; # ᢔ≠.𐋢
+𐩁≮񣊛≯.٬𞵕⳿; 𐩁≮񣊛≯.٬𞵕⳿; [B1, B2, B3, P1, V6]; xn--gdhc0519o0y27b.xn--lib468q0d21a; ; ; # 𐩁≮≯.٬⳿
+𐩁≮񣊛≯.٬𞵕⳿; 𐩁≮񣊛≯.٬𞵕⳿; [B1, B2, B3, P1, V6]; xn--gdhc0519o0y27b.xn--lib468q0d21a; ; ; # 𐩁≮≯.٬⳿
+𐩁≮񣊛≯.٬𞵕⳿; ; [B1, B2, B3, P1, V6]; xn--gdhc0519o0y27b.xn--lib468q0d21a; ; ; # 𐩁≮≯.٬⳿
+𐩁≮񣊛≯.٬𞵕⳿; 𐩁≮񣊛≯.٬𞵕⳿; [B1, B2, B3, P1, V6]; xn--gdhc0519o0y27b.xn--lib468q0d21a; ; ; # 𐩁≮≯.٬⳿
+xn--gdhc0519o0y27b.xn--lib468q0d21a; 𐩁≮񣊛≯.٬𞵕⳿; [B1, B2, B3, V6]; xn--gdhc0519o0y27b.xn--lib468q0d21a; ; ; # 𐩁≮≯.٬⳿
+-。⺐; -.⺐; [V3]; -.xn--6vj; ; ; # -.⺐
+-。⺐; -.⺐; [V3]; -.xn--6vj; ; ; # -.⺐
+-.xn--6vj; -.⺐; [V3]; -.xn--6vj; ; ; # -.⺐
+󠰩𑲬.ٜ; 󠰩𑲬.ٜ; [P1, V5, V6]; xn--sn3d59267c.xn--4hb; ; ; # 𑲬.ٜ
+󠰩𑲬.ٜ; ; [P1, V5, V6]; xn--sn3d59267c.xn--4hb; ; ; # 𑲬.ٜ
+xn--sn3d59267c.xn--4hb; 󠰩𑲬.ٜ; [V5, V6]; xn--sn3d59267c.xn--4hb; ; ; # 𑲬.ٜ
+𐍺.񚇃‌; ; [C1, P1, V5, V6]; xn--ie8c.xn--0ug03366c; ; xn--ie8c.xn--2g51a; [P1, V5, V6] # 𐍺.
+xn--ie8c.xn--2g51a; 𐍺.񚇃; [V5, V6]; xn--ie8c.xn--2g51a; ; ; # 𐍺.
+xn--ie8c.xn--0ug03366c; 𐍺.񚇃‌; [C1, V5, V6]; xn--ie8c.xn--0ug03366c; ; ; # 𐍺.
+ؽۣ.𐨎; ; [B1, B3, B6, V5]; xn--8gb64a.xn--mr9c; ; ; # ؽۣ.𐨎
+xn--8gb64a.xn--mr9c; ؽۣ.𐨎; [B1, B3, B6, V5]; xn--8gb64a.xn--mr9c; ; ; # ؽۣ.𐨎
+漦Ⴙς.񡻀𐴄; ; [B5, B6, P1, V6]; xn--3xa157d717e.xn--9d0d3162t; ; xn--4xa947d717e.xn--9d0d3162t; # 漦Ⴙς.𐴄
+漦ⴙς.񡻀𐴄; ; [B5, B6, P1, V6]; xn--3xa972sl47b.xn--9d0d3162t; ; xn--4xa772sl47b.xn--9d0d3162t; # 漦ⴙς.𐴄
+漦ႹΣ.񡻀𐴄; 漦Ⴙσ.񡻀𐴄; [B5, B6, P1, V6]; xn--4xa947d717e.xn--9d0d3162t; ; ; # 漦Ⴙσ.𐴄
+漦ⴙσ.񡻀𐴄; ; [B5, B6, P1, V6]; xn--4xa772sl47b.xn--9d0d3162t; ; ; # 漦ⴙσ.𐴄
+漦Ⴙσ.񡻀𐴄; ; [B5, B6, P1, V6]; xn--4xa947d717e.xn--9d0d3162t; ; ; # 漦Ⴙσ.𐴄
+xn--4xa947d717e.xn--9d0d3162t; 漦Ⴙσ.񡻀𐴄; [B5, B6, V6]; xn--4xa947d717e.xn--9d0d3162t; ; ; # 漦Ⴙσ.𐴄
+xn--4xa772sl47b.xn--9d0d3162t; 漦ⴙσ.񡻀𐴄; [B5, B6, V6]; xn--4xa772sl47b.xn--9d0d3162t; ; ; # 漦ⴙσ.𐴄
+xn--3xa972sl47b.xn--9d0d3162t; 漦ⴙς.񡻀𐴄; [B5, B6, V6]; xn--3xa972sl47b.xn--9d0d3162t; ; ; # 漦ⴙς.𐴄
+xn--3xa157d717e.xn--9d0d3162t; 漦Ⴙς.񡻀𐴄; [B5, B6, V6]; xn--3xa157d717e.xn--9d0d3162t; ; ; # 漦Ⴙς.𐴄
+𐹫踧್򫚇.󜀃⒈𝨤; ; [B1, P1, V6]; xn--8tc1437dro0d6q06h.xn--tsh2611ncu71e; ; ; # 𐹫踧್.⒈𝨤
+𐹫踧್򫚇.󜀃1.𝨤; ; [B1, B3, B6, P1, V5, V6]; xn--8tc1437dro0d6q06h.xn--1-p948l.xn--m82h; ; ; # 𐹫踧್.1.𝨤
+xn--8tc1437dro0d6q06h.xn--1-p948l.xn--m82h; 𐹫踧್򫚇.󜀃1.𝨤; [B1, B3, B6, V5, V6]; xn--8tc1437dro0d6q06h.xn--1-p948l.xn--m82h; ; ; # 𐹫踧್.1.𝨤
+xn--8tc1437dro0d6q06h.xn--tsh2611ncu71e; 𐹫踧್򫚇.󜀃⒈𝨤; [B1, V6]; xn--8tc1437dro0d6q06h.xn--tsh2611ncu71e; ; ; # 𐹫踧್.⒈𝨤
+‍≮.󠟪𹫏-; ‍≮.󠟪𹫏-; [C2, P1, V3, V6]; xn--1ug95g.xn----cr99a1w710b; ; xn--gdh.xn----cr99a1w710b; [P1, V3, V6] # ≮.-
+‍≮.󠟪𹫏-; ‍≮.󠟪𹫏-; [C2, P1, V3, V6]; xn--1ug95g.xn----cr99a1w710b; ; xn--gdh.xn----cr99a1w710b; [P1, V3, V6] # ≮.-
+‍≮.󠟪𹫏-; ; [C2, P1, V3, V6]; xn--1ug95g.xn----cr99a1w710b; ; xn--gdh.xn----cr99a1w710b; [P1, V3, V6] # ≮.-
+‍≮.󠟪𹫏-; ‍≮.󠟪𹫏-; [C2, P1, V3, V6]; xn--1ug95g.xn----cr99a1w710b; ; xn--gdh.xn----cr99a1w710b; [P1, V3, V6] # ≮.-
+xn--gdh.xn----cr99a1w710b; ≮.󠟪𹫏-; [V3, V6]; xn--gdh.xn----cr99a1w710b; ; ; # ≮.-
+xn--1ug95g.xn----cr99a1w710b; ‍≮.󠟪𹫏-; [C2, V3, V6]; xn--1ug95g.xn----cr99a1w710b; ; ; # ≮.-
+‍‍襔。Ⴜ5ꡮ񵝏; ‍‍襔.Ⴜ5ꡮ񵝏; [C2, P1, V6]; xn--1uga7691f.xn--5-r1g7167ipfw8d; ; xn--2u2a.xn--5-r1g7167ipfw8d; [P1, V6] # 襔.Ⴜ5ꡮ
+‍‍襔。ⴜ5ꡮ񵝏; ‍‍襔.ⴜ5ꡮ񵝏; [C2, P1, V6]; xn--1uga7691f.xn--5-uws5848bpf44e; ; xn--2u2a.xn--5-uws5848bpf44e; [P1, V6] # 襔.ⴜ5ꡮ
+xn--2u2a.xn--5-uws5848bpf44e; 襔.ⴜ5ꡮ񵝏; [V6]; xn--2u2a.xn--5-uws5848bpf44e; ; ; # 襔.ⴜ5ꡮ
+xn--1uga7691f.xn--5-uws5848bpf44e; ‍‍襔.ⴜ5ꡮ񵝏; [C2, V6]; xn--1uga7691f.xn--5-uws5848bpf44e; ; ; # 襔.ⴜ5ꡮ
+xn--2u2a.xn--5-r1g7167ipfw8d; 襔.Ⴜ5ꡮ񵝏; [V6]; xn--2u2a.xn--5-r1g7167ipfw8d; ; ; # 襔.Ⴜ5ꡮ
+xn--1uga7691f.xn--5-r1g7167ipfw8d; ‍‍襔.Ⴜ5ꡮ񵝏; [C2, V6]; xn--1uga7691f.xn--5-r1g7167ipfw8d; ; ; # 襔.Ⴜ5ꡮ
+𐫜𑌼‍.婀; 𐫜𑌼‍.婀; [B3, C2]; xn--1ugx063g1if.xn--q0s; ; xn--ix9c26l.xn--q0s; [] # 𐫜𑌼.婀
+𐫜𑌼‍.婀; ; [B3, C2]; xn--1ugx063g1if.xn--q0s; ; xn--ix9c26l.xn--q0s; [] # 𐫜𑌼.婀
+xn--ix9c26l.xn--q0s; 𐫜𑌼.婀; ; xn--ix9c26l.xn--q0s; ; ; # 𐫜𑌼.婀
+𐫜𑌼.婀; ; ; xn--ix9c26l.xn--q0s; ; ; # 𐫜𑌼.婀
+xn--1ugx063g1if.xn--q0s; 𐫜𑌼‍.婀; [B3, C2]; xn--1ugx063g1if.xn--q0s; ; ; # 𐫜𑌼.婀
+󠅽︒︒𐹯。⬳᩸; ︒︒𐹯.⬳᩸; [B1, P1, V6]; xn--y86ca186j.xn--7of309e; ; ; # ︒︒𐹯.⬳᩸
+󠅽。。𐹯。⬳᩸; ..𐹯.⬳᩸; [B1, X4_2]; ..xn--no0d.xn--7of309e; [B1, A4_2]; ; # ..𐹯.⬳᩸
+..xn--no0d.xn--7of309e; ..𐹯.⬳᩸; [B1, X4_2]; ..xn--no0d.xn--7of309e; [B1, A4_2]; ; # ..𐹯.⬳᩸
+xn--y86ca186j.xn--7of309e; ︒︒𐹯.⬳᩸; [B1, V6]; xn--y86ca186j.xn--7of309e; ; ; # ︒︒𐹯.⬳᩸
+𝟖ß.󠄐-?Ⴏ; 8ß.-?Ⴏ; [P1, V3, V6]; xn--8-qfa.xn---?-gfk; ; 8ss.xn---?-gfk; # 8ß.-?Ⴏ
+8ß.󠄐-?Ⴏ; 8ß.-?Ⴏ; [P1, V3, V6]; xn--8-qfa.xn---?-gfk; ; 8ss.xn---?-gfk; # 8ß.-?Ⴏ
+8ß.󠄐-?ⴏ; 8ß.-?ⴏ; [P1, V3, V6]; xn--8-qfa.xn---?-261a; ; 8ss.xn---?-261a; # 8ß.-?ⴏ
+8SS.󠄐-?Ⴏ; 8ss.-?Ⴏ; [P1, V3, V6]; 8ss.xn---?-gfk; ; ; # 8ss.-?Ⴏ
+8ss.󠄐-?ⴏ; 8ss.-?ⴏ; [P1, V3, V6]; 8ss.xn---?-261a; ; ; # 8ss.-?ⴏ
+8ss.󠄐-?Ⴏ; 8ss.-?Ⴏ; [P1, V3, V6]; 8ss.xn---?-gfk; ; ; # 8ss.-?Ⴏ
+8ss.xn---?-gfk; 8ss.-?Ⴏ; [P1, V3, V6]; 8ss.xn---?-gfk; ; ; # 8ss.-?Ⴏ
+8ss.xn---?-261a; 8ss.-?ⴏ; [P1, V3, V6]; 8ss.xn---?-261a; ; ; # 8ss.-?ⴏ
+xn--8-qfa.xn---?-261a; 8ß.-?ⴏ; [P1, V3, V6]; xn--8-qfa.xn---?-261a; ; ; # 8ß.-?ⴏ
+xn--8-qfa.xn---?-gfk; 8ß.-?Ⴏ; [P1, V3, V6]; xn--8-qfa.xn---?-gfk; ; ; # 8ß.-?Ⴏ
+𝟖ß.󠄐-?ⴏ; 8ß.-?ⴏ; [P1, V3, V6]; xn--8-qfa.xn---?-261a; ; 8ss.xn---?-261a; # 8ß.-?ⴏ
+𝟖SS.󠄐-?Ⴏ; 8ss.-?Ⴏ; [P1, V3, V6]; 8ss.xn---?-gfk; ; ; # 8ss.-?Ⴏ
+𝟖ss.󠄐-?ⴏ; 8ss.-?ⴏ; [P1, V3, V6]; 8ss.xn---?-261a; ; ; # 8ss.-?ⴏ
+𝟖ss.󠄐-?Ⴏ; 8ss.-?Ⴏ; [P1, V3, V6]; 8ss.xn---?-gfk; ; ; # 8ss.-?Ⴏ
+8ss.-?Ⴏ; ; [P1, V3, V6]; 8ss.xn---?-gfk; ; ; # 8ss.-?Ⴏ
+8ss.-?ⴏ; ; [P1, V3, V6]; 8ss.xn---?-261a; ; ; # 8ss.-?ⴏ
+8SS.-?Ⴏ; 8ss.-?Ⴏ; [P1, V3, V6]; 8ss.xn---?-gfk; ; ; # 8ss.-?Ⴏ
+xn--8-qfa.-?ⴏ; 8ß.-?ⴏ; [P1, V3, V6]; xn--8-qfa.xn---?-261a; ; ; # 8ß.-?ⴏ
+XN--8-QFA.-?Ⴏ; 8ß.-?Ⴏ; [P1, V3, V6]; xn--8-qfa.xn---?-gfk; ; ; # 8ß.-?Ⴏ
+Xn--8-Qfa.-?Ⴏ; 8ß.-?Ⴏ; [P1, V3, V6]; xn--8-qfa.xn---?-gfk; ; ; # 8ß.-?Ⴏ
+xn--8-qfa.-?Ⴏ; 8ß.-?Ⴏ; [P1, V3, V6]; xn--8-qfa.xn---?-gfk; ; ; # 8ß.-?Ⴏ
+𝟖Ss.󠄐-?Ⴏ; 8ss.-?Ⴏ; [P1, V3, V6]; 8ss.xn---?-gfk; ; ; # 8ss.-?Ⴏ
+8Ss.󠄐-?Ⴏ; 8ss.-?Ⴏ; [P1, V3, V6]; 8ss.xn---?-gfk; ; ; # 8ss.-?Ⴏ
+-‍󠋟.‌𐹣Ⴅ; ; [B1, C1, C2, P1, V3, V6]; xn----ugnv7071n.xn--dnd999e4j4p; ; xn----s721m.xn--dnd9201k; [B1, P1, V3, V6] # -.𐹣Ⴅ
+-‍󠋟.‌𐹣ⴅ; ; [B1, C1, C2, P1, V3, V6]; xn----ugnv7071n.xn--0ugz32cgr0p; ; xn----s721m.xn--wkj1423e; [B1, P1, V3, V6] # -.𐹣ⴅ
+xn----s721m.xn--wkj1423e; -󠋟.𐹣ⴅ; [B1, V3, V6]; xn----s721m.xn--wkj1423e; ; ; # -.𐹣ⴅ
+xn----ugnv7071n.xn--0ugz32cgr0p; -‍󠋟.‌𐹣ⴅ; [B1, C1, C2, V3, V6]; xn----ugnv7071n.xn--0ugz32cgr0p; ; ; # -.𐹣ⴅ
+xn----s721m.xn--dnd9201k; -󠋟.𐹣Ⴅ; [B1, V3, V6]; xn----s721m.xn--dnd9201k; ; ; # -.𐹣Ⴅ
+xn----ugnv7071n.xn--dnd999e4j4p; -‍󠋟.‌𐹣Ⴅ; [B1, C1, C2, V3, V6]; xn----ugnv7071n.xn--dnd999e4j4p; ; ; # -.𐹣Ⴅ
+ꦹ‍큷𻶡。₂; ꦹ‍큷𻶡.2; [C2, P1, V5, V6]; xn--1ug1435cfkyaoi04d.2; ; xn--0m9as84e2e21c.2; [P1, V5, V6] # ꦹ큷.2
+ꦹ‍큷𻶡。₂; ꦹ‍큷𻶡.2; [C2, P1, V5, V6]; xn--1ug1435cfkyaoi04d.2; ; xn--0m9as84e2e21c.2; [P1, V5, V6] # ꦹ큷.2
+ꦹ‍큷𻶡。2; ꦹ‍큷𻶡.2; [C2, P1, V5, V6]; xn--1ug1435cfkyaoi04d.2; ; xn--0m9as84e2e21c.2; [P1, V5, V6] # ꦹ큷.2
+ꦹ‍큷𻶡。2; ꦹ‍큷𻶡.2; [C2, P1, V5, V6]; xn--1ug1435cfkyaoi04d.2; ; xn--0m9as84e2e21c.2; [P1, V5, V6] # ꦹ큷.2
+xn--0m9as84e2e21c.2; ꦹ큷𻶡.2; [V5, V6]; xn--0m9as84e2e21c.2; ; ; # ꦹ큷.2
+xn--1ug1435cfkyaoi04d.2; ꦹ‍큷𻶡.2; [C2, V5, V6]; xn--1ug1435cfkyaoi04d.2; ; ; # ꦹ큷.2
+?.🄄𞯘; ; [B1, P1, V6]; ?.xn--3x6hx6f; ; ; # ?.🄄
+?.3,𞯘; ; [B1, P1, V6]; ?.xn--3,-tb22a; ; ; # ?.3,
+?.xn--3,-tb22a; ?.3,𞯘; [B1, P1, V6]; ?.xn--3,-tb22a; ; ; # ?.3,
+?.xn--3x6hx6f; ?.🄄𞯘; [B1, P1, V6]; ?.xn--3x6hx6f; ; ; # ?.🄄
+𝨖𐩙。۝󀡶ꣅ⒈; 𝨖𐩙.۝󀡶ꣅ⒈; [B1, P1, V5, V6]; xn--rt9cl956a.xn--tlb403mxv4g06s9i; ; ; # 𝨖.ꣅ⒈
+𝨖𐩙。۝󀡶ꣅ1.; 𝨖𐩙.۝󀡶ꣅ1.; [B1, P1, V5, V6]; xn--rt9cl956a.xn--1-dxc8545j0693i.; ; ; # 𝨖.ꣅ1.
+xn--rt9cl956a.xn--1-dxc8545j0693i.; 𝨖𐩙.۝󀡶ꣅ1.; [B1, V5, V6]; xn--rt9cl956a.xn--1-dxc8545j0693i.; ; ; # 𝨖.ꣅ1.
+xn--rt9cl956a.xn--tlb403mxv4g06s9i; 𝨖𐩙.۝󀡶ꣅ⒈; [B1, V5, V6]; xn--rt9cl956a.xn--tlb403mxv4g06s9i; ; ; # 𝨖.ꣅ⒈
+򒈣סڸ。Ⴈ‍; 򒈣סڸ.Ⴈ‍; [B5, B6, C2, P1, V6]; xn--meb44b57607c.xn--gnd699e; ; xn--meb44b57607c.xn--gnd; [B5, B6, P1, V6] # סڸ.Ⴈ
+򒈣סڸ。ⴈ‍; 򒈣סڸ.ⴈ‍; [B5, B6, C2, P1, V6]; xn--meb44b57607c.xn--1ug232c; ; xn--meb44b57607c.xn--zkj; [B5, B6, P1, V6] # סڸ.ⴈ
+xn--meb44b57607c.xn--zkj; 򒈣סڸ.ⴈ; [B5, B6, V6]; xn--meb44b57607c.xn--zkj; ; ; # סڸ.ⴈ
+xn--meb44b57607c.xn--1ug232c; 򒈣סڸ.ⴈ‍; [B5, B6, C2, V6]; xn--meb44b57607c.xn--1ug232c; ; ; # סڸ.ⴈ
+xn--meb44b57607c.xn--gnd; 򒈣סڸ.Ⴈ; [B5, B6, V6]; xn--meb44b57607c.xn--gnd; ; ; # סڸ.Ⴈ
+xn--meb44b57607c.xn--gnd699e; 򒈣סڸ.Ⴈ‍; [B5, B6, C2, V6]; xn--meb44b57607c.xn--gnd699e; ; ; # סڸ.Ⴈ
+󀚶𝨱ߦ⒈.𑗝髯‌; 󀚶𝨱ߦ⒈.𑗝髯‌; [B1, B5, C1, P1, V5, V6]; xn--etb477lq931a1f58e.xn--0ugx259bocxd; ; xn--etb477lq931a1f58e.xn--uj6at43v; [B1, B5, P1, V5, V6] # 𝨱ߦ⒈.𑗝髯
+󀚶𝨱ߦ1..𑗝髯‌; ; [B1, B5, C1, P1, V5, V6, X4_2]; xn--1-idd62296a1fr6e..xn--0ugx259bocxd; [B1, B5, C1, P1, V5, V6, A4_2]; xn--1-idd62296a1fr6e..xn--uj6at43v; [B1, B5, P1, V5, V6, A4_2] # 𝨱ߦ1..𑗝髯
+xn--1-idd62296a1fr6e..xn--uj6at43v; 󀚶𝨱ߦ1..𑗝髯; [B1, B5, V5, V6, X4_2]; xn--1-idd62296a1fr6e..xn--uj6at43v; [B1, B5, V5, V6, A4_2]; ; # 𝨱ߦ1..𑗝髯
+xn--1-idd62296a1fr6e..xn--0ugx259bocxd; 󀚶𝨱ߦ1..𑗝髯‌; [B1, B5, C1, V5, V6, X4_2]; xn--1-idd62296a1fr6e..xn--0ugx259bocxd; [B1, B5, C1, V5, V6, A4_2]; ; # 𝨱ߦ1..𑗝髯
+xn--etb477lq931a1f58e.xn--uj6at43v; 󀚶𝨱ߦ⒈.𑗝髯; [B1, B5, V5, V6]; xn--etb477lq931a1f58e.xn--uj6at43v; ; ; # 𝨱ߦ⒈.𑗝髯
+xn--etb477lq931a1f58e.xn--0ugx259bocxd; 󀚶𝨱ߦ⒈.𑗝髯‌; [B1, B5, C1, V5, V6]; xn--etb477lq931a1f58e.xn--0ugx259bocxd; ; ; # 𝨱ߦ⒈.𑗝髯
+𐫀.ډ𑌀; 𐫀.ډ𑌀; ; xn--pw9c.xn--fjb8658k; ; ; # 𐫀.ډ𑌀
+𐫀.ډ𑌀; ; ; xn--pw9c.xn--fjb8658k; ; ; # 𐫀.ډ𑌀
+xn--pw9c.xn--fjb8658k; 𐫀.ډ𑌀; ; xn--pw9c.xn--fjb8658k; ; ; # 𐫀.ډ𑌀
+𑋪.𐳝; 𑋪.𐳝; [B1, B3, B6, V5]; xn--fm1d.xn--5c0d; ; ; # 𑋪.𐳝
+𑋪.𐳝; ; [B1, B3, B6, V5]; xn--fm1d.xn--5c0d; ; ; # 𑋪.𐳝
+𑋪.𐲝; 𑋪.𐳝; [B1, B3, B6, V5]; xn--fm1d.xn--5c0d; ; ; # 𑋪.𐳝
+xn--fm1d.xn--5c0d; 𑋪.𐳝; [B1, B3, B6, V5]; xn--fm1d.xn--5c0d; ; ; # 𑋪.𐳝
+𑋪.𐲝; 𑋪.𐳝; [B1, B3, B6, V5]; xn--fm1d.xn--5c0d; ; ; # 𑋪.𐳝
+≠膣。ྃ; ≠膣.ྃ; [P1, V5, V6]; xn--1chy468a.xn--2ed; ; ; # ≠膣.ྃ
+≠膣。ྃ; ≠膣.ྃ; [P1, V5, V6]; xn--1chy468a.xn--2ed; ; ; # ≠膣.ྃ
+xn--1chy468a.xn--2ed; ≠膣.ྃ; [V5, V6]; xn--1chy468a.xn--2ed; ; ; # ≠膣.ྃ
+񰀎-ݽ。ß; 񰀎-ݽ.ß; [B5, B6, P1, V6]; xn----j6c95618k.xn--zca; ; xn----j6c95618k.ss; # -ݽ.ß
+񰀎-ݽ。ß; 񰀎-ݽ.ß; [B5, B6, P1, V6]; xn----j6c95618k.xn--zca; ; xn----j6c95618k.ss; # -ݽ.ß
+񰀎-ݽ。SS; 񰀎-ݽ.ss; [B5, B6, P1, V6]; xn----j6c95618k.ss; ; ; # -ݽ.ss
+񰀎-ݽ。ss; 񰀎-ݽ.ss; [B5, B6, P1, V6]; xn----j6c95618k.ss; ; ; # -ݽ.ss
+񰀎-ݽ。Ss; 񰀎-ݽ.ss; [B5, B6, P1, V6]; xn----j6c95618k.ss; ; ; # -ݽ.ss
+xn----j6c95618k.ss; 񰀎-ݽ.ss; [B5, B6, V6]; xn----j6c95618k.ss; ; ; # -ݽ.ss
+xn----j6c95618k.xn--zca; 񰀎-ݽ.ß; [B5, B6, V6]; xn----j6c95618k.xn--zca; ; ; # -ݽ.ß
+񰀎-ݽ。SS; 񰀎-ݽ.ss; [B5, B6, P1, V6]; xn----j6c95618k.ss; ; ; # -ݽ.ss
+񰀎-ݽ。ss; 񰀎-ݽ.ss; [B5, B6, P1, V6]; xn----j6c95618k.ss; ; ; # -ݽ.ss
+񰀎-ݽ。Ss; 񰀎-ݽ.ss; [B5, B6, P1, V6]; xn----j6c95618k.ss; ; ; # -ݽ.ss
+ς𐹠ᡚ𑄳.⾭𐹽𽐖𐫜; ς𐹠ᡚ𑄳.靑𐹽𽐖𐫜; [B5, B6, P1, V6]; xn--3xa856hp23pxmc.xn--es5a888tvjc2u15h; ; xn--4xa656hp23pxmc.xn--es5a888tvjc2u15h; # ς𐹠ᡚ𑄳.靑𐹽𐫜
+ς𐹠ᡚ𑄳.靑𐹽𽐖𐫜; ; [B5, B6, P1, V6]; xn--3xa856hp23pxmc.xn--es5a888tvjc2u15h; ; xn--4xa656hp23pxmc.xn--es5a888tvjc2u15h; # ς𐹠ᡚ𑄳.靑𐹽𐫜
+Σ𐹠ᡚ𑄳.靑𐹽𽐖𐫜; σ𐹠ᡚ𑄳.靑𐹽𽐖𐫜; [B5, B6, P1, V6]; xn--4xa656hp23pxmc.xn--es5a888tvjc2u15h; ; ; # σ𐹠ᡚ𑄳.靑𐹽𐫜
+σ𐹠ᡚ𑄳.靑𐹽𽐖𐫜; ; [B5, B6, P1, V6]; xn--4xa656hp23pxmc.xn--es5a888tvjc2u15h; ; ; # σ𐹠ᡚ𑄳.靑𐹽𐫜
+xn--4xa656hp23pxmc.xn--es5a888tvjc2u15h; σ𐹠ᡚ𑄳.靑𐹽𽐖𐫜; [B5, B6, V6]; xn--4xa656hp23pxmc.xn--es5a888tvjc2u15h; ; ; # σ𐹠ᡚ𑄳.靑𐹽𐫜
+xn--3xa856hp23pxmc.xn--es5a888tvjc2u15h; ς𐹠ᡚ𑄳.靑𐹽𽐖𐫜; [B5, B6, V6]; xn--3xa856hp23pxmc.xn--es5a888tvjc2u15h; ; ; # ς𐹠ᡚ𑄳.靑𐹽𐫜
+Σ𐹠ᡚ𑄳.⾭𐹽𽐖𐫜; σ𐹠ᡚ𑄳.靑𐹽𽐖𐫜; [B5, B6, P1, V6]; xn--4xa656hp23pxmc.xn--es5a888tvjc2u15h; ; ; # σ𐹠ᡚ𑄳.靑𐹽𐫜
+σ𐹠ᡚ𑄳.⾭𐹽𽐖𐫜; σ𐹠ᡚ𑄳.靑𐹽𽐖𐫜; [B5, B6, P1, V6]; xn--4xa656hp23pxmc.xn--es5a888tvjc2u15h; ; ; # σ𐹠ᡚ𑄳.靑𐹽𐫜
+𐋷。‍; 𐋷.‍; [C2]; xn--r97c.xn--1ug; ; xn--r97c.; [] # 𐋷.
+xn--r97c.; 𐋷.; ; xn--r97c.; ; ; # 𐋷.
+𐋷.; ; ; xn--r97c.; ; ; # 𐋷.
+xn--r97c.xn--1ug; 𐋷.‍; [C2]; xn--r97c.xn--1ug; ; ; # 𐋷.
+𑰳𑈯。⥪; 𑰳𑈯.⥪; [V5]; xn--2g1d14o.xn--jti; ; ; # 𑰳𑈯.⥪
+xn--2g1d14o.xn--jti; 𑰳𑈯.⥪; [V5]; xn--2g1d14o.xn--jti; ; ; # 𑰳𑈯.⥪
+𑆀䁴񤧣.Ⴕ𝟜‌͈; 𑆀䁴񤧣.Ⴕ4‌͈; [C1, P1, V5, V6]; xn--1mnx647cg3x1b.xn--4-zfb324h32o; ; xn--1mnx647cg3x1b.xn--4-zfb324h; [P1, V5, V6] # 𑆀䁴.Ⴕ4͈
+𑆀䁴񤧣.Ⴕ4‌͈; ; [C1, P1, V5, V6]; xn--1mnx647cg3x1b.xn--4-zfb324h32o; ; xn--1mnx647cg3x1b.xn--4-zfb324h; [P1, V5, V6] # 𑆀䁴.Ⴕ4͈
+𑆀䁴񤧣.ⴕ4‌͈; ; [C1, P1, V5, V6]; xn--1mnx647cg3x1b.xn--4-zfb502tlsl; ; xn--1mnx647cg3x1b.xn--4-zfb5123a; [P1, V5, V6] # 𑆀䁴.ⴕ4͈
+xn--1mnx647cg3x1b.xn--4-zfb5123a; 𑆀䁴񤧣.ⴕ4͈; [V5, V6]; xn--1mnx647cg3x1b.xn--4-zfb5123a; ; ; # 𑆀䁴.ⴕ4͈
+xn--1mnx647cg3x1b.xn--4-zfb502tlsl; 𑆀䁴񤧣.ⴕ4‌͈; [C1, V5, V6]; xn--1mnx647cg3x1b.xn--4-zfb502tlsl; ; ; # 𑆀䁴.ⴕ4͈
+xn--1mnx647cg3x1b.xn--4-zfb324h; 𑆀䁴񤧣.Ⴕ4͈; [V5, V6]; xn--1mnx647cg3x1b.xn--4-zfb324h; ; ; # 𑆀䁴.Ⴕ4͈
+xn--1mnx647cg3x1b.xn--4-zfb324h32o; 𑆀䁴񤧣.Ⴕ4‌͈; [C1, V5, V6]; xn--1mnx647cg3x1b.xn--4-zfb324h32o; ; ; # 𑆀䁴.Ⴕ4͈
+𑆀䁴񤧣.ⴕ𝟜‌͈; 𑆀䁴񤧣.ⴕ4‌͈; [C1, P1, V5, V6]; xn--1mnx647cg3x1b.xn--4-zfb502tlsl; ; xn--1mnx647cg3x1b.xn--4-zfb5123a; [P1, V5, V6] # 𑆀䁴.ⴕ4͈
+憡?‌Ⴔ.𐋮‍≠; ; [C1, C2, P1, V6]; xn--?-c1g798iy27d.xn--1ug73gl146a; ; xn--?-c1g3623d.xn--1chz659f; [P1, V6] # 憡?Ⴔ.𐋮≠
+憡?‌Ⴔ.𐋮‍≠; 憡?‌Ⴔ.𐋮‍≠; [C1, C2, P1, V6]; xn--?-c1g798iy27d.xn--1ug73gl146a; ; xn--?-c1g3623d.xn--1chz659f; [P1, V6] # 憡?Ⴔ.𐋮≠
+憡?‌ⴔ.𐋮‍≠; 憡?‌ⴔ.𐋮‍≠; [C1, C2, P1, V6]; xn--?-sgn310doh5c.xn--1ug73gl146a; ; xn--?-fwsr13r.xn--1chz659f; [P1, V6] # 憡?ⴔ.𐋮≠
+憡?‌ⴔ.𐋮‍≠; ; [C1, C2, P1, V6]; xn--?-sgn310doh5c.xn--1ug73gl146a; ; xn--?-fwsr13r.xn--1chz659f; [P1, V6] # 憡?ⴔ.𐋮≠
+xn--?-fwsr13r.xn--1chz659f; 憡?ⴔ.𐋮≠; [P1, V6]; xn--?-fwsr13r.xn--1chz659f; ; ; # 憡?ⴔ.𐋮≠
+xn--?-sgn310doh5c.xn--1ug73gl146a; 憡?‌ⴔ.𐋮‍≠; [C1, C2, P1, V6]; xn--?-sgn310doh5c.xn--1ug73gl146a; ; ; # 憡?ⴔ.𐋮≠
+xn--?-c1g3623d.xn--1chz659f; 憡?Ⴔ.𐋮≠; [P1, V6]; xn--?-c1g3623d.xn--1chz659f; ; ; # 憡?Ⴔ.𐋮≠
+xn--?-c1g798iy27d.xn--1ug73gl146a; 憡?‌Ⴔ.𐋮‍≠; [C1, C2, P1, V6]; xn--?-c1g798iy27d.xn--1ug73gl146a; ; ; # 憡?Ⴔ.𐋮≠
+憡?ⴔ.xn--1chz659f; 憡?ⴔ.𐋮≠; [P1, V6]; xn--?-fwsr13r.xn--1chz659f; ; ; # 憡?ⴔ.𐋮≠
+憡?Ⴔ.XN--1CHZ659F; 憡?Ⴔ.𐋮≠; [P1, V6]; xn--?-c1g3623d.xn--1chz659f; ; ; # 憡?Ⴔ.𐋮≠
+憡?Ⴔ.xn--1chz659f; 憡?Ⴔ.𐋮≠; [P1, V6]; xn--?-c1g3623d.xn--1chz659f; ; ; # 憡?Ⴔ.𐋮≠
+憡?‌ⴔ.xn--1ug73gl146a; 憡?‌ⴔ.𐋮‍≠; [C1, C2, P1, V6]; xn--?-sgn310doh5c.xn--1ug73gl146a; ; xn--?-fwsr13r.xn--1ug73gl146a; [C2, P1, V6] # 憡?ⴔ.𐋮≠
+憡?‌Ⴔ.XN--1UG73GL146A; 憡?‌Ⴔ.𐋮‍≠; [C1, C2, P1, V6]; xn--?-c1g798iy27d.xn--1ug73gl146a; ; xn--?-c1g3623d.xn--1ug73gl146a; [C2, P1, V6] # 憡?Ⴔ.𐋮≠
+憡?‌Ⴔ.xn--1ug73gl146a; 憡?‌Ⴔ.𐋮‍≠; [C1, C2, P1, V6]; xn--?-c1g798iy27d.xn--1ug73gl146a; ; xn--?-c1g3623d.xn--1ug73gl146a; [C2, P1, V6] # 憡?Ⴔ.𐋮≠
+xn--?-c1g3623d.xn--1ug73gl146a; 憡?Ⴔ.𐋮‍≠; [C2, P1, V6]; xn--?-c1g3623d.xn--1ug73gl146a; ; ; # 憡?Ⴔ.𐋮≠
+xn--?-fwsr13r.xn--1ug73gl146a; 憡?ⴔ.𐋮‍≠; [C2, P1, V6]; xn--?-fwsr13r.xn--1ug73gl146a; ; ; # 憡?ⴔ.𐋮≠
+憡?Ⴔ.xn--1ug73gl146a; 憡?Ⴔ.𐋮‍≠; [C2, P1, V6]; xn--?-c1g3623d.xn--1ug73gl146a; ; ; # 憡?Ⴔ.𐋮≠
+憡?ⴔ.xn--1ug73gl146a; 憡?ⴔ.𐋮‍≠; [C2, P1, V6]; xn--?-fwsr13r.xn--1ug73gl146a; ; ; # 憡?ⴔ.𐋮≠
+憡?Ⴔ.XN--1UG73GL146A; 憡?Ⴔ.𐋮‍≠; [C2, P1, V6]; xn--?-c1g3623d.xn--1ug73gl146a; ; ; # 憡?Ⴔ.𐋮≠
diff --git a/test/lisp/net/puny-tests.el b/test/lisp/net/puny-tests.el
index 8689bbf2a85..1b0cf56895e 100644
--- a/test/lisp/net/puny-tests.el
+++ b/test/lisp/net/puny-tests.el
@@ -61,4 +61,17 @@
;; Only allowed in unrestricted.
(should-not (puny-highly-restrictive-domain-p "I♥NY.org")))
+(ert-deftest puny-normalize ()
+ (should (equal (puny-encode-string (string-glyph-compose "Bä.com"))
+ "xn--b.com-gra"))
+ (should (equal (puny-encode-string "Bä.com")
+ "xn--b.com-gra"))
+ (should (equal (puny-encode-string "Bä.com") "xn--b.com-gra")))
+
+;;; TODO!
+;; puny-resources/IdnaTestV2.txt has a bunch of tests, and they should
+;; be implemented. However, the puny encoding does not fully
+;; implement https://www.unicode.org/reports/tr46/#Conformance yet, so
+;; it'll fail.
+
;;; puny-tests.el ends here
diff --git a/test/lisp/net/secrets-tests.el b/test/lisp/net/secrets-tests.el
index a02e926a79a..7e66774701c 100644
--- a/test/lisp/net/secrets-tests.el
+++ b/test/lisp/net/secrets-tests.el
@@ -57,8 +57,11 @@
(defun secrets--test-delete-all-session-items ()
"Delete all items of collection \"session\" bound to this Emacs."
- (dolist (item (secrets-list-items "session"))
- (secrets-delete-item "session" item)))
+ ;; If the "session" collection does not exist, a `dbus-error' is
+ ;; fired, which we ignore.
+ (dbus-ignore-errors
+ (dolist (item (secrets-list-items "session"))
+ (secrets-delete-item "session" item))))
(ert-deftest secrets-test01-sessions ()
"Test opening / closing a secrets session."
@@ -93,7 +96,7 @@
(unwind-protect
(progn
(should (secrets-open-session))
- (should (member "session" (secrets-list-collections)))
+ (skip-unless (member "session" (secrets-list-collections)))
;; Create a random collection. This asks for a password
;; outside our control, so we make it in the interactive case
@@ -153,6 +156,7 @@
(unwind-protect
(let (item-path)
(should (secrets-open-session))
+ (skip-unless (member "session" (secrets-list-collections)))
;; Cleanup. There could be items in the "session" collection.
(secrets--test-delete-all-session-items)
@@ -214,6 +218,7 @@
(unwind-protect
(progn
(should (secrets-open-session))
+ (skip-unless (member "session" (secrets-list-collections)))
;; Cleanup. There could be items in the "session" collection.
(secrets--test-delete-all-session-items)
diff --git a/test/lisp/net/shr-tests.el b/test/lisp/net/shr-tests.el
index e71bd025de9..821ca5ca636 100644
--- a/test/lisp/net/shr-tests.el
+++ b/test/lisp/net/shr-tests.el
@@ -27,6 +27,8 @@
(require 'ert-x)
(require 'shr)
+(declare-function libxml-parse-html-region "xml.c")
+
(defun shr-test (name)
(with-temp-buffer
(insert-file-contents (format (concat (ert-resource-directory) "/%s.html") name))
diff --git a/test/lisp/net/tramp-archive-tests.el b/test/lisp/net/tramp-archive-tests.el
index aaa41d0c584..54d1ecf3652 100644
--- a/test/lisp/net/tramp-archive-tests.el
+++ b/test/lisp/net/tramp-archive-tests.el
@@ -122,12 +122,6 @@ the origin of the temporary TMPFILE, have no write permissions."
(directory-files tmpfile 'full directory-files-no-dot-files-regexp))
(delete-directory tmpfile)))
-(defun tramp-archive--test-emacs26-p ()
- "Check for Emacs version >= 26.1.
-Some semantics has been changed for there, w/o new functions or
-variables, so we check the Emacs version directly."
- (>= emacs-major-version 26))
-
(defun tramp-archive--test-emacs27-p ()
"Check for Emacs version >= 27.1.
Some semantics has been changed for there, w/o new functions or
@@ -433,7 +427,7 @@ This checks also `file-name-as-directory', `file-name-directory',
(setq tmp-name
(file-local-copy
(expand-file-name "what" tramp-archive-test-archive)))
- :type tramp-file-missing))
+ :type 'file-missing))
;; Cleanup.
(ignore-errors (tramp-archive--test-delete tmp-name))
@@ -461,7 +455,7 @@ This checks also `file-name-as-directory', `file-name-directory',
(should-error
(insert-file-contents
(expand-file-name "what" tramp-archive-test-archive))
- :type tramp-file-missing))
+ :type 'file-missing))
;; Cleanup.
(tramp-archive-cleanup-hash))))
@@ -552,11 +546,9 @@ This checks also `file-name-as-directory', `file-name-directory',
(should (file-directory-p tmp-name2))
(should (file-exists-p tmp-name4))
;; Target directory does exist already.
- ;; This has been changed in Emacs 26.1.
- (when (tramp-archive--test-emacs26-p)
- (should-error
- (copy-directory tmp-name1 tmp-name2)
- :type 'file-error))
+ (should-error
+ (copy-directory tmp-name1 tmp-name2)
+ :type 'file-error)
(tramp-archive--test-delete tmp-name4)
(copy-directory tmp-name1 (file-name-as-directory tmp-name2))
(should (file-directory-p tmp-name3))
@@ -621,13 +613,11 @@ This checks also `file-name-as-directory', `file-name-directory',
(append '("LANG=C" "LANGUAGE=C" "LC_ALL=C") process-environment)))
(unwind-protect
(progn
- ;; Due to Bug#29423, this works only since for Emacs 26.1.
- (when nil ;; TODO (tramp-archive--test-emacs26-p)
- (with-temp-buffer
- (insert-directory tramp-archive-test-archive nil)
- (goto-char (point-min))
- (should
- (looking-at-p (regexp-quote tramp-archive-test-archive)))))
+ (with-temp-buffer
+ (insert-directory tramp-archive-test-archive nil)
+ (goto-char (point-min))
+ (should
+ (looking-at-p (regexp-quote tramp-archive-test-archive))))
(with-temp-buffer
(insert-directory tramp-archive-test-archive "-al")
(goto-char (point-min))
@@ -655,7 +645,7 @@ This checks also `file-name-as-directory', `file-name-directory',
(should-error
(insert-directory
(expand-file-name "baz" tramp-archive-test-archive) nil)
- :type tramp-file-missing)))
+ :type 'file-missing)))
;; Cleanup.
(tramp-archive-cleanup-hash))))
@@ -715,7 +705,7 @@ This tests also `access-file', `file-readable-p' and `file-regular-p'."
;; Check error case.
(should-error
(access-file tmp-name4 "error")
- :type tramp-file-missing))
+ :type 'file-missing))
;; Cleanup.
(tramp-archive-cleanup-hash))))
@@ -854,38 +844,27 @@ This tests also `file-executable-p', `file-writable-p' and `set-file-modes'."
;; Cleanup.
(tramp-archive-cleanup-hash))))
-;; The functions were introduced in Emacs 26.1.
(ert-deftest tramp-archive-test40-make-nearby-temp-file ()
"Check `make-nearby-temp-file' and `temporary-file-directory'."
(skip-unless tramp-archive-enabled)
- ;; Since Emacs 26.1.
- (skip-unless
- (and (fboundp 'make-nearby-temp-file) (fboundp 'temporary-file-directory)))
- ;; `make-nearby-temp-file' and `temporary-file-directory' exists
- ;; since Emacs 26.1. We don't want to see compiler warnings for
- ;; older Emacsen.
(let ((default-directory tramp-archive-test-archive)
tmp-file)
;; The file archive shall know a temporary file directory. It is
;; not in the archive itself.
- (should
- (stringp (with-no-warnings (with-no-warnings (temporary-file-directory)))))
- (should-not
- (tramp-archive-file-name-p (with-no-warnings (temporary-file-directory))))
+ (should (stringp (temporary-file-directory)))
+ (should-not (tramp-archive-file-name-p (temporary-file-directory)))
;; A temporary file or directory shall not be located in the
;; archive itself.
- (setq tmp-file
- (with-no-warnings (make-nearby-temp-file "tramp-archive-test")))
+ (setq tmp-file (make-nearby-temp-file "tramp-archive-test"))
(should (file-exists-p tmp-file))
(should (file-regular-p tmp-file))
(should-not (tramp-archive-file-name-p tmp-file))
(delete-file tmp-file)
(should-not (file-exists-p tmp-file))
- (setq tmp-file
- (with-no-warnings (make-nearby-temp-file "tramp-archive-test" 'dir)))
+ (setq tmp-file (make-nearby-temp-file "tramp-archive-test" 'dir))
(should (file-exists-p tmp-file))
(should (file-directory-p tmp-file))
(should-not (tramp-archive-file-name-p tmp-file))
@@ -909,7 +888,7 @@ This tests also `file-executable-p', `file-writable-p' and `set-file-modes'."
(zerop (nth 1 fsi))
(zerop (nth 2 fsi))))))
-(ert-deftest tramp-archive-test45-auto-load ()
+(ert-deftest tramp-archive-test47-auto-load ()
"Check that `tramp-archive' autoloads properly."
:tags '(:expensive-test)
(skip-unless tramp-archive-enabled)
@@ -952,7 +931,7 @@ This tests also `file-executable-p', `file-writable-p' and `set-file-modes'."
(format "(setq tramp-archive-enabled %s)" enabled))
(shell-quote-argument (format code file)))))))))))
-(ert-deftest tramp-archive-test45-delay-load ()
+(ert-deftest tramp-archive-test47-delay-load ()
"Check that `tramp-archive' is loaded lazily, only when needed."
:tags '(:expensive-test)
(skip-unless tramp-archive-enabled)
diff --git a/test/lisp/net/tramp-resources/foo.tar.gz b/test/lisp/net/tramp-resources/foo.tar.gz
new file mode 100644
index 00000000000..0d2e9878dd7
--- /dev/null
+++ b/test/lisp/net/tramp-resources/foo.tar.gz
Binary files differ
diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el
index 9071beedf2e..8b6d10033f1 100644
--- a/test/lisp/net/tramp-tests.el
+++ b/test/lisp/net/tramp-tests.el
@@ -43,10 +43,12 @@
(require 'cl-lib)
(require 'dired)
-(require 'ert)
+(require 'dired-aux)
+(require 'tramp)
(require 'ert-x)
+(require 'seq) ; For `seq-random-elt', autoloaded since Emacs 28.1
+(require 'tar-mode)
(require 'trace)
-(require 'tramp)
(require 'vc)
(require 'vc-bzr)
(require 'vc-git)
@@ -62,9 +64,6 @@
(declare-function tramp-method-out-of-band-p "tramp-sh")
(declare-function tramp-smb-get-localname "tramp-smb")
(defvar ange-ftp-make-backup-files)
-(defvar auto-save-file-name-transforms)
-(defvar lock-file-name-transforms)
-(defvar remote-file-name-inhibit-locks)
(defvar tramp-connection-properties)
(defvar tramp-copy-size-limit)
(defvar tramp-display-escape-sequence-regexp)
@@ -75,17 +74,91 @@
(defvar tramp-remote-path)
(defvar tramp-remote-process-environment)
-;; Needed for Emacs 25.
-(defvar connection-local-criteria-alist)
-(defvar connection-local-profile-alist)
;; Needed for Emacs 26.
-(defvar async-shell-command-width)
+(declare-function with-connection-local-variables "files-x")
;; Needed for Emacs 27.
+(defvar lock-file-name-transforms)
(defvar process-file-return-signal-string)
+(defvar remote-file-name-inhibit-locks)
(defvar shell-command-dont-erase-buffer)
;; Needed for Emacs 28.
(defvar dired-copy-dereference)
+;; `ert-resource-file' was introduced in Emacs 28.1.
+(unless (macrop 'ert-resource-file)
+ (eval-and-compile
+ (defvar ert-resource-directory-format "%s-resources/"
+ "Format for `ert-resource-directory'.")
+ (defvar ert-resource-directory-trim-left-regexp ""
+ "Regexp for `string-trim' (left) used by `ert-resource-directory'.")
+ (defvar ert-resource-directory-trim-right-regexp "\\(-tests?\\)?\\.el"
+ "Regexp for `string-trim' (right) used by `ert-resource-directory'.")
+
+ (defmacro ert-resource-directory ()
+ "Return absolute file name of the resource directory for this file.
+
+The path to the resource directory is the \"resources\" directory
+in the same directory as the test file.
+
+If that directory doesn't exist, use the directory named like the
+test file but formatted by `ert-resource-directory-format' and trimmed
+using `string-trim' with arguments
+`ert-resource-directory-trim-left-regexp' and
+`ert-resource-directory-trim-right-regexp'. The default values mean
+that if called from a test file named \"foo-tests.el\", return
+the absolute file name for \"foo-resources\"."
+ `(let* ((testfile ,(or (bound-and-true-p byte-compile-current-file)
+ (and load-in-progress load-file-name)
+ buffer-file-name))
+ (default-directory (file-name-directory testfile)))
+ (file-truename
+ (if (file-accessible-directory-p "resources/")
+ (expand-file-name "resources/")
+ (expand-file-name
+ (format
+ ert-resource-directory-format
+ (string-trim testfile
+ ert-resource-directory-trim-left-regexp
+ ert-resource-directory-trim-right-regexp)))))))
+
+ (defmacro ert-resource-file (file)
+ "Return file name of resource file named FILE.
+A resource file is in the resource directory as per
+`ert-resource-directory'."
+ `(expand-file-name ,file (ert-resource-directory)))))
+
+;; `ert-remote-temporary-file-directory' was introduced in Emacs 29.1.
+;; Adapting `tramp-remote-path' happens also there.
+(unless (boundp 'ert-remote-temporary-file-directory)
+ (eval-and-compile
+ ;; There is no default value on w32 systems, which could work out
+ ;; of the box.
+ (defconst ert-remote-temporary-file-directory
+ (cond
+ ((getenv "REMOTE_TEMPORARY_FILE_DIRECTORY"))
+ ((eq system-type 'windows-nt) null-device)
+ (t (add-to-list
+ 'tramp-methods
+ '("mock"
+ (tramp-login-program "sh")
+ (tramp-login-args (("-i")))
+ (tramp-remote-shell "/bin/sh")
+ (tramp-remote-shell-args ("-c"))
+ (tramp-connection-timeout 10)))
+ (add-to-list
+ 'tramp-default-host-alist
+ `("\\`mock\\'" nil ,(system-name)))
+ ;; Emacs's Makefile sets $HOME to a nonexistent value.
+ ;; Needed in batch mode only, therefore.
+ (unless (and (null noninteractive) (file-directory-p "~/"))
+ (setenv "HOME" temporary-file-directory))
+ (format "/mock::%s" temporary-file-directory)))
+ "Temporary directory for remote file tests.")
+
+ ;; This should happen on hydra only.
+ (when (getenv "EMACS_HYDRA_CI")
+ (add-to-list 'tramp-remote-path 'tramp-own-remote-path))))
+
;; Beautify batch mode.
(when noninteractive
;; Suppress nasty messages.
@@ -95,32 +168,9 @@
'(fset 'tramp-gvfs-handler-askquestion
(lambda (_message _choices) '(t nil 0)))))
-;; There is no default value on w32 systems, which could work out of the box.
-(defconst tramp-test-temporary-file-directory
- (cond
- ((getenv "REMOTE_TEMPORARY_FILE_DIRECTORY"))
- ((eq system-type 'windows-nt) null-device)
- (t (add-to-list
- 'tramp-methods
- '("mock"
- (tramp-login-program "sh")
- (tramp-login-args (("-i")))
- (tramp-remote-shell "/bin/sh")
- (tramp-remote-shell-args ("-c"))
- (tramp-connection-timeout 10)))
- (add-to-list
- 'tramp-default-host-alist
- `("\\`mock\\'" nil ,(system-name)))
- ;; Emacs's Makefile sets $HOME to a nonexistent value. Needed
- ;; in batch mode only, therefore.
- (unless (and (null noninteractive) (file-directory-p "~/"))
- (setenv "HOME" temporary-file-directory))
- (format "/mock::%s" temporary-file-directory)))
- "Temporary directory for Tramp tests.")
-
(defconst tramp-test-vec
- (and (file-remote-p tramp-test-temporary-file-directory)
- (tramp-dissect-file-name tramp-test-temporary-file-directory))
+ (and (file-remote-p ert-remote-temporary-file-directory)
+ (tramp-dissect-file-name ert-remote-temporary-file-directory))
"The used `tramp-file-name' structure.")
(setq auth-source-save-behavior nil
@@ -129,13 +179,10 @@
tramp-allow-unsafe-temporary-files t
tramp-cache-read-persistent-data t ;; For auth-sources.
tramp-copy-size-limit nil
+ tramp-error-show-message-timeout nil
tramp-persistency-file-name nil
tramp-verbose 0)
-;; This should happen on hydra only.
-(when (getenv "EMACS_HYDRA_CI")
- (add-to-list 'tramp-remote-path 'tramp-own-remote-path))
-
(defvar tramp--test-enabled-checked nil
"Cached result of `tramp--test-enabled'.
If the function did run, the value is a cons cell, the `cdr'
@@ -149,9 +196,9 @@ being the result.")
(cons
t (ignore-errors
(and
- (file-remote-p tramp-test-temporary-file-directory)
- (file-directory-p tramp-test-temporary-file-directory)
- (file-writable-p tramp-test-temporary-file-directory))))))
+ (file-remote-p ert-remote-temporary-file-directory)
+ (file-directory-p ert-remote-temporary-file-directory)
+ (file-writable-p ert-remote-temporary-file-directory))))))
(when (cdr tramp--test-enabled-checked)
;; Cleanup connection.
@@ -170,7 +217,7 @@ The temporary file is not created."
(if quoted #'tramp-compat-file-name-quote #'identity)
(expand-file-name
(make-temp-name "tramp-test")
- (if local temporary-file-directory tramp-test-temporary-file-directory))))
+ (if local temporary-file-directory ert-remote-temporary-file-directory))))
;; Method "smb" supports `make-symbolic-link' only if the remote host
;; has CIFS capabilities. tramp-adb.el, tramp-gvfs.el, tramp-rclone.el
@@ -216,8 +263,7 @@ is greater than 10.
(when (and (null tramp--test-instrument-test-case-p) (> tramp-verbose 3))
(untrace-all)
(dolist (buf (tramp-list-tramp-buffers))
- (with-current-buffer buf
- (message ";; %s\n%s" buf (buffer-string)))
+ (message ";; %s\n%s" buf (tramp-get-buffer-string buf))
(kill-buffer buf))))))
(defsubst tramp--test-message (fmt-string &rest arguments)
@@ -237,8 +283,7 @@ is greater than 10.
(unwind-protect
(progn ,@body)
(tramp--test-message
- "%s %f sec"
- ,message (float-time (time-subtract (current-time) start))))))
+ "%s %f sec" ,message (float-time (time-subtract nil start))))))
;; `always' is introduced with Emacs 28.1.
(defalias 'tramp--test-always
@@ -254,12 +299,12 @@ Also see `ignore'."
"Test availability of Tramp functions."
:expected-result (if (tramp--test-enabled) :passed :failed)
(tramp--test-message
- "Remote directory: `%s'" tramp-test-temporary-file-directory)
+ "Remote directory: `%s'" ert-remote-temporary-file-directory)
(should (ignore-errors
(and
- (file-remote-p tramp-test-temporary-file-directory)
- (file-directory-p tramp-test-temporary-file-directory)
- (file-writable-p tramp-test-temporary-file-directory)))))
+ (file-remote-p ert-remote-temporary-file-directory)
+ (file-directory-p ert-remote-temporary-file-directory)
+ (file-writable-p ert-remote-temporary-file-directory)))))
(ert-deftest tramp-test01-file-name-syntax ()
"Check remote file name syntax."
@@ -802,8 +847,7 @@ Also see `ignore'."
(string-equal
(file-remote-p
"/method1:user1@host1|method2:user2@host2:/path/to/file")
- (format "/%s:%s@%s|%s:%s@%s:"
- "method1" "user1" "host1" "method2" "user2" "host2")))
+ "/method2:user2@host2:"))
(should
(string-equal
(file-remote-p
@@ -839,10 +883,7 @@ Also see `ignore'."
"/method1:user1@host1"
"|method2:user2@host2"
"|method3:user3@host3:/path/to/file"))
- (format "/%s:%s@%s|%s:%s@%s|%s:%s@%s:"
- "method1" "user1" "host1"
- "method2" "user2" "host2"
- "method3" "user3" "host3")))
+ "/method3:user3@host3:"))
(should
(string-equal
(file-remote-p
@@ -901,10 +942,7 @@ Also see `ignore'."
"/-:user1@host1"
"|-:user2@host2"
"|-:user3@host3:/path/to/file"))
- (format "/%s:%s@%s|%s:%s@%s|%s:%s@%s:"
- "method1" "user1" "host1"
- "method2" "user2" "host2"
- "method3" "user3" "host3")))
+ "/method3:user3@host3:"))
;; Expand `tramp-default-user-alist'.
(add-to-list 'tramp-default-user-alist '("method1" "host1" "user1"))
@@ -917,10 +955,7 @@ Also see `ignore'."
"/method1:host1"
"|method2:host2"
"|method3:host3:/path/to/file"))
- (format "/%s:%s@%s|%s:%s@%s|%s:%s@%s:"
- "method1" "user1" "host1"
- "method2" "user2" "host2"
- "method3" "user3" "host3")))
+ "/method3:user3@host3:"))
;; Expand `tramp-default-host-alist'.
(add-to-list 'tramp-default-host-alist '("method1" "user1" "host1"))
@@ -933,10 +968,7 @@ Also see `ignore'."
"/method1:user1@"
"|method2:user2@"
"|method3:user3@:/path/to/file"))
- (format "/%s:%s@%s|%s:%s@%s|%s:%s@%s:"
- "method1" "user1" "host1"
- "method2" "user2" "host2"
- "method3" "user3" "host3")))
+ "/method3:user3@host3:"))
;; Ad-hoc user name and host name expansion.
(setq tramp-default-method-alist nil
@@ -949,10 +981,7 @@ Also see `ignore'."
"/method1:user1@host1"
"|method2:user2@"
"|method3:user3@:/path/to/file"))
- (format "/%s:%s@%s|%s:%s@%s|%s:%s@%s:"
- "method1" "user1" "host1"
- "method2" "user2" "host1"
- "method3" "user3" "host1")))
+ "/method3:user3@host1:"))
(should
(string-equal
(file-remote-p
@@ -961,11 +990,7 @@ Also see `ignore'."
"|method2:user2@host2"
"|method3:%u@%h"
"|method4:user4%domain4@host4#1234:/path/to/file"))
- (format "/%s:%s@%s|%s:%s@%s|%s:%s@%s|%s:%s@%s:"
- "method1" "user2" "host2"
- "method2" "user2" "host2"
- "method3" "user4" "host4"
- "method4" "user4%domain4" "host4#1234"))))
+ "/method4:user4%domain4@host4#1234:")))
;; Exit.
(tramp-change-syntax syntax))))
@@ -1153,7 +1178,7 @@ Also see `ignore'."
(should
(string-equal
(file-remote-p "/user1@host1|user2@host2:/path/to/file")
- (format "/%s@%s|%s@%s:" "user1" "host1" "user2" "host2")))
+ "/user2@host2:"))
(should
(string-equal
(file-remote-p
@@ -1187,10 +1212,7 @@ Also see `ignore'."
"/user1@host1"
"|user2@host2"
"|user3@host3:/path/to/file"))
- (format "/%s@%s|%s@%s|%s@%s:"
- "user1" "host1"
- "user2" "host2"
- "user3" "host3")))
+ "/user3@host3:"))
(should
(string-equal
(file-remote-p
@@ -1249,10 +1271,7 @@ Also see `ignore'."
"/host1"
"|host2"
"|host3:/path/to/file"))
- (format "/%s@%s|%s@%s|%s@%s:"
- "user1" "host1"
- "user2" "host2"
- "user3" "host3")))
+ "/user3@host3:"))
;; Expand `tramp-default-host-alist'.
(add-to-list 'tramp-default-host-alist '(nil "user1" "host1"))
@@ -1265,10 +1284,7 @@ Also see `ignore'."
"/user1@"
"|user2@"
"|user3@:/path/to/file"))
- (format "/%s@%s|%s@%s|%s@%s:"
- "user1" "host1"
- "user2" "host2"
- "user3" "host3")))
+ "/user3@host3:"))
;; Ad-hoc user name and host name expansion.
(setq tramp-default-user-alist nil
@@ -1280,10 +1296,7 @@ Also see `ignore'."
"/user1@host1"
"|user2@"
"|user3@:/path/to/file"))
- (format "/%s@%s|%s@%s|%s@%s:"
- "user1" "host1"
- "user2" "host1"
- "user3" "host1")))
+ "/user3@host1:"))
(should
(string-equal
(file-remote-p
@@ -1292,11 +1305,7 @@ Also see `ignore'."
"|user2@host2"
"|%u@%h"
"|user4%domain4@host4#1234:/path/to/file"))
- (format "/%s@%s|%s@%s|%s@%s|%s@%s:"
- "user2" "host2"
- "user2" "host2"
- "user4" "host4"
- "user4%domain4" "host4#1234"))))
+ "/user4%domain4@host4#1234:")))
;; Exit.
(tramp-change-syntax syntax))))
@@ -1792,8 +1801,7 @@ Also see `ignore'."
(string-equal
(file-remote-p
"/[method1/user1@host1|method2/user2@host2]/path/to/file")
- (format "/[%s/%s@%s|%s/%s@%s]"
- "method1" "user1" "host1" "method2" "user2" "host2")))
+ "/[method2/user2@host2]"))
(should
(string-equal
(file-remote-p
@@ -1829,10 +1837,7 @@ Also see `ignore'."
"/[method1/user1@host1"
"|method2/user2@host2"
"|method3/user3@host3]/path/to/file"))
- (format "/[%s/%s@%s|%s/%s@%s|%s/%s@%s]"
- "method1" "user1" "host1"
- "method2" "user2" "host2"
- "method3" "user3" "host3")))
+ "/[method3/user3@host3]"))
(should
(string-equal
(file-remote-p
@@ -1891,10 +1896,7 @@ Also see `ignore'."
"/[/user1@host1"
"|/user2@host2"
"|/user3@host3]/path/to/file"))
- (format "/[%s/%s@%s|%s/%s@%s|%s/%s@%s]"
- "method1" "user1" "host1"
- "method2" "user2" "host2"
- "method3" "user3" "host3")))
+ "/[method3/user3@host3]"))
;; Expand `tramp-default-user-alist'.
(add-to-list 'tramp-default-user-alist '("method1" "host1" "user1"))
@@ -1907,10 +1909,7 @@ Also see `ignore'."
"/[method1/host1"
"|method2/host2"
"|method3/host3]/path/to/file"))
- (format "/[%s/%s@%s|%s/%s@%s|%s/%s@%s]"
- "method1" "user1" "host1"
- "method2" "user2" "host2"
- "method3" "user3" "host3")))
+ "/[method3/user3@host3]"))
;; Expand `tramp-default-host-alist'.
(add-to-list 'tramp-default-host-alist '("method1" "user1" "host1"))
@@ -1923,10 +1922,7 @@ Also see `ignore'."
"/[method1/user1@"
"|method2/user2@"
"|method3/user3@]/path/to/file"))
- (format "/[%s/%s@%s|%s/%s@%s|%s/%s@%s]"
- "method1" "user1" "host1"
- "method2" "user2" "host2"
- "method3" "user3" "host3")))
+ "/[method3/user3@host3]"))
;; Ad-hoc user name and host name expansion.
(setq tramp-default-method-alist nil
@@ -1939,10 +1935,7 @@ Also see `ignore'."
"/[method1/user1@host1"
"|method2/user2@"
"|method3/user3@]/path/to/file"))
- (format "/[%s/%s@%s|%s/%s@%s|%s/%s@%s]"
- "method1" "user1" "host1"
- "method2" "user2" "host1"
- "method3" "user3" "host1")))
+ "/[method3/user3@host1]"))
(should
(string-equal
(file-remote-p
@@ -1951,11 +1944,7 @@ Also see `ignore'."
"|method2/user2@host2"
"|method3/%u@%h"
"|method4/user4%domain4@host4#1234]/path/to/file"))
- (format "/[%s/%s@%s|%s/%s@%s|%s/%s@%s|%s/%s@%s]"
- "method1" "user2" "host2"
- "method2" "user2" "host2"
- "method3" "user4" "host4"
- "method4" "user4%domain4" "host4#1234"))))
+ "/[method4/user4%domain4@host4#1234]")))
;; Exit.
(tramp-change-syntax syntax))))
@@ -2012,7 +2001,7 @@ Also see `ignore'."
(find-file
(format
"%s|%s:foo:"
- (substring (file-remote-p tramp-test-temporary-file-directory) 0 -1)
+ (substring (file-remote-p ert-remote-temporary-file-directory) 0 -1)
m))
:type 'user-error))))
@@ -2067,44 +2056,41 @@ Also see `ignore'."
(substitute-in-file-name "/method:host:/:/path//foo")
"/method:host:/:/path//foo"))
- ;; Forwhatever reasons, the following tests let Emacs crash for
- ;; Emacs 25, occasionally. No idea what's up.
- (when (tramp--test-emacs26-p)
- (should
- (string-equal
- (substitute-in-file-name (concat "/method:host://~" foo))
- (concat "/~" foo)))
- (should
- (string-equal
- (substitute-in-file-name (concat "/method:host:/~" foo))
- (concat "/method:host:/~" foo)))
- (should
- (string-equal
- (substitute-in-file-name (concat "/method:host:/path//~" foo))
- (concat "/~" foo)))
- ;; (substitute-in-file-name "/path/~foo") expands only for a local
- ;; user "foo" to "/~foo"". Otherwise, it doesn't expand.
- (should
- (string-equal
- (substitute-in-file-name (concat "/method:host:/path/~" foo))
- (concat "/method:host:/path/~" foo)))
- ;; Quoting local part.
- (should
- (string-equal
- (substitute-in-file-name (concat "/method:host:/://~" foo))
- (concat "/method:host:/://~" foo)))
- (should
- (string-equal
- (substitute-in-file-name (concat "/method:host:/:/~" foo))
- (concat "/method:host:/:/~" foo)))
- (should
- (string-equal
- (substitute-in-file-name (concat "/method:host:/:/path//~" foo))
- (concat "/method:host:/:/path//~" foo)))
- (should
- (string-equal
- (substitute-in-file-name (concat "/method:host:/:/path/~" foo))
- (concat "/method:host:/:/path/~" foo))))
+ (should
+ (string-equal
+ (substitute-in-file-name (concat "/method:host://~" foo))
+ (concat "/~" foo)))
+ (should
+ (string-equal
+ (substitute-in-file-name (concat "/method:host:/~" foo))
+ (concat "/method:host:/~" foo)))
+ (should
+ (string-equal
+ (substitute-in-file-name (concat "/method:host:/path//~" foo))
+ (concat "/~" foo)))
+ ;; (substitute-in-file-name "/path/~foo") expands only for a local
+ ;; user "foo" to "/~foo"". Otherwise, it doesn't expand.
+ (should
+ (string-equal
+ (substitute-in-file-name (concat "/method:host:/path/~" foo))
+ (concat "/method:host:/path/~" foo)))
+ ;; Quoting local part.
+ (should
+ (string-equal
+ (substitute-in-file-name (concat "/method:host:/://~" foo))
+ (concat "/method:host:/://~" foo)))
+ (should
+ (string-equal
+ (substitute-in-file-name (concat "/method:host:/:/~" foo))
+ (concat "/method:host:/:/~" foo)))
+ (should
+ (string-equal
+ (substitute-in-file-name (concat "/method:host:/:/path//~" foo))
+ (concat "/method:host:/:/path//~" foo)))
+ (should
+ (string-equal
+ (substitute-in-file-name (concat "/method:host:/:/path/~" foo))
+ (concat "/method:host:/:/path/~" foo)))
(let (process-environment)
(should
@@ -2177,25 +2163,25 @@ Also see `ignore'."
(ert-deftest tramp-test05-expand-file-name-relative ()
"Check `expand-file-name'."
(skip-unless (tramp--test-enabled))
- ;; The bugs are fixed in Emacs 28.1.
- (skip-unless (tramp--test-emacs28-p))
;; Methods with a share do not expand "/path/..".
(skip-unless (not (tramp--test-share-p)))
+ ;; The bugs are fixed in Emacs 28.1.
+ (skip-unless (tramp--test-emacs28-p))
(should
(string-equal
(let ((default-directory
(concat
- (file-remote-p tramp-test-temporary-file-directory) "/path")))
+ (file-remote-p ert-remote-temporary-file-directory) "/path")))
(expand-file-name ".." "./"))
- (concat (file-remote-p tramp-test-temporary-file-directory) "/"))))
+ (concat (file-remote-p ert-remote-temporary-file-directory) "/"))))
(ert-deftest tramp-test05-expand-file-name-top ()
"Check `expand-file-name'."
(skip-unless (tramp--test-enabled))
(skip-unless (not (tramp--test-ange-ftp-p)))
- (let ((dir (concat (file-remote-p tramp-test-temporary-file-directory) "/")))
+ (let ((dir (concat (file-remote-p ert-remote-temporary-file-directory) "/")))
(dolist (local '("." ".."))
(should (string-equal (expand-file-name local dir) dir))
(should (string-equal (expand-file-name (concat dir local)) dir)))))
@@ -2258,8 +2244,8 @@ This checks also `file-name-as-directory', `file-name-directory',
;; We must clear `tramp-default-method'. On hydra, it is "ftp",
;; which ruins the tests.
(let ((tramp-default-method
- (file-remote-p tramp-test-temporary-file-directory 'method))
- (host (file-remote-p tramp-test-temporary-file-directory 'host)))
+ (file-remote-p ert-remote-temporary-file-directory 'method))
+ (host (file-remote-p ert-remote-temporary-file-directory 'host)))
(dolist
(file
`(,(format "/%s::" tramp-default-method)
@@ -2278,6 +2264,54 @@ This checks also `file-name-as-directory', `file-name-directory',
(should (string-equal (file-name-directory file) file))
(should (string-equal (file-name-nondirectory file) "")))))))
+(ert-deftest tramp-test07-abbreviate-file-name ()
+ "Check that Tramp abbreviates file names correctly."
+ (skip-unless (tramp--test-enabled))
+ (skip-unless (not (tramp--test-ange-ftp-p)))
+ ;; `abbreviate-file-name' is supported since Emacs 29.1.
+ (skip-unless (tramp--test-emacs29-p))
+
+ ;; We must refill the cache. `file-truename' does it.
+ (file-truename ert-remote-temporary-file-directory)
+ (let* ((remote-host (file-remote-p ert-remote-temporary-file-directory))
+ (remote-host-nohop
+ (tramp-make-tramp-file-name (tramp-dissect-file-name remote-host)))
+ ;; Not all methods can expand "~".
+ (home-dir (ignore-errors (expand-file-name (concat remote-host "~"))))
+ home-dir-nohop)
+ (skip-unless home-dir)
+
+ ;; Check home-dir abbreviation.
+ (unless (string-suffix-p "~" home-dir)
+ (should (equal (abbreviate-file-name (concat home-dir "/foo/bar"))
+ (concat remote-host-nohop "~/foo/bar")))
+ (should (equal (abbreviate-file-name
+ (concat remote-host "/nowhere/special"))
+ (concat remote-host-nohop "/nowhere/special"))))
+
+ ;; Check `directory-abbrev-alist' abbreviation.
+ (let ((directory-abbrev-alist
+ `((,(concat "\\`" (regexp-quote home-dir) "/foo")
+ . ,(concat home-dir "/f"))
+ (,(concat "\\`" (regexp-quote remote-host) "/nowhere")
+ . ,(concat remote-host "/nw")))))
+ (should (equal (abbreviate-file-name (concat home-dir "/foo/bar"))
+ (concat remote-host-nohop "~/f/bar")))
+ (should (equal (abbreviate-file-name
+ (concat remote-host "/nowhere/special"))
+ (concat remote-host-nohop "/nw/special"))))
+
+ ;; Check that home-dir abbreviation doesn't occur when home-dir is just "/".
+ (setq home-dir (concat remote-host "/")
+ home-dir-nohop
+ (tramp-make-tramp-file-name (tramp-dissect-file-name home-dir)))
+ ;; The remote home directory is kept in the connection property "~".
+ ;; We fake this setting.
+ (tramp-set-connection-property tramp-test-vec "~" (file-local-name home-dir))
+ (should (equal (abbreviate-file-name (concat home-dir "foo/bar"))
+ (concat home-dir-nohop "foo/bar")))
+ (tramp-flush-connection-property tramp-test-vec "~")))
+
(ert-deftest tramp-test07-file-exists-p ()
"Check `file-exist-p', `write-region' and `delete-file'."
(skip-unless (tramp--test-enabled))
@@ -2328,7 +2362,7 @@ This checks also `file-name-as-directory', `file-name-directory',
(insert-file-contents tmp-name2)
(should (string-equal (buffer-string) "foo")))
;; Check also that a file transfer with compression works.
- (let ((default-directory tramp-test-temporary-file-directory)
+ (let ((default-directory ert-remote-temporary-file-directory)
(tramp-copy-size-limit 4)
(tramp-inline-compress-start-size 2))
(delete-file tmp-name2)
@@ -2338,7 +2372,7 @@ This checks also `file-name-as-directory', `file-name-directory',
(delete-file tmp-name2)
(should-error
(setq tmp-name2 (file-local-copy tmp-name1))
- :type tramp-file-missing))
+ :type 'file-missing))
;; Cleanup.
(ignore-errors
@@ -2377,7 +2411,7 @@ This checks also `file-name-as-directory', `file-name-directory',
(delete-file tmp-name)
(should-error
(insert-file-contents tmp-name)
- :type tramp-file-missing))
+ :type 'file-missing))
;; Cleanup.
(ignore-errors (delete-file tmp-name))))))
@@ -2448,23 +2482,20 @@ This checks also `file-name-as-directory', `file-name-directory',
(should (string-equal (buffer-string) "34")))
;; Check message.
- ;; Macro `ert-with-message-capture' was introduced in Emacs 26.1.
- (with-no-warnings (when (symbol-plist 'ert-with-message-capture)
- (let (inhibit-message)
- (dolist
- (noninteractive (unless (tramp--test-ange-ftp-p) '(nil t)))
- (dolist (visit '(nil t "string" no-message))
- (ert-with-message-capture tramp--test-messages
- (write-region "foo" nil tmp-name nil visit)
- ;; We must check the last line. There could be
- ;; other messages from the progress reporter.
- (should
- (string-match-p
- (if (and (null noninteractive)
- (or (eq visit t) (null visit) (stringp visit)))
- (format "^Wrote %s\n\\'" (regexp-quote tmp-name))
- "^\\'")
- tramp--test-messages))))))))
+ (let (inhibit-message)
+ (dolist (noninteractive (unless (tramp--test-ange-ftp-p) '(nil t)))
+ (dolist (visit '(nil t "string" no-message))
+ (ert-with-message-capture tramp--test-messages
+ (write-region "foo" nil tmp-name nil visit)
+ ;; We must check the last line. There could be
+ ;; other messages from the progress reporter.
+ (should
+ (string-match-p
+ (if (and (null noninteractive)
+ (or (eq visit t) (null visit) (stringp visit)))
+ (format "^Wrote %s\n\\'" (regexp-quote tmp-name))
+ "^\\'")
+ tramp--test-messages))))))
;; We do not test lockname here. See
;; `tramp-test39-make-lock-file-name'.
@@ -2474,17 +2505,15 @@ This checks also `file-name-as-directory', `file-name-directory',
;; Ange-FTP.
((symbol-function 'yes-or-no-p) #'tramp--test-always))
(write-region "foo" nil tmp-name nil nil nil 'mustbenew))
- ;; `mustbenew' is passed to Tramp since Emacs 26.1.
- (when (tramp--test-emacs26-p)
- (should-error
- (cl-letf (((symbol-function #'y-or-n-p) #'ignore)
- ;; Ange-FTP.
- ((symbol-function #'yes-or-no-p) #'ignore))
- (write-region "foo" nil tmp-name nil nil nil 'mustbenew))
- :type 'file-already-exists)
- (should-error
- (write-region "foo" nil tmp-name nil nil nil 'excl)
- :type 'file-already-exists)))
+ (should-error
+ (cl-letf (((symbol-function #'y-or-n-p) #'ignore)
+ ;; Ange-FTP.
+ ((symbol-function #'yes-or-no-p) #'ignore))
+ (write-region "foo" nil tmp-name nil nil nil 'mustbenew))
+ :type 'file-already-exists)
+ (should-error
+ (write-region "foo" nil tmp-name nil nil nil 'excl)
+ :type 'file-already-exists))
;; Cleanup.
(ignore-errors (delete-file tmp-name))))))
@@ -2515,13 +2544,65 @@ This checks also `file-name-as-directory', `file-name-directory',
(setq-local file-precious-flag t)
(setq-local backup-inhibited t)
(insert "bar")
+ (should (buffer-modified-p))
(should (null (save-buffer)))
+ (should (not (buffer-modified-p)))
(should-not (cl-member tmp-name written-files :test #'string=)))
;; Cleanup.
(ignore-errors (advice-remove 'write-region advice))
(ignore-errors (delete-file tmp-name)))))
+;; The following test is inspired by Bug#55166.
+(ert-deftest tramp-test10-write-region-other-file-name-handler ()
+ "Check that another file name handler in VISIT is acknowledged."
+ (skip-unless (tramp--test-enabled))
+ (skip-unless (not (tramp--test-ange-ftp-p)))
+ (skip-unless (executable-find "gzip"))
+ ;; The function was introduced in Emacs 28.1.
+ (skip-unless (boundp 'tar-goto-file))
+
+ (let* ((default-directory ert-remote-temporary-file-directory)
+ (archive (ert-resource-file "foo.tar.gz"))
+ (tmp-file (expand-file-name (file-name-nondirectory archive)))
+ (require-final-newline t)
+ (inhibit-message t)
+ (backup-inhibited t)
+ create-lockfiles buffer1 buffer2)
+ (unwind-protect
+ (progn
+ (copy-file archive tmp-file 'ok)
+ ;; Read archive. Check contents of foo.txt, and modify it. Save.
+ (with-current-buffer (setq buffer1 (find-file-noselect tmp-file))
+ ;; The function was introduced in Emacs 28.1.
+ (with-no-warnings (should (tar-goto-file "foo.txt")))
+ (save-current-buffer
+ (setq buffer2 (tar-extract))
+ (should (string-equal (buffer-string) "foo\n"))
+ (goto-char (point-max))
+ (insert "bar")
+ (should (buffer-modified-p))
+ (should (null (save-buffer)))
+ (should-not (buffer-modified-p)))
+ (should (buffer-modified-p))
+ (should (null (save-buffer)))
+ (should-not (buffer-modified-p)))
+
+ (kill-buffer buffer1)
+ (kill-buffer buffer2)
+ ;; Read archive. Check contents of modified foo.txt.
+ (with-current-buffer (setq buffer1 (find-file-noselect tmp-file))
+ ;; The function was introduced in Emacs 28.1.
+ (with-no-warnings (should (tar-goto-file "foo.txt")))
+ (save-current-buffer
+ (setq buffer2 (tar-extract))
+ (should (string-equal (buffer-string) "foo\nbar\n")))))
+
+ ;; Cleanup.
+ (ignore-errors (kill-buffer buffer1))
+ (ignore-errors (kill-buffer buffer2))
+ (ignore-errors (delete-file tmp-file)))))
+
(ert-deftest tramp-test11-copy-file ()
"Check `copy-file'."
(skip-unless (tramp--test-enabled))
@@ -2548,7 +2629,7 @@ This checks also `file-name-as-directory', `file-name-directory',
(progn
(should-error
(copy-file source target)
- :type tramp-file-missing)
+ :type 'file-missing)
(write-region "foo" nil source)
(should (file-exists-p source))
(copy-file source target)
@@ -2574,9 +2655,7 @@ This checks also `file-name-as-directory', `file-name-directory',
(should (file-exists-p source))
(make-directory target)
(should (file-directory-p target))
- ;; This has been changed in Emacs 26.1.
- (when (and (tramp--test-expensive-test-p)
- (tramp--test-emacs26-p))
+ (when (tramp--test-expensive-test-p)
(should-error
(copy-file source target)
:type 'file-already-exists)
@@ -2662,7 +2741,7 @@ This checks also `file-name-as-directory', `file-name-directory',
(progn
(should-error
(rename-file source target)
- :type tramp-file-missing)
+ :type 'file-missing)
(write-region "foo" nil source)
(should (file-exists-p source))
(rename-file source target)
@@ -2691,9 +2770,7 @@ This checks also `file-name-as-directory', `file-name-directory',
(should (file-exists-p source))
(make-directory target)
(should (file-directory-p target))
- ;; This has been changed in Emacs 26.1.
- (when (and (tramp--test-expensive-test-p)
- (tramp--test-emacs26-p))
+ (when (tramp--test-expensive-test-p)
(should-error
(rename-file source target)
:type 'file-already-exists)
@@ -2874,7 +2951,7 @@ This tests also `file-directory-p' and `file-accessible-directory-p'."
(ert-deftest tramp-test15-copy-directory ()
"Check `copy-directory'."
(skip-unless (tramp--test-enabled))
- (skip-unless (or (tramp--test-emacs26-p) (not (tramp--test-rclone-p))))
+ (skip-unless (not (tramp--test-rclone-p)))
(dolist (quoted (if (tramp--test-expensive-test-p) '(nil t) '(nil)))
(let* ((tmp-name1 (tramp--test-make-temp-name nil quoted))
@@ -2891,7 +2968,7 @@ This tests also `file-directory-p' and `file-accessible-directory-p'."
(progn
(should-error
(copy-directory tmp-name1 tmp-name2)
- :type tramp-file-missing)
+ :type 'file-missing)
;; Copy empty directory.
(make-directory tmp-name1)
(write-region "foo" nil tmp-name4)
@@ -2901,11 +2978,9 @@ This tests also `file-directory-p' and `file-accessible-directory-p'."
(should (file-directory-p tmp-name2))
(should (file-exists-p tmp-name5))
;; Target directory does exist already.
- ;; This has been changed in Emacs 26.1.
- (when (tramp--test-emacs26-p)
- (should-error
- (copy-directory tmp-name1 tmp-name2)
- :type 'file-already-exists))
+ (should-error
+ (copy-directory tmp-name1 tmp-name2)
+ :type 'file-already-exists)
(copy-directory tmp-name1 (file-name-as-directory tmp-name2))
(should (file-directory-p tmp-name3))
(should (file-exists-p tmp-name6)))
@@ -2996,7 +3071,7 @@ This tests also `file-directory-p' and `file-accessible-directory-p'."
(progn
(should-error
(directory-files tmp-name1)
- :type tramp-file-missing)
+ :type 'file-missing)
(make-directory tmp-name1)
(write-region "foo" nil tmp-name2)
(write-region "bla" nil tmp-name3)
@@ -3120,14 +3195,12 @@ This tests also `file-directory-p' and `file-accessible-directory-p'."
(insert-directory tmp-name1 nil)
(goto-char (point-min))
(should (looking-at-p (regexp-quote tmp-name1))))
- ;; This has been fixed in Emacs 26.1. See Bug#29423.
- (when (tramp--test-emacs26-p)
- (with-temp-buffer
- (insert-directory (file-name-as-directory tmp-name1) nil)
- (goto-char (point-min))
- (should
- (looking-at-p
- (regexp-quote (file-name-as-directory tmp-name1))))))
+ (with-temp-buffer
+ (insert-directory (file-name-as-directory tmp-name1) nil)
+ (goto-char (point-min))
+ (should
+ (looking-at-p
+ (regexp-quote (file-name-as-directory tmp-name1)))))
(with-temp-buffer
(insert-directory tmp-name1 "-al")
(goto-char (point-min))
@@ -3159,7 +3232,7 @@ This tests also `file-directory-p' and `file-accessible-directory-p'."
;; modes are still "accessible".
(not (tramp--test-sshfs-p))
;; A directory is always accessible for user "root".
- (not (zerop (tramp-compat-file-attribute-user-id
+ (not (zerop (file-attribute-user-id
(file-attributes tmp-name1)))))
(set-file-modes tmp-name1 0)
(with-temp-buffer
@@ -3171,7 +3244,7 @@ This tests also `file-directory-p' and `file-accessible-directory-p'."
(with-temp-buffer
(should-error
(insert-directory tmp-name1 nil)
- :type tramp-file-missing)))
+ :type 'file-missing)))
;; Cleanup.
(ignore-errors (delete-directory tmp-name1 'recursive))))))
@@ -3179,14 +3252,12 @@ This tests also `file-directory-p' and `file-accessible-directory-p'."
(ert-deftest tramp-test17-dired-with-wildcards ()
"Check `dired' with wildcards."
;; `separate' syntax and IPv6 host name syntax do not work.
- (skip-unless (not (string-match-p "\\[" tramp-test-temporary-file-directory)))
+ (skip-unless (not (string-match-p "\\[" ert-remote-temporary-file-directory)))
(skip-unless (tramp--test-enabled))
(skip-unless (tramp--test-sh-p))
(skip-unless (not (tramp--test-rsync-p)))
;; Wildcards are not supported in tramp-crypt.el.
(skip-unless (not (tramp--test-crypt-p)))
- ;; Since Emacs 26.1.
- (skip-unless (fboundp 'insert-directory-wildcard-in-dir-p))
(dolist (quoted (if (tramp--test-expensive-test-p) '(nil t) '(nil)))
(let* ((tmp-name1
@@ -3195,10 +3266,10 @@ This tests also `file-directory-p' and `file-accessible-directory-p'."
(expand-file-name (tramp--test-make-temp-name nil quoted)))
(tmp-name3 (expand-file-name "foo" tmp-name1))
(tmp-name4 (expand-file-name "bar" tmp-name2))
- (tramp-test-temporary-file-directory
+ (ert-remote-temporary-file-directory
(funcall
(if quoted #'tramp-compat-file-name-quote #'identity)
- tramp-test-temporary-file-directory))
+ ert-remote-temporary-file-directory))
buffer)
(unwind-protect
(progn
@@ -3216,19 +3287,19 @@ This tests also `file-directory-p' and `file-accessible-directory-p'."
(setq buffer
(dired-noselect
(expand-file-name
- "tramp-test*" tramp-test-temporary-file-directory)))
+ "tramp-test*" ert-remote-temporary-file-directory)))
(goto-char (point-min))
(should
(re-search-forward
(regexp-quote
(file-relative-name
- tmp-name1 tramp-test-temporary-file-directory))))
+ tmp-name1 ert-remote-temporary-file-directory))))
(goto-char (point-min))
(should
(re-search-forward
(regexp-quote
(file-relative-name
- tmp-name2 tramp-test-temporary-file-directory)))))
+ tmp-name2 ert-remote-temporary-file-directory)))))
(kill-buffer buffer)
;; Check for expanded directory and file names.
@@ -3236,20 +3307,20 @@ This tests also `file-directory-p' and `file-accessible-directory-p'."
(setq buffer
(dired-noselect
(expand-file-name
- "tramp-test*/*" tramp-test-temporary-file-directory)))
+ "tramp-test*/*" ert-remote-temporary-file-directory)))
(goto-char (point-min))
(should
(re-search-forward
(regexp-quote
(file-relative-name
- tmp-name3 tramp-test-temporary-file-directory))))
+ tmp-name3 ert-remote-temporary-file-directory))))
(goto-char (point-min))
(should
(re-search-forward
(regexp-quote
(file-relative-name
tmp-name4
- tramp-test-temporary-file-directory)))))
+ ert-remote-temporary-file-directory)))))
(kill-buffer buffer)
;; Check for special characters.
@@ -3264,20 +3335,20 @@ This tests also `file-directory-p' and `file-accessible-directory-p'."
(setq buffer
(dired-noselect
(expand-file-name
- "tramp-test*/*" tramp-test-temporary-file-directory)))
+ "tramp-test*/*" ert-remote-temporary-file-directory)))
(goto-char (point-min))
(should
(re-search-forward
(regexp-quote
(file-relative-name
- tmp-name3 tramp-test-temporary-file-directory))))
+ tmp-name3 ert-remote-temporary-file-directory))))
(goto-char (point-min))
(should
(re-search-forward
(regexp-quote
(file-relative-name
tmp-name4
- tramp-test-temporary-file-directory)))))
+ ert-remote-temporary-file-directory)))))
(kill-buffer buffer))
;; Cleanup.
@@ -3315,7 +3386,7 @@ This tests also `file-directory-p' and `file-accessible-directory-p'."
(goto-char (point-min))
(while (not (or (eobp)
(string-equal
- (dired-get-filename 'localp 'no-error)
+ (dired-get-filename 'no-dir 'no-error)
(file-name-nondirectory tmp-name2))))
(forward-line 1))
(should-not (eobp))
@@ -3325,14 +3396,14 @@ This tests also `file-directory-p' and `file-accessible-directory-p'."
;; Point shall still be the recent file.
(should
(string-equal
- (dired-get-filename 'localp 'no-error)
+ (dired-get-filename 'no-dir 'no-error)
(file-name-nondirectory tmp-name2)))
(should-not (re-search-forward "dired" nil t))
;; The copied file has been inserted the line before.
(forward-line -1)
(should
(string-equal
- (dired-get-filename 'localp 'no-error)
+ (dired-get-filename 'no-dir 'no-error)
(file-name-nondirectory tmp-name3))))
(kill-buffer buffer))
@@ -3350,8 +3421,8 @@ This tests also `access-file', `file-readable-p',
;; We must use `file-truename' for the temporary directory,
;; because it could be located on a symlinked directory. This
;; would let the test fail.
- (let* ((tramp-test-temporary-file-directory
- (file-truename tramp-test-temporary-file-directory))
+ (let* ((ert-remote-temporary-file-directory
+ (file-truename ert-remote-temporary-file-directory))
(tmp-name1 (tramp--test-make-temp-name nil quoted))
(tmp-name2 (tramp--test-make-temp-name nil quoted))
;; File name with "//".
@@ -3371,28 +3442,27 @@ This tests also `access-file', `file-readable-p',
(and test-file-ownership-preserved-p
(zerop (logand
#o1000
- (file-modes tramp-test-temporary-file-directory))))
+ (file-modes ert-remote-temporary-file-directory))))
(write-region "foo" nil tmp-name1)
(setq test-file-ownership-preserved-p
- (= (tramp-compat-file-attribute-group-id
- (file-attributes tmp-name1))
+ (= (file-attribute-group-id (file-attributes tmp-name1))
(tramp-get-remote-gid tramp-test-vec 'integer)))
(delete-file tmp-name1))
(when (tramp--test-supports-set-file-modes-p)
(write-region "foo" nil tmp-name1)
;; A file is always accessible for user "root".
- (when (not (zerop (tramp-compat-file-attribute-user-id
- (file-attributes tmp-name1))))
+ (unless
+ (zerop (file-attribute-user-id (file-attributes tmp-name1)))
(set-file-modes tmp-name1 0)
(should-error
(access-file tmp-name1 "error")
- :type 'file-error)
+ :type tramp-permission-denied)
(set-file-modes tmp-name1 #o777))
(delete-file tmp-name1))
(should-error
(access-file tmp-name1 "error")
- :type tramp-file-missing)
+ :type 'file-missing)
;; `file-ownership-preserved-p' should return t for
;; non-existing files.
@@ -3409,33 +3479,29 @@ This tests also `access-file', `file-readable-p',
;; We do not test inodes and device numbers.
(setq attr (file-attributes tmp-name1))
(should (consp attr))
- (should (null (tramp-compat-file-attribute-type attr)))
- (should (numberp (tramp-compat-file-attribute-link-number attr)))
- (should (numberp (tramp-compat-file-attribute-user-id attr)))
- (should (numberp (tramp-compat-file-attribute-group-id attr)))
+ (should (null (file-attribute-type attr)))
+ (should (numberp (file-attribute-link-number attr)))
+ (should (numberp (file-attribute-user-id attr)))
+ (should (numberp (file-attribute-group-id attr)))
(should
- (stringp
- (current-time-string
- (tramp-compat-file-attribute-access-time attr))))
+ (stringp (current-time-string (file-attribute-access-time attr))))
(should
(stringp
- (current-time-string
- (tramp-compat-file-attribute-modification-time attr))))
+ (current-time-string (file-attribute-modification-time attr))))
(should
(stringp
- (current-time-string
- (tramp-compat-file-attribute-status-change-time attr))))
- (should (numberp (tramp-compat-file-attribute-size attr)))
- (should (stringp (tramp-compat-file-attribute-modes attr)))
+ (current-time-string (file-attribute-status-change-time attr))))
+ (should (numberp (file-attribute-size attr)))
+ (should (stringp (file-attribute-modes attr)))
(setq attr (file-attributes tmp-name1 'string))
- (should (stringp (tramp-compat-file-attribute-user-id attr)))
- (should (stringp (tramp-compat-file-attribute-group-id attr)))
+ (should (stringp (file-attribute-user-id attr)))
+ (should (stringp (file-attribute-group-id attr)))
(tramp--test-ignore-make-symbolic-link-error
(should-error
(access-file tmp-name2 "error")
- :type tramp-file-missing)
+ :type 'file-missing)
(when test-file-ownership-preserved-p
(should (file-ownership-preserved-p tmp-name2 'group)))
(make-symbolic-link tmp-name1 tmp-name2)
@@ -3449,13 +3515,13 @@ This tests also `access-file', `file-readable-p',
(string-equal
(funcall
(if quoted #'tramp-compat-file-name-quote #'identity)
- (tramp-compat-file-attribute-type attr))
+ (file-attribute-type attr))
(file-remote-p (file-truename tmp-name1) 'localname)))
(delete-file tmp-name2))
;; Check, that "//" in symlinks are handled properly.
(with-temp-buffer
- (let ((default-directory tramp-test-temporary-file-directory))
+ (let ((default-directory ert-remote-temporary-file-directory))
(shell-command
(format
"ln -s %s %s"
@@ -3468,7 +3534,7 @@ This tests also `access-file', `file-readable-p',
(setq attr (file-attributes tmp-name2))
(should
(string-equal
- (tramp-compat-file-attribute-type attr)
+ (file-attribute-type attr)
(funcall
(if (tramp--test-sshfs-p) #'file-name-nondirectory #'identity)
(tramp-file-name-localname
@@ -3486,7 +3552,7 @@ This tests also `access-file', `file-readable-p',
(when test-file-ownership-preserved-p
(should (file-ownership-preserved-p tmp-name1 'group)))
(setq attr (file-attributes tmp-name1))
- (should (eq (tramp-compat-file-attribute-type attr) t)))
+ (should (eq (file-attribute-type attr) t)))
;; Cleanup.
(ignore-errors (delete-directory tmp-name1))
@@ -3504,9 +3570,9 @@ They might differ only in time attributes or directory size."
(start-time (- tramp--test-start-time 10)))
;; Link number. For directories, it includes the number of
;; subdirectories. Set it to 1.
- (when (eq (tramp-compat-file-attribute-type attr1) t)
+ (when (eq (file-attribute-type attr1) t)
(setcar (nthcdr 1 attr1) 1))
- (when (eq (tramp-compat-file-attribute-type attr2) t)
+ (when (eq (file-attribute-type attr2) t)
(setcar (nthcdr 1 attr2) 1))
;; Access time.
(setcar (nthcdr 4 attr1) tramp-time-dont-know)
@@ -3519,42 +3585,33 @@ They might differ only in time attributes or directory size."
;; order to compensate a possible timestamp resolution higher than
;; a second on the remote machine.
(when (or (tramp-compat-time-equal-p
- (tramp-compat-file-attribute-modification-time attr1)
- tramp-time-dont-know)
+ (file-attribute-modification-time attr1) tramp-time-dont-know)
(tramp-compat-time-equal-p
- (tramp-compat-file-attribute-modification-time attr2)
- tramp-time-dont-know))
+ (file-attribute-modification-time attr2) tramp-time-dont-know))
(setcar (nthcdr 5 attr1) tramp-time-dont-know)
(setcar (nthcdr 5 attr2) tramp-time-dont-know))
(when (< start-time
- (float-time (tramp-compat-file-attribute-modification-time attr1)))
+ (float-time (file-attribute-modification-time attr1)))
(setcar (nthcdr 5 attr1) tramp-time-dont-know))
(when (< start-time
- (float-time (tramp-compat-file-attribute-modification-time attr2)))
+ (float-time (file-attribute-modification-time attr2)))
(setcar (nthcdr 5 attr2) tramp-time-dont-know))
;; Status change time. Ditto.
(when (or (tramp-compat-time-equal-p
- (tramp-compat-file-attribute-status-change-time attr1)
- tramp-time-dont-know)
+ (file-attribute-status-change-time attr1) tramp-time-dont-know)
(tramp-compat-time-equal-p
- (tramp-compat-file-attribute-status-change-time attr2)
- tramp-time-dont-know))
+ (file-attribute-status-change-time attr2) tramp-time-dont-know))
(setcar (nthcdr 6 attr1) tramp-time-dont-know)
(setcar (nthcdr 6 attr2) tramp-time-dont-know))
- (when
- (< start-time
- (float-time
- (tramp-compat-file-attribute-status-change-time attr1)))
+ (when (< start-time (float-time (file-attribute-status-change-time attr1)))
(setcar (nthcdr 6 attr1) tramp-time-dont-know))
- (when
- (< start-time
- (float-time (tramp-compat-file-attribute-status-change-time attr2)))
+ (when (< start-time (float-time (file-attribute-status-change-time attr2)))
(setcar (nthcdr 6 attr2) tramp-time-dont-know))
;; Size. Set it to 0 for directories, because it might have
;; changed. For example the upper directory "../".
- (when (eq (tramp-compat-file-attribute-type attr1) t)
+ (when (eq (file-attribute-type attr1) t)
(setcar (nthcdr 7 attr1) 0))
- (when (eq (tramp-compat-file-attribute-type attr2) t)
+ (when (eq (file-attribute-type attr2) t)
(setcar (nthcdr 7 attr2) 0))
;; The check.
(unless (equal attr1 attr2) (tramp--test-message "%S\n%S" attr1 attr2))
@@ -3578,12 +3635,12 @@ They might differ only in time attributes or directory size."
(progn
(should-error
(directory-files-and-attributes tmp-name1)
- :type tramp-file-missing)
+ :type 'file-missing)
(make-directory tmp-name1)
(should (file-directory-p tmp-name1))
(setq tramp--test-start-time
(float-time
- (tramp-compat-file-attribute-modification-time
+ (file-attribute-modification-time
(file-attributes tmp-name1))))
(make-directory tmp-name2)
(should (file-directory-p tmp-name2))
@@ -3641,9 +3698,9 @@ This tests also `file-executable-p', `file-writable-p' and `set-file-modes'."
(should (= (file-modes tmp-name1) #o444))
(should-not (file-executable-p tmp-name1))
;; A file is always writable for user "root".
- (unless (or (zerop (tramp-compat-file-attribute-user-id
- (file-attributes tmp-name1)))
- (tramp--test-sshfs-p))
+ (unless
+ (or (zerop (file-attribute-user-id (file-attributes tmp-name1)))
+ (tramp--test-sshfs-p))
(should-not (file-writable-p tmp-name1)))
;; Check the NOFOLLOW arg. It exists since Emacs 28. For
;; regular files, there shouldn't be a difference.
@@ -3717,16 +3774,13 @@ This tests also `file-executable-p', `file-writable-p' and `set-file-modes'."
"Check `file-symlink-p'.
This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
(skip-unless (tramp--test-enabled))
- ;; The semantics have changed heavily in Emacs 26.1. We cannot test
- ;; older Emacsen, therefore.
- (skip-unless (tramp--test-emacs26-p))
(dolist (quoted (if (tramp--test-expensive-test-p) '(nil t) '(nil)))
;; We must use `file-truename' for the temporary directory,
;; because it could be located on a symlinked directory. This
;; would let the test fail.
- (let* ((tramp-test-temporary-file-directory
- (file-truename tramp-test-temporary-file-directory))
+ (let* ((ert-remote-temporary-file-directory
+ (file-truename ert-remote-temporary-file-directory))
(tmp-name1 (tramp--test-make-temp-name nil quoted))
(tmp-name2 (tramp--test-make-temp-name nil quoted))
(tmp-name3 (tramp--test-make-temp-name 'local quoted))
@@ -3873,7 +3927,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
(should (file-equal-p tmp-name1 tmp-name2))
;; Check relative symlink file name.
(delete-file tmp-name2)
- (let ((default-directory tramp-test-temporary-file-directory))
+ (let ((default-directory ert-remote-temporary-file-directory))
(make-symbolic-link (file-name-nondirectory tmp-name1) tmp-name2))
(should (file-symlink-p tmp-name2))
(should-not (string-equal tmp-name2 (file-truename tmp-name2)))
@@ -3920,7 +3974,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
(tramp--test-ignore-make-symbolic-link-error
(make-directory tmp-name1)
(should (file-directory-p tmp-name1))
- (let* ((tramp-test-temporary-file-directory
+ (let* ((ert-remote-temporary-file-directory
(file-truename tmp-name1))
(tmp-name2 (tramp--test-make-temp-name nil quoted))
(tmp-name3 tmp-name2)
@@ -3936,11 +3990,11 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
(when (tramp--test-expensive-test-p)
(should-error
(with-temp-buffer (insert-file-contents tmp-name2))
- :type tramp-file-missing))
+ :type 'file-missing))
(when (tramp--test-expensive-test-p)
(should-error
(with-temp-buffer (insert-file-contents tmp-name3))
- :type tramp-file-missing))
+ :type 'file-missing))
;; `directory-files' does not show symlinks to
;; non-existing targets in the "smb" case. So we remove
;; the symlinks manually.
@@ -3981,7 +4035,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
(directory-file-name
(funcall
(if quoted #'tramp-compat-file-name-quote #'identity)
- tramp-test-temporary-file-directory)))
+ ert-remote-temporary-file-directory)))
(dir2 (file-name-as-directory dir1)))
(should (string-equal (file-truename dir1) (expand-file-name dir1)))
(should (string-equal (file-truename dir2) (expand-file-name dir2)))))))
@@ -4001,7 +4055,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
(progn
(write-region "foo" nil tmp-name1)
(should (file-exists-p tmp-name1))
- (should (consp (tramp-compat-file-attribute-modification-time
+ (should (consp (file-attribute-modification-time
(file-attributes tmp-name1))))
;; Skip the test, if the remote handler is not able to set
;; the correct time.
@@ -4009,13 +4063,12 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
;; Dumb remote shells without perl(1) or stat(1) are not
;; able to return the date correctly. They say "don't know".
(unless (tramp-compat-time-equal-p
- (tramp-compat-file-attribute-modification-time
+ (file-attribute-modification-time
(file-attributes tmp-name1))
tramp-time-dont-know)
(should
(tramp-compat-time-equal-p
- (tramp-compat-file-attribute-modification-time
- (file-attributes tmp-name1))
+ (file-attribute-modification-time (file-attributes tmp-name1))
(seconds-to-time 1)))
(write-region "bla" nil tmp-name2)
(should (file-exists-p tmp-name2))
@@ -4030,7 +4083,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
(set-file-times tmp-name1 (seconds-to-time 1) 'nofollow)
(should
(tramp-compat-time-equal-p
- (tramp-compat-file-attribute-modification-time
+ (file-attribute-modification-time
(file-attributes tmp-name1))
(seconds-to-time 1)))))))
@@ -4072,7 +4125,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
"Check that `file-acl' and `set-file-acl' work proper."
(skip-unless (tramp--test-enabled))
;; The following test checks also whether `set-file-modes' will work.
- (skip-unless (file-acl tramp-test-temporary-file-directory))
+ (skip-unless (file-acl ert-remote-temporary-file-directory))
(skip-unless (not (tramp--test-crypt-p)))
;; `filename-non-special' has been fixed in Emacs 27.1, see Bug#29579.
@@ -4093,7 +4146,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
(should (file-acl tmp-name2))
(should (string-equal (file-acl tmp-name1) (file-acl tmp-name2)))
;; Different permissions mean different ACLs.
- (when (not (tramp--test-windows-nt-or-smb-p))
+ (unless (tramp--test-windows-nt-or-smb-p)
(set-file-modes tmp-name1 #o777)
(set-file-modes tmp-name2 #o444)
(should-not
@@ -4151,7 +4204,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
"Check `file-selinux-context' and `set-file-selinux-context'."
(skip-unless (tramp--test-enabled))
(skip-unless
- (not (equal (file-selinux-context tramp-test-temporary-file-directory)
+ (not (equal (file-selinux-context ert-remote-temporary-file-directory)
'(nil nil nil nil))))
(skip-unless (not (tramp--test-crypt-p)))
@@ -4212,7 +4265,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
(let ((default-directory temporary-file-directory))
(shell-command-to-string "id -Z"))
(let ((default-directory
- tramp-test-temporary-file-directory))
+ ert-remote-temporary-file-directory))
(shell-command-to-string "id -Z"))))
;; Two files with same SELinux context.
@@ -4295,10 +4348,10 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
;; Method and host name in completion mode. This kind of completion
;; does not work on MS Windows.
- (when (not (memq system-type '(cygwin windows-nt)))
+ (unless (memq system-type '(cygwin windows-nt))
(let ((tramp-fuse-remove-hidden-files t)
- (method (file-remote-p tramp-test-temporary-file-directory 'method))
- (host (file-remote-p tramp-test-temporary-file-directory 'host))
+ (method (file-remote-p ert-remote-temporary-file-directory 'method))
+ (host (file-remote-p ert-remote-temporary-file-directory 'host))
(orig-syntax tramp-syntax))
(when (and (stringp host) (string-match tramp-host-with-port-regexp host))
(setq host (match-string 1 host)))
@@ -4450,7 +4503,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
(dolist (quoted (if (tramp--test-expensive-test-p) '(nil t) '(nil)))
(let* ((tmp-name (tramp--test-make-temp-name nil quoted))
(fnnd (file-name-nondirectory tmp-name))
- (default-directory tramp-test-temporary-file-directory)
+ (default-directory ert-remote-temporary-file-directory)
(buffer (get-buffer-create "*tramp-tests*"))
kill-buffer-query-functions)
(unwind-protect
@@ -4584,16 +4637,19 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
(skip-unless (tramp--test-supports-processes-p))
(dolist (quoted (if (tramp--test-expensive-test-p) '(nil t) '(nil)))
- (let ((default-directory tramp-test-temporary-file-directory)
+ (let ((default-directory ert-remote-temporary-file-directory)
(tmp-name (tramp--test-make-temp-name nil quoted))
- kill-buffer-query-functions proc)
+ kill-buffer-query-functions command proc)
;; Simple process.
(unwind-protect
(with-temp-buffer
- (setq proc (start-file-process "test1" (current-buffer) "cat"))
+ (setq command '("cat")
+ proc
+ (apply #'start-file-process "test1" (current-buffer) command))
(should (processp proc))
(should (equal (process-status proc) 'run))
+ (should (equal (process-get proc 'remote-command) command))
(process-send-string proc "foo\n")
(process-send-eof proc)
;; Read output.
@@ -4610,11 +4666,11 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
(with-temp-buffer
(write-region "foo" nil tmp-name)
(should (file-exists-p tmp-name))
- (setq proc
- (start-file-process
- "test2" (current-buffer)
- "cat" (file-name-nondirectory tmp-name)))
+ (setq command `("cat" ,(file-name-nondirectory tmp-name))
+ proc
+ (apply #'start-file-process "test2" (current-buffer) command))
(should (processp proc))
+ (should (equal (process-get proc 'remote-command) command))
;; Read output.
(with-timeout (10 (tramp--test-timeout-handler))
(while (< (- (point-max) (point-min)) (length "foo"))
@@ -4629,9 +4685,12 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
;; Process filter.
(unwind-protect
(with-temp-buffer
- (setq proc (start-file-process "test3" (current-buffer) "cat"))
+ (setq command '("cat")
+ proc
+ (apply #'start-file-process "test3" (current-buffer) command))
(should (processp proc))
(should (equal (process-status proc) 'run))
+ (should (equal (process-get proc 'remote-command) command))
(set-process-filter
proc
(lambda (p s) (with-current-buffer (process-buffer p) (insert s))))
@@ -4650,9 +4709,12 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
(unless (tramp--test-sshfs-p)
(unwind-protect
(with-temp-buffer
- (setq proc (start-file-process "test3" (current-buffer) "cat"))
+ (setq command '("cat")
+ proc
+ (apply #'start-file-process "test4" (current-buffer) command))
(should (processp proc))
(should (equal (process-status proc) 'run))
+ (should (equal (process-get proc 'remote-command) command))
(set-process-filter proc t)
(process-send-string proc "foo\n")
(process-send-eof proc)
@@ -4678,12 +4740,14 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
(dolist (process-connection-type '(nil pipe t pty))
(unwind-protect
(with-temp-buffer
- (setq proc
- (start-file-process
- (format "test4-%s" process-connection-type)
- (current-buffer) "hexdump" "-v" "-e" "/1 \"%02X\n\""))
+ (setq command '("hexdump" "-v" "-e" "/1 \"%02X\n\"")
+ proc
+ (apply #'start-file-process
+ (format "test5-%s" process-connection-type)
+ (current-buffer) command))
(should (processp proc))
(should (equal (process-status proc) 'run))
+ (should (equal (process-get proc 'remote-command) command))
(process-send-string proc "foo\r\n")
(process-send-eof proc)
;; Read output.
@@ -4711,12 +4775,13 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
;; It works only for tramp-sh.el, and not direct async processes.
(if (or (not (tramp--test-sh-p)) (tramp-direct-async-process-p))
(should-error
- (start-file-process "test5" (current-buffer) nil)
+ (start-file-process "test6" (current-buffer) nil)
:type 'wrong-type-argument)
- (setq proc (start-file-process "test5" (current-buffer) nil))
+ (setq proc (start-file-process "test6" (current-buffer) nil))
(should (processp proc))
(should (equal (process-status proc) 'run))
+ (should-not (process-get proc 'remote-command))
;; On MS Windows, `process-tty-name' returns nil.
(unless (tramp--test-windows-nt-p)
(should (stringp (process-tty-name proc))))))
@@ -4738,7 +4803,7 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'."
:tags (append '(:expensive-test :tramp-asynchronous-processes)
(and ,unstable '(:unstable)))
(skip-unless (tramp--test-enabled))
- (let ((default-directory tramp-test-temporary-file-directory)
+ (let ((default-directory ert-remote-temporary-file-directory)
(ert-test (ert-get-test ',test))
(tramp-connection-properties
(cons '(nil "direct-async-process" t)
@@ -4751,7 +4816,7 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'."
(cl-letf (((symbol-function #'tramp--test-enabled) #'tramp--test-always)
((symbol-function #'internal-default-process-sentinel)
#'ignore))
- (file-truename tramp-test-temporary-file-directory)
+ (file-truename ert-remote-temporary-file-directory)
(funcall (ert-test-body ert-test)))))))
(tramp--test--deftest-direct-async-process tramp-test29-start-file-process
@@ -4768,21 +4833,23 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'."
(skip-unless (tramp--test-emacs27-p))
(dolist (quoted (if (tramp--test-expensive-test-p) '(nil t) '(nil)))
- (let ((default-directory tramp-test-temporary-file-directory)
+ (let ((default-directory ert-remote-temporary-file-directory)
(tmp-name (tramp--test-make-temp-name nil quoted))
- kill-buffer-query-functions proc)
+ kill-buffer-query-functions command proc)
(with-no-warnings (should-not (make-process)))
;; Simple process.
(unwind-protect
(with-temp-buffer
- (setq proc
+ (setq command '("cat")
+ proc
(with-no-warnings
(make-process
- :name "test1" :buffer (current-buffer) :command '("cat")
+ :name "test1" :buffer (current-buffer) :command command
:file-handler t)))
(should (processp proc))
(should (equal (process-status proc) 'run))
+ (should (equal (process-get proc 'remote-command) command))
(process-send-string proc "foo\n")
(process-send-eof proc)
;; Read output.
@@ -4799,13 +4866,14 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'."
(with-temp-buffer
(write-region "foo" nil tmp-name)
(should (file-exists-p tmp-name))
- (setq proc
+ (setq command `("cat" ,(file-name-nondirectory tmp-name))
+ proc
(with-no-warnings
(make-process
- :name "test2" :buffer (current-buffer)
- :command `("cat" ,(file-name-nondirectory tmp-name))
+ :name "test2" :buffer (current-buffer) :command command
:file-handler t)))
(should (processp proc))
+ (should (equal (process-get proc 'remote-command) command))
;; Read output.
(with-timeout (10 (tramp--test-timeout-handler))
(while (< (- (point-max) (point-min)) (length "foo"))
@@ -4820,16 +4888,18 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'."
;; Process filter.
(unwind-protect
(with-temp-buffer
- (setq proc
+ (setq command '("cat")
+ proc
(with-no-warnings
(make-process
- :name "test3" :buffer (current-buffer) :command '("cat")
+ :name "test3" :buffer (current-buffer) :command command
:filter
(lambda (p s)
(with-current-buffer (process-buffer p) (insert s)))
:file-handler t)))
(should (processp proc))
(should (equal (process-status proc) 'run))
+ (should (equal (process-get proc 'remote-command) command))
(process-send-string proc "foo\n")
(process-send-eof proc)
;; Read output.
@@ -4845,14 +4915,16 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'."
(unless (tramp--test-sshfs-p)
(unwind-protect
(with-temp-buffer
- (setq proc
+ (setq command '("cat")
+ proc
(with-no-warnings
(make-process
- :name "test3" :buffer (current-buffer) :command '("cat")
+ :name "test4" :buffer (current-buffer) :command command
:filter t
:file-handler t)))
(should (processp proc))
(should (equal (process-status proc) 'run))
+ (should (equal (process-get proc 'remote-command) command))
(process-send-string proc "foo\n")
(process-send-eof proc)
;; Read output. There shouldn't be any.
@@ -4868,16 +4940,18 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'."
;; Process sentinel.
(unwind-protect
(with-temp-buffer
- (setq proc
+ (setq command '("cat")
+ proc
(with-no-warnings
(make-process
- :name "test4" :buffer (current-buffer) :command '("cat")
+ :name "test5" :buffer (current-buffer) :command command
:sentinel
(lambda (p s)
(with-current-buffer (process-buffer p) (insert s)))
:file-handler t)))
(should (processp proc))
(should (equal (process-status proc) 'run))
+ (should (equal (process-get proc 'remote-command) command))
(process-send-string proc "foo\n")
(process-send-eof proc)
(delete-process proc)
@@ -4896,14 +4970,15 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'."
(let ((stderr (generate-new-buffer "*stderr*")))
(unwind-protect
(with-temp-buffer
- (setq proc
+ (setq command '("cat" "/does-not-exist")
+ proc
(with-no-warnings
(make-process
- :name "test5" :buffer (current-buffer)
- :command '("cat" "/does-not-exist")
+ :name "test6" :buffer (current-buffer) :command command
:stderr stderr
:file-handler t)))
(should (processp proc))
+ (should (equal (process-get proc 'remote-command) command))
;; Read output.
(with-timeout (10 (tramp--test-timeout-handler))
(while (accept-process-output proc 0 nil t)))
@@ -4927,14 +5002,15 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'."
(unless (tramp-direct-async-process-p)
(unwind-protect
(with-temp-buffer
- (setq proc
+ (setq command '("cat" "/does-not-exist")
+ proc
(with-no-warnings
(make-process
- :name "test6" :buffer (current-buffer)
- :command '("cat" "/does-not-exist")
+ :name "test7" :buffer (current-buffer) :command command
:stderr tmp-name
:file-handler t)))
(should (processp proc))
+ (should (equal (process-get proc 'remote-command) command))
;; Read stderr.
(with-timeout (10 (tramp--test-timeout-handler))
(while (accept-process-output proc nil nil t)))
@@ -4965,18 +5041,20 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'."
(unless connection-type '(nil pipe t pty)))
(unwind-protect
(with-temp-buffer
- (setq proc
+ (setq command '("hexdump" "-v" "-e" "/1 \"%02X\n\"")
+ proc
(with-no-warnings
(make-process
:name
- (format "test7-%s-%s"
+ (format "test8-%s-%s"
connection-type process-connection-type)
:buffer (current-buffer)
:connection-type connection-type
- :command '("hexdump" "-v" "-e" "/1 \"%02X\n\"")
+ :command command
:file-handler t)))
(should (processp proc))
(should (equal (process-status proc) 'run))
+ (should (equal (process-get proc 'remote-command) command))
(process-send-string proc "foo\r\n")
(process-send-eof proc)
;; Read output.
@@ -5004,31 +5082,33 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'."
(ert-deftest tramp-test31-interrupt-process ()
"Check `interrupt-process'."
- :tags (append '(:expensive-test :tramp-asynchronous-processes)
- (and (or (getenv "EMACS_HYDRA_CI") (getenv "EMACS_EMBA_CI"))
- '(:unstable)))
+ ;; The final `process-live-p' check does not run sufficiently.
+ :tags '(:expensive-test :tramp-asynchronous-processes :unstable)
(skip-unless (tramp--test-enabled))
(skip-unless (tramp--test-sh-p))
(skip-unless (not (tramp--test-windows-nt-p)))
(skip-unless (not (tramp--test-crypt-p)))
- ;; Since Emacs 26.1.
- (skip-unless (boundp 'interrupt-process-functions))
+ ;; Since Emacs 27.1.
+ (skip-unless (macrop 'with-connection-local-variables))
;; We must use `file-truename' for the temporary directory, in
;; order to establish the connection prior running an asynchronous
;; process.
- (let ((default-directory (file-truename tramp-test-temporary-file-directory))
+ (let ((default-directory (file-truename ert-remote-temporary-file-directory))
(delete-exited-processes t)
- kill-buffer-query-functions proc)
+ kill-buffer-query-functions command proc)
(unwind-protect
(with-temp-buffer
- (setq proc (start-file-process-shell-command
- "test" (current-buffer)
- "trap 'echo boom; exit 1' 2; sleep 100"))
+ (setq command "trap 'echo boom; exit 1' 2; sleep 100"
+ proc (start-file-process-shell-command
+ "test" (current-buffer) command))
(should (processp proc))
(should (process-live-p proc))
(should (equal (process-status proc) 'run))
(should (numberp (process-get proc 'remote-pid)))
+ (should (equal (process-get proc 'remote-command)
+ (with-connection-local-variables
+ `(,shell-file-name ,shell-command-switch ,command))))
(should (interrupt-process proc))
;; Let the process accept the interrupt.
(with-timeout (10 (tramp--test-timeout-handler))
@@ -5043,12 +5123,132 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'."
;; Cleanup.
(ignore-errors (delete-process proc)))))
+(ert-deftest tramp-test31-signal-process ()
+ "Check `signal-process'."
+ ;; The final `process-live-p' check does not run sufficiently.
+ :tags '(:expensive-test :tramp-asynchronous-processes :unstable)
+ (skip-unless (tramp--test-enabled))
+ (skip-unless (tramp--test-sh-p))
+ (skip-unless (not (tramp--test-windows-nt-p)))
+ (skip-unless (not (tramp--test-crypt-p)))
+ ;; Since Emacs 27.1.
+ (skip-unless (macrop 'with-connection-local-variables))
+ ;; Since Emacs 29.1.
+ (skip-unless (boundp 'signal-process-functions))
+
+ ;; We must use `file-truename' for the temporary directory, in
+ ;; order to establish the connection prior running an asynchronous
+ ;; process.
+ (let ((default-directory (file-truename ert-remote-temporary-file-directory))
+ (delete-exited-processes t)
+ kill-buffer-query-functions command proc)
+
+ (dolist (sigcode '(2 INT))
+ (unwind-protect
+ (with-temp-buffer
+ (setq command "trap 'echo boom; exit 1' 2; sleep 100"
+ proc (start-file-process-shell-command
+ (format "test1%s" sigcode) (current-buffer) command))
+ (should (processp proc))
+ (should (process-live-p proc))
+ (should (equal (process-status proc) 'run))
+ (should (numberp (process-get proc 'remote-pid)))
+ (should (equal (process-get proc 'remote-command)
+ (with-connection-local-variables
+ `(,shell-file-name ,shell-command-switch ,command))))
+ (should (zerop (signal-process proc sigcode)))
+ ;; Let the process accept the signal.
+ (with-timeout (10 (tramp--test-timeout-handler))
+ (while (accept-process-output proc 0 nil t)))
+ (should-not (process-live-p proc)))
+
+ ;; Cleanup.
+ (ignore-errors (kill-process proc))
+ (ignore-errors (delete-process proc)))
+
+ (unwind-protect
+ (with-temp-buffer
+ (setq command "trap 'echo boom; exit 1' 2; sleep 100"
+ proc (start-file-process-shell-command
+ (format "test2%s" sigcode) (current-buffer) command))
+ (should (processp proc))
+ (should (process-live-p proc))
+ (should (equal (process-status proc) 'run))
+ (should (numberp (process-get proc 'remote-pid)))
+ (should (equal (process-get proc 'remote-command)
+ (with-connection-local-variables
+ `(,shell-file-name ,shell-command-switch ,command))))
+ ;; `signal-process' has argument REMOTE since Emacs 29.
+ (with-no-warnings
+ (should
+ (zerop
+ (signal-process
+ (process-get proc 'remote-pid) sigcode default-directory))))
+ ;; Let the process accept the signal.
+ (with-timeout (10 (tramp--test-timeout-handler))
+ (while (accept-process-output proc 0 nil t)))
+ (should-not (process-live-p proc)))
+
+ ;; Cleanup.
+ (ignore-errors (kill-process proc))
+ (ignore-errors (delete-process proc))))))
+
+(ert-deftest tramp-test31-list-system-processes ()
+ "Check `list-system-processes'."
+ :tags '(:expensive-test)
+ (skip-unless (tramp--test-enabled))
+ (skip-unless (tramp--test-supports-processes-p))
+ ;; `list-system-processes' is supported since Emacs 29.1.
+ (skip-unless (tramp--test-emacs29-p))
+
+ (let ((default-directory ert-remote-temporary-file-directory))
+ (skip-unless (consp (list-system-processes)))
+ (should (not (equal (list-system-processes)
+ (let ((default-directory temporary-file-directory))
+ (list-system-processes)))))))
+
+(ert-deftest tramp-test31-process-attributes ()
+ "Check `process-attributes'."
+ :tags '(:expensive-test :tramp-asynchronous-processes)
+ (skip-unless (tramp--test-enabled))
+ (skip-unless (tramp--test-supports-processes-p))
+ ;; `process-attributes' is supported since Emacs 29.1.
+ (skip-unless (tramp--test-emacs29-p))
+
+ ;; We must use `file-truename' for the temporary directory, in
+ ;; order to establish the connection prior running an asynchronous
+ ;; process.
+ (let ((default-directory (file-truename ert-remote-temporary-file-directory))
+ (delete-exited-processes t)
+ kill-buffer-query-functions command proc)
+ (skip-unless (consp (list-system-processes)))
+
+ (unwind-protect
+ (progn
+ (setq command '("sleep" "100")
+ proc (apply #'start-file-process "test" nil command))
+ (while (accept-process-output proc 0))
+ (when-let ((pid (process-get proc 'remote-pid))
+ (attributes (process-attributes pid)))
+ ;; (tramp--test-message "%s" attributes)
+ (should (equal (cdr (assq 'comm attributes)) (car command)))
+ (should (equal (cdr (assq 'args attributes))
+ (mapconcat #'identity command " ")))))
+
+ ;; Cleanup.
+ (ignore-errors (delete-process proc)))))
+
(defun tramp--test-async-shell-command
(command output-buffer &optional error-buffer input)
"Like `async-shell-command', reading the output.
INPUT, if non-nil, is a string sent to the process."
(let ((proc (async-shell-command command output-buffer error-buffer))
(delete-exited-processes t))
+ ;; Since Emacs 27.1.
+ (when (macrop 'with-connection-local-variables)
+ (should (equal (process-get proc 'remote-command)
+ (with-connection-local-variables
+ `(,shell-file-name ,shell-command-switch ,command)))))
(cl-letf (((symbol-function #'shell-command-sentinel) #'ignore))
(when (stringp input)
(process-send-string proc input))
@@ -5076,7 +5276,7 @@ INPUT, if non-nil, is a string sent to the process."
(dolist (quoted (if (tramp--test-expensive-test-p) '(nil t) '(nil)))
(let ((tmp-name (tramp--test-make-temp-name nil quoted))
- (default-directory tramp-test-temporary-file-directory)
+ (default-directory ert-remote-temporary-file-directory)
;; Suppress nasty messages.
(inhibit-message t)
kill-buffer-query-functions)
@@ -5121,8 +5321,8 @@ INPUT, if non-nil, is a string sent to the process."
"echo foo >&2; echo bar" (current-buffer) stderr)
(should (string-equal "bar\n" (buffer-string)))
;; Check stderr.
- (with-current-buffer stderr
- (should (string-equal "foo\n" (buffer-string)))))
+ (should
+ (string-equal "foo\n" (tramp-get-buffer-string stderr))))
;; Cleanup.
(ignore-errors (kill-buffer stderr))))))
@@ -5157,7 +5357,7 @@ INPUT, if non-nil, is a string sent to the process."
(when (and (tramp--test-asynchronous-processes-p)
(tramp--test-sh-p) (tramp--test-emacs27-p))
(let* ((async-shell-command-width 1024)
- (default-directory tramp-test-temporary-file-directory)
+ (default-directory ert-remote-temporary-file-directory)
(cols (ignore-errors
(read (tramp--test-shell-command-to-string-asynchronously
"tput cols")))))
@@ -5209,7 +5409,7 @@ INPUT, if non-nil, is a string sent to the process."
;; We check both the local and remote case, in order to guarantee
;; that they behave similar.
(dolist (default-directory
- `(,temporary-file-directory ,tramp-test-temporary-file-directory))
+ `(,temporary-file-directory ,ert-remote-temporary-file-directory))
;; These are the possible values of `shell-command-dont-erase-buffer'.
;; `random' is taken as non-nil value without special meaning.
(dolist (shell-command-dont-erase-buffer
@@ -5309,7 +5509,7 @@ INPUT, if non-nil, is a string sent to the process."
(and (tramp--test-asynchronous-processes-p)
'(tramp--test-shell-command-to-string-asynchronously))))
- (let ((default-directory tramp-test-temporary-file-directory)
+ (let ((default-directory ert-remote-temporary-file-directory)
(shell-file-name "/bin/sh")
(envvar (concat "VAR_" (upcase (md5 (current-time-string)))))
kill-buffer-query-functions)
@@ -5400,7 +5600,7 @@ Use direct async.")
(skip-unless (not (tramp--test-crypt-p)))
;; We force a reconnect, in order to have a clean environment.
- (dolist (dir `(,tramp-test-temporary-file-directory
+ (dolist (dir `(,ert-remote-temporary-file-directory
"/mock:localhost#11111:" "/mock:localhost#22222:"))
(tramp-cleanup-connection
(tramp-dissect-file-name dir) 'keep-debug 'keep-password))
@@ -5432,12 +5632,9 @@ Use direct async.")
:tags '(:expensive-test)
(skip-unless (tramp--test-enabled))
;; Since Emacs 27.1.
- (skip-unless (fboundp 'with-connection-local-variables))
+ (skip-unless (macrop 'with-connection-local-variables))
- ;; `connection-local-set-profile-variables' and
- ;; `connection-local-set-profiles' exist since Emacs 26.1. We don't
- ;; want to see compiler warnings for older Emacsen.
- (let* ((default-directory tramp-test-temporary-file-directory)
+ (let* ((default-directory ert-remote-temporary-file-directory)
(tmp-name1 (tramp--test-make-temp-name))
(tmp-name2 (expand-file-name "foo" tmp-name1))
(enable-local-variables :all)
@@ -5451,24 +5648,25 @@ Use direct async.")
(should (file-directory-p tmp-name1))
;; `local-variable' is buffer-local due to explicit setting.
+ ;; We need `with-no-warnings', because `defvar-local' is not
+ ;; called at toplevel.
(with-no-warnings
- (defvar-local local-variable 'buffer))
+ (defvar-local local-variable 'buffer))
(with-temp-buffer
(should (eq local-variable 'buffer)))
;; `local-variable' is connection-local due to Tramp.
(write-region "foo" nil tmp-name2)
(should (file-exists-p tmp-name2))
- (with-no-warnings
- (connection-local-set-profile-variables
- 'local-variable-profile
- '((local-variable . connect)))
- (connection-local-set-profiles
- `(:application tramp
- :protocol ,(file-remote-p default-directory 'method)
- :user ,(file-remote-p default-directory 'user)
- :machine ,(file-remote-p default-directory 'host))
- 'local-variable-profile))
+ (connection-local-set-profile-variables
+ 'local-variable-profile
+ '((local-variable . connect)))
+ (connection-local-set-profiles
+ `(:application tramp
+ :protocol ,(file-remote-p default-directory 'method)
+ :user ,(file-remote-p default-directory 'user)
+ :machine ,(file-remote-p default-directory 'host))
+ 'local-variable-profile)
(with-current-buffer (find-file-noselect tmp-name2)
(should (eq local-variable 'connect))
(kill-buffer (current-buffer)))
@@ -5493,7 +5691,6 @@ Use direct async.")
;; Cleanup.
(ignore-errors (delete-directory tmp-name1 'recursive)))))
-;; The functions were introduced in Emacs 26.1.
(ert-deftest tramp-test34-explicit-shell-file-name ()
"Check that connection-local `explicit-shell-file-name' is set."
:tags '(:expensive-test :tramp-asynchronous-processes)
@@ -5503,14 +5700,8 @@ Use direct async.")
;; remote processes in Emacs. That doesn't work for tramp-adb.el.
(when (tramp--test-adb-p)
(skip-unless (tramp--test-emacs27-p)))
- ;; Since Emacs 26.1.
- (skip-unless (and (fboundp 'connection-local-set-profile-variables)
- (fboundp 'connection-local-set-profiles)))
-
- ;; `connection-local-set-profile-variables' and
- ;; `connection-local-set-profiles' exist since Emacs 26.1. We don't
- ;; want to see compiler warnings for older Emacsen.
- (let ((default-directory tramp-test-temporary-file-directory)
+
+ (let ((default-directory ert-remote-temporary-file-directory)
explicit-shell-file-name kill-buffer-query-functions
connection-local-profile-alist connection-local-criteria-alist)
(unwind-protect
@@ -5518,19 +5709,16 @@ Use direct async.")
;; `shell-mode' would ruin our test, because it deletes all
;; buffer local variables. Not needed in Emacs 27.1.
(put 'explicit-shell-file-name 'permanent-local t)
- ;; Declare connection-local variables `explicit-shell-file-name'
- ;; and `explicit-sh-args'.
- (with-no-warnings
- (connection-local-set-profile-variables
- 'remote-sh
- `((explicit-shell-file-name . ,(tramp--test-shell-file-name))
- (explicit-sh-args . ("-c" "echo foo"))))
- (connection-local-set-profiles
- `(:application tramp
- :protocol ,(file-remote-p default-directory 'method)
- :user ,(file-remote-p default-directory 'user)
- :machine ,(file-remote-p default-directory 'host))
- 'remote-sh))
+ (connection-local-set-profile-variables
+ 'remote-sh
+ `((explicit-shell-file-name . ,(tramp--test-shell-file-name))
+ (explicit-sh-args . ("-c" "echo foo"))))
+ (connection-local-set-profiles
+ `(:application tramp
+ :protocol ,(file-remote-p default-directory 'method)
+ :user ,(file-remote-p default-directory 'user)
+ :machine ,(file-remote-p default-directory 'host))
+ 'remote-sh)
(put 'explicit-shell-file-name 'safe-local-variable #'identity)
(put 'explicit-sh-args 'safe-local-variable #'identity)
@@ -5563,7 +5751,7 @@ Use direct async.")
(skip-unless (fboundp 'exec-path))
(let ((tmp-name (tramp--test-make-temp-name))
- (default-directory tramp-test-temporary-file-directory))
+ (default-directory ert-remote-temporary-file-directory))
(unwind-protect
(progn
(should (consp (with-no-warnings (exec-path))))
@@ -5608,7 +5796,7 @@ Use direct async.")
(skip-unless (fboundp 'exec-path))
(let* ((tmp-name (tramp--test-make-temp-name))
- (default-directory tramp-test-temporary-file-directory)
+ (default-directory ert-remote-temporary-file-directory)
(orig-exec-path (with-no-warnings (exec-path)))
(tramp-remote-path tramp-remote-path)
(orig-tramp-remote-path tramp-remote-path)
@@ -5675,7 +5863,7 @@ Use direct async.")
;; order to establish the connection prior running an asynchronous
;; process.
(let* ((default-directory
- (file-truename tramp-test-temporary-file-directory))
+ (file-truename ert-remote-temporary-file-directory))
(tmp-name1 (tramp--test-make-temp-name nil quoted))
(tmp-name2 (expand-file-name "foo" tmp-name1))
(tramp-remote-process-environment tramp-remote-process-environment)
@@ -5779,7 +5967,7 @@ Use direct async.")
(if quoted #'tramp-compat-file-name-quote #'identity)
(expand-file-name
(format "#%s#" (file-name-nondirectory tmp-name1))
- tramp-test-temporary-file-directory))))))
+ ert-remote-temporary-file-directory))))))
;; Use default `tramp-auto-save-directory' mechanism.
;; Ange-FTP doesn't care.
@@ -5833,7 +6021,7 @@ Use direct async.")
;; files, owned by root.
(let ((tramp-auto-save-directory temporary-file-directory))
(write-region "foo" nil tmp-name1)
- (when (zerop (or (tramp-compat-file-attribute-user-id
+ (when (zerop (or (file-attribute-user-id
(file-attributes tmp-name1))
tramp-unknown-id-integer))
(with-temp-buffer
@@ -5884,7 +6072,7 @@ Use direct async.")
(if quoted #'tramp-compat-file-name-quote #'identity)
(expand-file-name
(format "%s~" (file-name-nondirectory tmp-name1))
- tramp-test-temporary-file-directory)))))))
+ ert-remote-temporary-file-directory)))))))
(unwind-protect
;; Map `backup-directory-alist'.
@@ -5980,8 +6168,7 @@ Use direct async.")
(let ((backup-directory-alist `(("." . ,temporary-file-directory)))
tramp-backup-directory-alist)
(write-region "foo" nil tmp-name1)
- (when (zerop (or (tramp-compat-file-attribute-user-id
- (file-attributes tmp-name1))
+ (when (zerop (or (file-attribute-user-id (file-attributes tmp-name1))
tramp-unknown-id-integer))
(tramp-cleanup-connection
tramp-test-vec 'keep-debug 'keep-password)
@@ -6043,7 +6230,9 @@ Use direct async.")
(with-temp-buffer
(set-visited-file-name tmp-name1)
(insert "foo")
- (save-buffer))
+ (should (buffer-modified-p))
+ (save-buffer)
+ (should-not (buffer-modified-p)))
(should-not (with-no-warnings (file-locked-p tmp-name1)))
(with-no-warnings (lock-file tmp-name1))
(should (eq (with-no-warnings (file-locked-p tmp-name1)) t))
@@ -6117,8 +6306,7 @@ Use direct async.")
;; files, owned by root.
(let ((lock-file-name-transforms auto-save-file-name-transforms))
(write-region "foo" nil tmp-name1)
- (when (zerop (or (tramp-compat-file-attribute-user-id
- (file-attributes tmp-name1))
+ (when (zerop (or (file-attribute-user-id (file-attributes tmp-name1))
tramp-unknown-id-integer))
(tramp-cleanup-connection
tramp-test-vec 'keep-debug 'keep-password)
@@ -6166,42 +6354,44 @@ Use direct async.")
;; buffer results in a prompt.
(cl-letf (((symbol-function 'yes-or-no-p)
(lambda (_) (ert-fail "Test failed unexpectedly"))))
- (save-buffer))
+ (should (buffer-modified-p))
+ (save-buffer)
+ (should-not (buffer-modified-p)))
(should-not (file-locked-p tmp-name))
- ;; Macro `ert-with-message-capture' was introduced in Emacs 26.1.
- (with-no-warnings (when (symbol-plist 'ert-with-message-capture)
- ;; For local files, just changing the file
- ;; modification on disk doesn't hurt, because file
- ;; contents in buffer and on disk are equal. For
- ;; remote files, file contents is not compared. We
- ;; mock an older modification time in buffer,
- ;; because Tramp regards modification times equal if
- ;; they differ for less than 2 seconds.
- (set-visited-file-modtime (time-add (current-time) -60))
- ;; Some Tramp methods cannot check the file
- ;; modification time properly, for them it doesn't
- ;; make sense to test.
- (when (not (verify-visited-file-modtime))
- (cl-letf (((symbol-function 'read-char-choice)
- (lambda (prompt &rest _) (message "%s" prompt) ?y)))
- (ert-with-message-capture captured-messages
- (insert "bar")
- (when create-lockfiles
- (should (string-match-p
- (format
- "^%s changed on disk; really edit the buffer\\?"
- (if (tramp--test-crypt-p)
- ".+" (file-name-nondirectory tmp-name)))
- captured-messages))
- (should (file-locked-p tmp-name)))))
-
- ;; `save-buffer' removes the file lock.
- (cl-letf (((symbol-function 'yes-or-no-p) #'tramp--test-always)
- ((symbol-function 'read-char-choice)
- (lambda (&rest _) ?y)))
- (save-buffer))
- (should-not (file-locked-p tmp-name))))))
+ ;; For local files, just changing the file
+ ;; modification on disk doesn't hurt, because file
+ ;; contents in buffer and on disk are equal. For
+ ;; remote files, file contents is not compared. We
+ ;; mock an older modification time in buffer, because
+ ;; Tramp regards modification times equal if they
+ ;; differ for less than 2 seconds.
+ (set-visited-file-modtime (time-add (current-time) -60))
+ ;; Some Tramp methods cannot check the file
+ ;; modification time properly, for them it doesn't
+ ;; make sense to test.
+ (when (not (verify-visited-file-modtime))
+ (cl-letf (((symbol-function 'read-char-choice)
+ (lambda (prompt &rest _) (message "%s" prompt) ?y)))
+ (ert-with-message-capture captured-messages
+ (insert "bar")
+ (when create-lockfiles
+ (should (string-match-p
+ (format
+ "^%s changed on disk; really edit the buffer\\?"
+ (if (tramp--test-crypt-p)
+ ".+" (file-name-nondirectory tmp-name)))
+ captured-messages))
+ (should (file-locked-p tmp-name)))))
+
+ ;; `save-buffer' removes the file lock.
+ (cl-letf (((symbol-function 'yes-or-no-p) #'tramp--test-always)
+ ((symbol-function 'read-char-choice)
+ (lambda (&rest _) ?y)))
+ (should (buffer-modified-p))
+ (save-buffer)
+ (should-not (buffer-modified-p)))
+ (should-not (file-locked-p tmp-name))))
;; Cleanup.
(set-buffer-modified-p nil)
@@ -6214,24 +6404,18 @@ Use direct async.")
"Check `make-nearby-temp-file' and `temporary-file-directory'."
(skip-unless (tramp--test-enabled))
(skip-unless (not (tramp--test-ange-ftp-p)))
- ;; Since Emacs 26.1.
- (skip-unless
- (and (fboundp 'make-nearby-temp-file) (fboundp 'temporary-file-directory)))
- ;; `make-nearby-temp-file' and `temporary-file-directory' exists
- ;; since Emacs 26.1. We don't want to see compiler warnings for
- ;; older Emacsen.
- (let ((default-directory tramp-test-temporary-file-directory)
+ (let ((default-directory ert-remote-temporary-file-directory)
tmp-file)
;; The remote host shall know a temporary file directory.
- (should (stringp (with-no-warnings (temporary-file-directory))))
+ (should (stringp (temporary-file-directory)))
(should
(string-equal
(file-remote-p default-directory)
- (file-remote-p (with-no-warnings (temporary-file-directory)))))
+ (file-remote-p (temporary-file-directory))))
;; The temporary file shall be located on the remote host.
- (setq tmp-file (with-no-warnings (make-nearby-temp-file "tramp-test")))
+ (setq tmp-file (make-nearby-temp-file "tramp-test"))
(should (file-exists-p tmp-file))
(should (file-regular-p tmp-file))
(should
@@ -6241,18 +6425,12 @@ Use direct async.")
(delete-file tmp-file)
(should-not (file-exists-p tmp-file))
- (setq tmp-file (with-no-warnings (make-nearby-temp-file "tramp-test" 'dir)))
+ (setq tmp-file (make-nearby-temp-file "tramp-test" 'dir))
(should (file-exists-p tmp-file))
(should (file-directory-p tmp-file))
(delete-directory tmp-file)
(should-not (file-exists-p tmp-file))))
-(defun tramp--test-emacs26-p ()
- "Check for Emacs version >= 26.1.
-Some semantics has been changed for there, w/o new functions or
-variables, so we check the Emacs version directly."
- (>= emacs-major-version 26))
-
(defun tramp--test-emacs27-p ()
"Check for Emacs version >= 27.1.
Some semantics has been changed for there, w/o new functions or
@@ -6265,20 +6443,26 @@ Some semantics has been changed for there, w/o new functions or
variables, so we check the Emacs version directly."
(>= emacs-major-version 28))
+(defun tramp--test-emacs29-p ()
+ "Check for Emacs version >= 29.1.
+Some semantics has been changed for there, w/o new functions or
+variables, so we check the Emacs version directly."
+ (>= emacs-major-version 29))
+
(defun tramp--test-adb-p ()
"Check, whether the remote host runs Android.
This requires restrictions of file name syntax."
- (tramp-adb-file-name-p tramp-test-temporary-file-directory))
+ (tramp-adb-file-name-p ert-remote-temporary-file-directory))
(defun tramp--test-ange-ftp-p ()
"Check, whether Ange-FTP is used."
(eq
- (tramp-find-foreign-file-name-handler tramp-test-temporary-file-directory)
+ (tramp-find-foreign-file-name-handler tramp-test-vec)
'tramp-ftp-file-name-handler))
(defun tramp--test-asynchronous-processes-p ()
"Whether asynchronous processes tests are run.
-This is used in tests which we dont't want to tag
+This is used in tests which we don't want to tag
`:tramp-asynchronous-processes' completely."
(and
(ert-select-tests
@@ -6291,17 +6475,17 @@ This is used in tests which we dont't want to tag
(defun tramp--test-crypt-p ()
"Check, whether the remote directory is crypted."
- (tramp-crypt-file-name-p tramp-test-temporary-file-directory))
+ (tramp-crypt-file-name-p ert-remote-temporary-file-directory))
(defun tramp--test-docker-p ()
"Check, whether the docker method is used.
This does not support some special file names."
(string-equal
- "docker" (file-remote-p tramp-test-temporary-file-directory 'method)))
+ "docker" (file-remote-p ert-remote-temporary-file-directory 'method)))
(defun tramp--test-expensive-test-p ()
"Whether expensive tests are run.
-This is used in tests which we dont't want to tag `:expensive'
+This is used in tests which we don't want to tag `:expensive'
completely."
(ert-select-tests
(ert--stats-selector ert--current-run-stats)
@@ -6313,7 +6497,7 @@ completely."
This does not support globbing characters in file names (yet)."
;; Globbing characters are ??, ?* and ?\[.
(string-match-p
- "ftp$" (file-remote-p tramp-test-temporary-file-directory 'method)))
+ "ftp$" (file-remote-p ert-remote-temporary-file-directory 'method)))
(defun tramp--test-fuse-p ()
"Check, whether an FUSE file system isused."
@@ -6322,20 +6506,20 @@ This does not support globbing characters in file names (yet)."
(defun tramp--test-gdrive-p ()
"Check, whether the gdrive method is used."
(string-equal
- "gdrive" (file-remote-p tramp-test-temporary-file-directory 'method)))
+ "gdrive" (file-remote-p ert-remote-temporary-file-directory 'method)))
(defun tramp--test-gvfs-p (&optional method)
"Check, whether the remote host runs a GVFS based method.
This requires restrictions of file name syntax.
If optional METHOD is given, it is checked first."
(or (member method tramp-gvfs-methods)
- (tramp-gvfs-file-name-p tramp-test-temporary-file-directory)))
+ (tramp-gvfs-file-name-p ert-remote-temporary-file-directory)))
(defun tramp--test-hpux-p ()
"Check, whether the remote host runs HP-UX.
Several special characters do not work properly there."
;; We must refill the cache. `file-truename' does it.
- (file-truename tramp-test-temporary-file-directory)
+ (file-truename ert-remote-temporary-file-directory)
(ignore-errors (tramp-check-remote-uname tramp-test-vec "^HP-UX")))
(defun tramp--test-ksh-p ()
@@ -6343,21 +6527,21 @@ Several special characters do not work properly there."
ksh93 makes some strange conversions of non-latin characters into
a $'' syntax."
;; We must refill the cache. `file-truename' does it.
- (file-truename tramp-test-temporary-file-directory)
+ (file-truename ert-remote-temporary-file-directory)
(string-match-p
"ksh$" (tramp-get-connection-property tramp-test-vec "remote-shell" "")))
(defun tramp--test-macos-p ()
"Check, whether the remote host runs macOS."
;; We must refill the cache. `file-truename' does it.
- (file-truename tramp-test-temporary-file-directory)
+ (file-truename ert-remote-temporary-file-directory)
(ignore-errors (tramp-check-remote-uname tramp-test-vec "Darwin")))
(defun tramp--test-mock-p ()
"Check, whether the mock method is used.
This does not support external Emacs calls."
(string-equal
- "mock" (file-remote-p tramp-test-temporary-file-directory 'method)))
+ "mock" (file-remote-p ert-remote-temporary-file-directory 'method)))
(defun tramp--test-out-of-band-p ()
"Check, whether an out-of-band method is used."
@@ -6366,13 +6550,13 @@ This does not support external Emacs calls."
(defun tramp--test-rclone-p ()
"Check, whether the remote host is offered by rclone.
This requires restrictions of file name syntax."
- (tramp-rclone-file-name-p tramp-test-temporary-file-directory))
+ (tramp-rclone-file-name-p ert-remote-temporary-file-directory))
(defun tramp--test-rsync-p ()
"Check, whether the rsync method is used.
This does not support special file names."
(string-equal
- "rsync" (file-remote-p tramp-test-temporary-file-directory 'method)))
+ "rsync" (file-remote-p ert-remote-temporary-file-directory 'method)))
(defun tramp--test-sh-p ()
"Check, whether the remote host runs a based method from tramp-sh.el."
@@ -6386,30 +6570,30 @@ Additionally, ls does not support \"--dired\"."
;; We must refill the cache. `insert-directory' does it.
;; This fails for tramp-crypt.el, so we ignore that.
(ignore-errors
- (insert-directory tramp-test-temporary-file-directory "-al"))
- (not (tramp-get-connection-property tramp-test-vec "ls--dired" nil)))))
+ (insert-directory ert-remote-temporary-file-directory "-al"))
+ (not (tramp-get-connection-property tramp-test-vec "ls--dired")))))
(defun tramp--test-share-p ()
"Check, whether the method needs a share."
(and (tramp--test-gvfs-p)
(string-match-p
"^\\(afp\\|davs?\\|smb\\)$"
- (file-remote-p tramp-test-temporary-file-directory 'method))))
+ (file-remote-p ert-remote-temporary-file-directory 'method))))
(defun tramp--test-sshfs-p ()
"Check, whether the remote host is offered by sshfs.
This requires restrictions of file name syntax."
- (tramp-sshfs-file-name-p tramp-test-temporary-file-directory))
+ (tramp-sshfs-file-name-p ert-remote-temporary-file-directory))
(defun tramp--test-sudoedit-p ()
"Check, whether the sudoedit method is used."
- (tramp-sudoedit-file-name-p tramp-test-temporary-file-directory))
+ (tramp-sudoedit-file-name-p ert-remote-temporary-file-directory))
(defun tramp--test-telnet-p ()
"Check, whether the telnet method is used.
This does not support special file names."
(string-equal
- "telnet" (file-remote-p tramp-test-temporary-file-directory 'method)))
+ "telnet" (file-remote-p ert-remote-temporary-file-directory 'method)))
(defun tramp--test-windows-nt-p ()
"Check, whether the locale host runs MS Windows."
@@ -6430,7 +6614,7 @@ This requires restrictions of file name syntax."
(defun tramp--test-smb-p ()
"Check, whether the locale or remote host runs MS Windows.
This requires restrictions of file name syntax."
- (tramp-smb-file-name-p tramp-test-temporary-file-directory))
+ (tramp-smb-file-name-p ert-remote-temporary-file-directory))
(defun tramp--test-supports-processes-p ()
"Return whether the method under test supports external processes."
@@ -6446,7 +6630,7 @@ This requires restrictions of file name syntax."
(and
(tramp--test-gvfs-p)
(string-match-p
- "ftp" (file-remote-p tramp-test-temporary-file-directory 'method)))))
+ "ftp" (file-remote-p ert-remote-temporary-file-directory 'method)))))
(defun tramp--test-check-files (&rest files)
"Run a simple but comprehensive test over every file in FILES."
@@ -6457,8 +6641,8 @@ This requires restrictions of file name syntax."
;; We must use `file-truename' for the temporary directory,
;; because it could be located on a symlinked directory. This
;; would let the test fail.
- (let* ((tramp-test-temporary-file-directory
- (file-truename tramp-test-temporary-file-directory))
+ (let* ((ert-remote-temporary-file-directory
+ (file-truename ert-remote-temporary-file-directory))
(tramp-fuse-remove-hidden-files t)
(tmp-name1 (tramp--test-make-temp-name nil quoted))
(tmp-name2 (tramp--test-make-temp-name 'local quoted))
@@ -6504,7 +6688,7 @@ This requires restrictions of file name syntax."
(string-equal
(funcall
(if quoted #'tramp-compat-file-name-quote #'identity)
- (tramp-compat-file-attribute-type (file-attributes file3)))
+ (file-attribute-type (file-attributes file3)))
(file-remote-p (file-truename file1) 'localname)))
;; Check file contents.
(with-temp-buffer
@@ -6535,7 +6719,7 @@ This requires restrictions of file name syntax."
(setq buffer (dired-noselect tmp-name1 "--dired -al"))
(goto-char (point-min))
(while (not (eobp))
- (when-let ((name (dired-get-filename 'localp 'no-error)))
+ (when-let ((name (dired-get-filename 'no-dir 'no-error)))
(unless
(string-match-p name directory-files-no-dot-files-regexp)
(should (member name files))))
@@ -6645,7 +6829,7 @@ This requires restrictions of file name syntax."
(dolist (elt files)
(let ((envvar (concat "VAR_" (upcase (md5 elt))))
(elt (encode-coding-string elt coding-system-for-read))
- (default-directory tramp-test-temporary-file-directory)
+ (default-directory ert-remote-temporary-file-directory)
(process-environment process-environment))
(setenv envvar elt)
;; The value of PS1 could confuse Tramp's detection
@@ -6730,7 +6914,7 @@ This requires restrictions of file name syntax."
(skip-unless (not (getenv "EMACS_HYDRA_CI"))) ; SLOW ~ 245s
(skip-unless (tramp--test-enabled))
(skip-unless (not (tramp--test-rsync-p)))
- (skip-unless (or (tramp--test-emacs26-p) (not (tramp--test-rclone-p))))
+ (skip-unless (not (tramp--test-rclone-p)))
(tramp--test-special-characters))
@@ -6743,12 +6927,12 @@ Use the \"stat\" command."
(skip-unless (tramp--test-sh-p))
(skip-unless (not (tramp--test-rsync-p)))
;; We cannot use `tramp-test-vec', because this fails during compilation.
- (with-parsed-tramp-file-name tramp-test-temporary-file-directory nil
+ (with-parsed-tramp-file-name ert-remote-temporary-file-directory nil
(skip-unless (tramp-get-remote-stat v)))
(let ((tramp-connection-properties
(append
- `((,(regexp-quote (file-remote-p tramp-test-temporary-file-directory))
+ `((,(regexp-quote (file-remote-p ert-remote-temporary-file-directory))
"perl" nil))
tramp-connection-properties)))
(tramp--test-special-characters)))
@@ -6762,15 +6946,15 @@ Use the \"perl\" command."
(skip-unless (tramp--test-sh-p))
(skip-unless (not (tramp--test-rsync-p)))
;; We cannot use `tramp-test-vec', because this fails during compilation.
- (with-parsed-tramp-file-name tramp-test-temporary-file-directory nil
+ (with-parsed-tramp-file-name ert-remote-temporary-file-directory nil
(skip-unless (tramp-get-remote-perl v)))
(let ((tramp-connection-properties
(append
- `((,(regexp-quote (file-remote-p tramp-test-temporary-file-directory))
+ `((,(regexp-quote (file-remote-p ert-remote-temporary-file-directory))
"stat" nil)
;; See `tramp-sh-handle-file-truename'.
- (,(regexp-quote (file-remote-p tramp-test-temporary-file-directory))
+ (,(regexp-quote (file-remote-p ert-remote-temporary-file-directory))
"readlink" nil))
tramp-connection-properties)))
(tramp--test-special-characters)))
@@ -6786,12 +6970,12 @@ Use the \"ls\" command."
(let ((tramp-connection-properties
(append
- `((,(regexp-quote (file-remote-p tramp-test-temporary-file-directory))
+ `((,(regexp-quote (file-remote-p ert-remote-temporary-file-directory))
"perl" nil)
- (,(regexp-quote (file-remote-p tramp-test-temporary-file-directory))
+ (,(regexp-quote (file-remote-p ert-remote-temporary-file-directory))
"stat" nil)
;; See `tramp-sh-handle-file-truename'.
- (,(regexp-quote (file-remote-p tramp-test-temporary-file-directory))
+ (,(regexp-quote (file-remote-p ert-remote-temporary-file-directory))
"readlink" nil))
tramp-connection-properties)))
(tramp--test-special-characters)))
@@ -6826,7 +7010,7 @@ Use the \"ls\" command."
;; Use all available language specific snippets.
(lambda (x)
(and
- (stringp (setq x (eval (get-language-info (car x) 'sample-text))))
+ (stringp (setq x (eval (get-language-info (car x) 'sample-text) t)))
;; Filter out strings which use unencodable characters.
(not (and (or (tramp--test-gvfs-p) (tramp--test-smb-p))
(unencodable-char-position
@@ -6853,7 +7037,7 @@ Use the \"ls\" command."
(skip-unless (not (tramp--test-ksh-p)))
(skip-unless (not (tramp--test-gdrive-p)))
(skip-unless (not (tramp--test-crypt-p)))
- (skip-unless (or (tramp--test-emacs26-p) (not (tramp--test-rclone-p))))
+ (skip-unless (not (tramp--test-rclone-p)))
(tramp--test-utf8))
@@ -6870,12 +7054,12 @@ Use the \"stat\" command."
(skip-unless (not (tramp--test-ksh-p)))
(skip-unless (not (tramp--test-crypt-p)))
;; We cannot use `tramp-test-vec', because this fails during compilation.
- (with-parsed-tramp-file-name tramp-test-temporary-file-directory nil
+ (with-parsed-tramp-file-name ert-remote-temporary-file-directory nil
(skip-unless (tramp-get-remote-stat v)))
(let ((tramp-connection-properties
(append
- `((,(regexp-quote (file-remote-p tramp-test-temporary-file-directory))
+ `((,(regexp-quote (file-remote-p ert-remote-temporary-file-directory))
"perl" nil))
tramp-connection-properties)))
(tramp--test-utf8)))
@@ -6893,15 +7077,15 @@ Use the \"perl\" command."
(skip-unless (not (tramp--test-ksh-p)))
(skip-unless (not (tramp--test-crypt-p)))
;; We cannot use `tramp-test-vec', because this fails during compilation.
- (with-parsed-tramp-file-name tramp-test-temporary-file-directory nil
+ (with-parsed-tramp-file-name ert-remote-temporary-file-directory nil
(skip-unless (tramp-get-remote-perl v)))
(let ((tramp-connection-properties
(append
- `((,(regexp-quote (file-remote-p tramp-test-temporary-file-directory))
+ `((,(regexp-quote (file-remote-p ert-remote-temporary-file-directory))
"stat" nil)
;; See `tramp-sh-handle-file-truename'.
- (,(regexp-quote (file-remote-p tramp-test-temporary-file-directory))
+ (,(regexp-quote (file-remote-p ert-remote-temporary-file-directory))
"readlink" nil))
tramp-connection-properties)))
(tramp--test-utf8)))
@@ -6921,12 +7105,12 @@ Use the \"ls\" command."
(let ((tramp-connection-properties
(append
- `((,(regexp-quote (file-remote-p tramp-test-temporary-file-directory))
+ `((,(regexp-quote (file-remote-p ert-remote-temporary-file-directory))
"perl" nil)
- (,(regexp-quote (file-remote-p tramp-test-temporary-file-directory))
+ (,(regexp-quote (file-remote-p ert-remote-temporary-file-directory))
"stat" nil)
;; See `tramp-sh-handle-file-truename'.
- (,(regexp-quote (file-remote-p tramp-test-temporary-file-directory))
+ (,(regexp-quote (file-remote-p ert-remote-temporary-file-directory))
"readlink" nil))
tramp-connection-properties)))
(tramp--test-utf8)))
@@ -6939,14 +7123,12 @@ Use the \"ls\" command."
;; `file-system-info' exists since Emacs 27.1. We don't want to see
;; compiler warnings for older Emacsen.
- (let ((fsi (with-no-warnings
- (file-system-info tramp-test-temporary-file-directory))))
- (skip-unless fsi)
- (should (and (consp fsi)
- (= (length fsi) 3)
- (numberp (nth 0 fsi))
- (numberp (nth 1 fsi))
- (numberp (nth 2 fsi))))))
+ (when-let ((fsi (with-no-warnings
+ (file-system-info ert-remote-temporary-file-directory))))
+ (should (consp fsi))
+ (should (= (length fsi) 3))
+ (dotimes (i (length fsi))
+ (should (natnump (or (nth i fsi) 0))))))
;; `tramp-test44-asynchronous-requests' could be blocked. So we set a
;; timeout of 300 seconds, and we send a SIGUSR1 signal after 300
@@ -6960,13 +7142,13 @@ The values are derived from PROC. Run BODY.
This is needed in timer functions as well as process filters and sentinels."
;; FIXME: For tramp-sshfs.el, `processp' does not work.
(declare (indent 1) (debug (processp body)))
- `(let* ((v (tramp-get-connection-property ,proc "vector" nil))
- (pname (tramp-get-connection-property v "process-name" nil))
- (pbuffer (tramp-get-connection-property v "process-buffer" nil)))
+ `(let* ((v (tramp-get-connection-property ,proc "vector"))
+ (pname (tramp-get-connection-property v "process-name"))
+ (pbuffer (tramp-get-connection-property v "process-buffer")))
(tramp--test-message
"tramp--test-with-proper-process-name-and-buffer before %s %s"
- (tramp-get-connection-property v "process-name" nil)
- (tramp-get-connection-property v "process-buffer" nil))
+ (tramp-get-connection-property v "process-name")
+ (tramp-get-connection-property v "process-buffer"))
(if (process-name ,proc)
(tramp-set-connection-property v "process-name" (process-name ,proc))
(tramp-flush-connection-property v "process-name"))
@@ -6976,8 +7158,8 @@ This is needed in timer functions as well as process filters and sentinels."
(tramp-flush-connection-property v "process-buffer"))
(tramp--test-message
"tramp--test-with-proper-process-name-and-buffer changed %s %s"
- (tramp-get-connection-property v "process-name" nil)
- (tramp-get-connection-property v "process-buffer" nil))
+ (tramp-get-connection-property v "process-name")
+ (tramp-get-connection-property v "process-buffer"))
(unwind-protect
(progn ,@body)
(if pname
@@ -7067,11 +7249,7 @@ process sentinels. They shall not disturb each other."
(when buffers
(let ((time (float-time))
(default-directory tmp-name)
- (file
- (buffer-name
- ;; Use `seq-random-elt' once <26.1 support
- ;; is dropped.
- (nth (random (length buffers)) buffers)))
+ (file (buffer-name (seq-random-elt buffers)))
;; A remote operation in a timer could
;; confuse Tramp heavily. So we ignore this
;; error here.
@@ -7136,8 +7314,7 @@ process sentinels. They shall not disturb each other."
;; the buffers. Mix with regular operation.
(let ((buffers (copy-sequence buffers)))
(while buffers
- ;; Use `seq-random-elt' once <26.1 support is dropped.
- (let* ((buf (nth (random (length buffers)) buffers))
+ (let* ((buf (seq-random-elt buffers))
(proc (get-buffer-process buf))
(file (process-get proc 'foo))
(count (process-get proc 'bar)))
@@ -7193,8 +7370,110 @@ process sentinels. They shall not disturb each other."
;; (tramp--test--deftest-direct-async-process tramp-test44-asynchronous-requests
;; "Check parallel direct asynchronous requests." 'unstable)
+(ert-deftest tramp-test45-dired-compress-file ()
+ "Check that Tramp (un)compresses normal files."
+ (skip-unless (tramp--test-enabled))
+ (skip-unless (tramp--test-sh-p))
+ (skip-unless (not (tramp--test-crypt-p)))
+ ;; Starting with Emacs 29.1, `dired-compress-file' is performed by
+ ;; default handler.
+ (skip-unless (not (tramp--test-emacs29-p)))
+
+ (let ((default-directory ert-remote-temporary-file-directory)
+ (tmp-name (tramp--test-make-temp-name)))
+ (write-region "foo" nil tmp-name)
+ (dired default-directory)
+ (dired-revert)
+ (dired-goto-file tmp-name)
+ (should-not (dired-compress))
+ (should (string= (concat tmp-name ".gz") (dired-get-filename)))
+ (should-not (dired-compress))
+ (should (string= tmp-name (dired-get-filename)))
+ (delete-file tmp-name)))
+
+(ert-deftest tramp-test45-dired-compress-dir ()
+ "Check that Tramp (un)compresses directories."
+ (skip-unless (tramp--test-enabled))
+ (skip-unless (tramp--test-sh-p))
+ (skip-unless (not (tramp--test-crypt-p)))
+ ;; Starting with Emacs 29.1, `dired-compress-file' is performed by
+ ;; default handler.
+ (skip-unless (not (tramp--test-emacs29-p)))
+
+ (let ((default-directory ert-remote-temporary-file-directory)
+ (tmp-name (tramp--test-make-temp-name)))
+ (make-directory tmp-name)
+ (dired default-directory)
+ (dired-revert)
+ (dired-goto-file tmp-name)
+ (should-not (dired-compress))
+ (should (string= (concat tmp-name ".tar.gz") (dired-get-filename)))
+ (should-not (dired-compress))
+ (should (string= tmp-name (dired-get-filename)))
+ (delete-directory tmp-name)
+ (delete-file (concat tmp-name ".tar.gz"))))
+
+(ert-deftest tramp-test46-read-password ()
+ "Check Tramp password handling."
+ :tags '(:expensive-test)
+ (skip-unless (tramp--test-enabled))
+ (skip-unless (tramp--test-mock-p))
+ ;; Not all read commands understand argument "-s" or "-p".
+ (skip-unless
+ (string-empty-p
+ (let ((shell-file-name "sh"))
+ (shell-command-to-string "read -s -p Password: pass"))))
+
+ (let ((pass "secret")
+ (mock-entry (copy-sequence (assoc "mock" tramp-methods)))
+ mocked-input tramp-methods)
+ ;; We must mock `read-string', in order to avoid interactive
+ ;; arguments.
+ (cl-letf* (((symbol-function #'read-string)
+ (lambda (&rest _args) (pop mocked-input))))
+ (setcdr
+ (assq 'tramp-login-args mock-entry)
+ `((("-c")
+ (,(tramp-shell-quote-argument
+ (concat
+ "read -s -p 'Password: ' pass; echo; "
+ "(test \"pass$pass\" != \"pass" pass "\" && "
+ "echo \"Login incorrect\" || sh -i)"))))))
+ (setq tramp-methods `(,mock-entry))
+
+ ;; Reading password from stdin works.
+ (tramp-cleanup-connection tramp-test-vec 'keep-debug)
+ ;; We don't want to invalidate the password.
+ (setq mocked-input `(,(copy-sequence pass)))
+ (should (file-exists-p ert-remote-temporary-file-directory))
+
+ ;; Don't entering a password returns in error.
+ (tramp-cleanup-connection tramp-test-vec 'keep-debug)
+ (setq mocked-input nil)
+ (should-error (file-exists-p ert-remote-temporary-file-directory))
+
+ ;; A wrong password doesn't work either.
+ (tramp-cleanup-connection tramp-test-vec 'keep-debug)
+ (setq mocked-input `(,(concat pass pass)))
+ (should-error (file-exists-p ert-remote-temporary-file-directory))
+
+ ;; Reading password from auth-source works. We use the netrc
+ ;; backend; the other backends shall behave similar.
+ ;; Macro `ert-with-temp-file' was introduced in Emacs 29.1.
+ (with-no-warnings (when (symbol-plist 'ert-with-temp-file)
+ (tramp-cleanup-connection tramp-test-vec 'keep-debug)
+ (setq mocked-input nil)
+ (auth-source-forget-all-cached)
+ (ert-with-temp-file netrc-file
+ :prefix "tramp-test" :suffix ""
+ :text (format
+ "machine %s port mock password %s"
+ (file-remote-p ert-remote-temporary-file-directory 'host) pass)
+ (let ((auth-sources `(,netrc-file)))
+ (should (file-exists-p ert-remote-temporary-file-directory)))))))))
+
;; This test is inspired by Bug#29163.
-(ert-deftest tramp-test45-auto-load ()
+(ert-deftest tramp-test47-auto-load ()
"Check that Tramp autoloads properly."
;; If we use another syntax but `default', Tramp is already loaded
;; due to the `tramp-change-syntax' call.
@@ -7207,7 +7486,7 @@ process sentinels. They shall not disturb each other."
;; Suppress method name check.
"(let ((non-essential t)) \
(message \"Tramp loaded: %%s\" (and (file-remote-p %S) t)))"
- tramp-test-temporary-file-directory)))
+ ert-remote-temporary-file-directory)))
(should
(string-match-p
"Tramp loaded: t[\n\r]+"
@@ -7219,12 +7498,8 @@ process sentinels. They shall not disturb each other."
(mapconcat #'shell-quote-argument load-path " -L ")
(shell-quote-argument code)))))))
-(ert-deftest tramp-test45-delay-load ()
+(ert-deftest tramp-test47-delay-load ()
"Check that Tramp is loaded lazily, only when needed."
- ;; The autoloaded Tramp objects are different since Emacs 26.1. We
- ;; cannot test older Emacsen, therefore.
- (skip-unless (tramp--test-emacs26-p))
-
;; Tramp is neither loaded at Emacs startup, nor when completing a
;; non-Tramp file name like "/foo". Completing a Tramp-alike file
;; name like "/foo:" autoloads Tramp, when `tramp-mode' is t.
@@ -7252,7 +7527,7 @@ process sentinels. They shall not disturb each other."
(mapconcat #'shell-quote-argument load-path " -L ")
(shell-quote-argument (format code tm)))))))))
-(ert-deftest tramp-test45-recursive-load ()
+(ert-deftest tramp-test47-recursive-load ()
"Check that Tramp does not fail due to recursive load."
(skip-unless (tramp--test-enabled))
@@ -7260,10 +7535,10 @@ process sentinels. They shall not disturb each other."
(dolist (code
(list
(format
- "(expand-file-name %S)" tramp-test-temporary-file-directory)
+ "(expand-file-name %S)" ert-remote-temporary-file-directory)
(format
"(let ((default-directory %S)) (expand-file-name %S))"
- tramp-test-temporary-file-directory
+ ert-remote-temporary-file-directory
temporary-file-directory)))
(should-not
(string-match-p
@@ -7276,12 +7551,8 @@ process sentinels. They shall not disturb each other."
(mapconcat #'shell-quote-argument load-path " -L ")
(shell-quote-argument code))))))))
-(ert-deftest tramp-test45-remote-load-path ()
+(ert-deftest tramp-test47-remote-load-path ()
"Check that Tramp autoloads its packages with remote `load-path'."
- ;; The autoloaded Tramp objects are different since Emacs 26.1. We
- ;; cannot test older Emacsen, therefore.
- (skip-unless (tramp--test-emacs26-p))
-
;; `tramp-cleanup-all-connections' is autoloaded from tramp-cmds.el.
;; It shall still work, when a remote file name is in the
;; `load-path'.
@@ -7305,14 +7576,10 @@ process sentinels. They shall not disturb each other."
(mapconcat #'shell-quote-argument load-path " -L ")
(shell-quote-argument code)))))))
-(ert-deftest tramp-test46-unload ()
+(ert-deftest tramp-test48-unload ()
"Check that Tramp and its subpackages unload completely.
Since it unloads Tramp, it shall be the last test to run."
:tags '(:expensive-test)
- ;; The autoloaded Tramp objects are different since Emacs 26.1. We
- ;; cannot test older Emacsen, therefore.
- (skip-unless (tramp--test-emacs26-p))
-
;; We have autoloaded objects from tramp.el and tramp-archive.el.
;; In order to remove them, we first need to load both packages.
(require 'tramp)
@@ -7396,8 +7663,7 @@ If INTERACTIVE is non-nil, the tests are run interactively."
;; TODO:
-;; * dired-compress-file
-;; * dired-uncache
+;; * dired-uncache (partly done in other test functions)
;; * file-equal-p (partly done in `tramp-test21-file-links')
;; * file-in-directory-p
;; * file-name-case-insensitive-p
@@ -7408,8 +7674,9 @@ If INTERACTIVE is non-nil, the tests are run interactively."
;; * Work on skipped tests. Make a comment, when it is impossible.
;; * Revisit expensive tests, once problems in `tramp-error' are solved.
;; * Fix `tramp-test06-directory-file-name' for "ftp".
-;; * Implement `tramp-test31-interrupt-process' for "adb", "sshfs" and
-;; for direct async processes.
+;; * Implement `tramp-test31-interrupt-process' and
+;; `tramp-test31-signal-process' for "adb", "sshfs" and for direct
+;; async processes. Check, why they don't run stable.
;; * Check, why direct async processes do not work for
;; `tramp-test44-asynchronous-requests'.
diff --git a/test/lisp/obsolete/cl-tests.el b/test/lisp/obsolete/cl-tests.el
index 14205c83a38..5a701a1e550 100644
--- a/test/lisp/obsolete/cl-tests.el
+++ b/test/lisp/obsolete/cl-tests.el
@@ -25,12 +25,11 @@
(require 'cl))
(require 'ert)
-
-
(ert-deftest labels-function-quoting ()
"Test that #'foo does the right thing in `labels'." ; Bug#31792.
- (should (eq (funcall (labels ((foo () t))
- #'foo))
- t)))
+ (with-suppressed-warnings ((obsolete labels))
+ (should (eq (funcall (labels ((foo () t))
+ #'foo))
+ t))))
;;; cl-tests.el ends here
diff --git a/test/lisp/obsolete/inversion-tests.el b/test/lisp/obsolete/inversion-tests.el
index 7c8815c2822..8af91d7d147 100644
--- a/test/lisp/obsolete/inversion-tests.el
+++ b/test/lisp/obsolete/inversion-tests.el
@@ -30,7 +30,6 @@
(ert-deftest inversion-unit-test ()
"Test inversion to make sure it can identify different version strings."
- (interactive)
(let ((c1 (inversion-package-version 'inversion))
(c1i (inversion-package-incompatibility-version 'inversion))
(c2 (inversion-decode-version "1.3alpha2"))
diff --git a/test/lisp/paren-tests.el b/test/lisp/paren-tests.el
index f7d8658e875..baf5590cb94 100644
--- a/test/lisp/paren-tests.el
+++ b/test/lisp/paren-tests.el
@@ -117,5 +117,36 @@
(- (point-max) 1) (point-max)
nil)))))
+(ert-deftest paren-tests-open-paren-line ()
+ (cl-flet ((open-paren-line ()
+ (let* ((data (show-paren--default))
+ (here-beg (nth 0 data))
+ (there-beg (nth 2 data)))
+ (blink-paren-open-paren-line-string
+ (min here-beg there-beg)))))
+ ;; Lisp-like
+ (with-temp-buffer
+ (insert "(defun foo ()
+ (dummy))")
+ (goto-char (point-max))
+ (should (string= "(defun foo ()" (open-paren-line))))
+
+ ;; C-like
+ (with-temp-buffer
+ (insert "int foo() {
+ int blah;
+ }")
+ (goto-char (point-max))
+ (should (string= "int foo() {" (open-paren-line))))
+
+ ;; C-like with hanging {
+ (with-temp-buffer
+ (insert "int foo()
+ {
+ int blah;
+ }")
+ (goto-char (point-max))
+ (should (string= "int foo()...{" (open-paren-line))))))
+
(provide 'paren-tests)
;;; paren-tests.el ends here
diff --git a/test/lisp/progmodes/autoconf-tests.el b/test/lisp/progmodes/autoconf-tests.el
index e383b4bb6c4..7c609f3c2a7 100644
--- a/test/lisp/progmodes/autoconf-tests.el
+++ b/test/lisp/progmodes/autoconf-tests.el
@@ -31,18 +31,18 @@
(ert-deftest autoconf-tests-current-defun-function-define ()
(with-temp-buffer
- (insert "AC_DEFINE(HAVE_RSVG, 1, [Define to 1 if using librsvg.])")
+ (insert "AC_DEFINE([HAVE_RSVG], [1], [Define to 1 if using librsvg.])")
(goto-char (point-min))
(should-not (autoconf-current-defun-function))
- (forward-char 10)
+ (forward-char 11)
(should (equal (autoconf-current-defun-function) "HAVE_RSVG"))))
(ert-deftest autoconf-tests-current-defun-function-subst ()
(with-temp-buffer
- (insert "AC_SUBST(srcdir)")
+ (insert "AC_SUBST([srcdir])")
(goto-char (point-min))
(should-not (autoconf-current-defun-function))
- (forward-char 9)
+ (forward-char 10)
(should (equal (autoconf-current-defun-function) "srcdir"))))
(ert-deftest autoconf-tests-autoconf-mode-comment-syntax ()
diff --git a/test/lisp/progmodes/bug-reference-tests.el b/test/lisp/progmodes/bug-reference-tests.el
new file mode 100644
index 00000000000..fa06d7a1cd0
--- /dev/null
+++ b/test/lisp/progmodes/bug-reference-tests.el
@@ -0,0 +1,128 @@
+;;; bug-reference-tests.el --- Tests for bug-reference.el -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021-2022 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'bug-reference)
+(require 'ert)
+
+(defun test--get-github-entry (url)
+ (and (string-match
+ (car (bug-reference--build-forge-setup-entry
+ "github.com" 'github "https"))
+ url)
+ (match-string 1 url)))
+
+(defun test--get-gitlab-entry (url)
+ (and (string-match
+ (car (bug-reference--build-forge-setup-entry
+ "gitlab.com" 'gitlab "https"))
+ url)
+ (match-string 1 url)))
+
+(defun test--get-gitea-entry (url)
+ (and (string-match
+ (car (bug-reference--build-forge-setup-entry
+ "gitea.com" 'gitea "https"))
+ url)
+ (match-string 1 url)))
+
+(ert-deftest test-github-entry ()
+ (should
+ (equal
+ (test--get-github-entry "git@github.com:larsmagne/csid.git")
+ "larsmagne/csid"))
+ (should
+ (equal
+ (test--get-github-entry "git@github.com:larsmagne/csid")
+ "larsmagne/csid"))
+ (should
+ (equal
+ (test--get-github-entry "https://github.com/magit/magit.git")
+ "magit/magit"))
+ (should
+ (equal
+ (test--get-github-entry "https://github.com/magit/magit.git/")
+ "magit/magit"))
+ (should
+ (equal
+ (test--get-github-entry "https://github.com/magit/magit")
+ "magit/magit"))
+ (should
+ (equal
+ (test--get-github-entry "https://github.com/magit/magit/")
+ "magit/magit")))
+
+(ert-deftest test-gitlab-entry ()
+ (should
+ (equal
+ (test--get-gitlab-entry "git@gitlab.com:larsmagne/csid.git")
+ "larsmagne/csid"))
+ (should
+ (equal
+ (test--get-gitlab-entry "git@gitlab.com:larsmagne/csid")
+ "larsmagne/csid"))
+ (should
+ (equal
+ (test--get-gitlab-entry "https://gitlab.com/magit/magit.git")
+ "magit/magit"))
+ (should
+ (equal
+ (test--get-gitlab-entry "https://gitlab.com/magit/magit.git/")
+ "magit/magit"))
+ (should
+ (equal
+ (test--get-gitlab-entry "https://gitlab.com/magit/magit")
+ "magit/magit"))
+ (should
+ (equal
+ (test--get-gitlab-entry "https://gitlab.com/magit/magit/")
+ "magit/magit")))
+
+(ert-deftest test-gitea-entry ()
+ (should
+ (equal
+ (test--get-gitea-entry "git@gitea.com:larsmagne/csid.git")
+ "larsmagne/csid"))
+ (should
+ (equal
+ (test--get-gitea-entry "git@gitea.com:larsmagne/csid")
+ "larsmagne/csid"))
+ (should
+ (equal
+ (test--get-gitea-entry "https://gitea.com/magit/magit.git")
+ "magit/magit"))
+ (should
+ (equal
+ (test--get-gitea-entry "https://gitea.com/magit/magit.git/")
+ "magit/magit"))
+ (should
+ (equal
+ (test--get-gitea-entry "https://gitea.com/magit/magit")
+ "magit/magit"))
+ (should
+ (equal
+ (test--get-gitea-entry "https://gitea.com/magit/magit/")
+ "magit/magit")))
+
+;;; bug-reference-tests.el ends here
diff --git a/test/lisp/progmodes/compile-tests.el b/test/lisp/progmodes/compile-tests.el
index 7af4ff33716..36bdbe4c91b 100644
--- a/test/lisp/progmodes/compile-tests.el
+++ b/test/lisp/progmodes/compile-tests.el
@@ -230,6 +230,7 @@
(gnu "foo.c:8:23:information: message" 1 23 8 "foo.c")
(gnu "foo.c:8.23-45: Informational: message" 1 (23 . 45) (8 . nil) "foo.c")
(gnu "foo.c:8-23: message" 1 nil (8 . 23) "foo.c")
+ (gnu " |foo.c:8: message" 1 nil 8 "foo.c")
;; The next one is not in the GNU standards AFAICS.
;; Here we seem to interpret it as LINE1-LINE2.COL2.
(gnu "foo.c:8-45.3: message" 1 (nil . 3) (8 . 45) "foo.c")
@@ -259,6 +260,9 @@
"e: e:\\src\\Test.kt: (34, 15): foo: bar" 4 15 34 "e:\\src\\Test.kt" 2)
(gradle-kotlin
"w: e:\\src\\Test.kt: (11, 98): foo: bar" 4 98 11 "e:\\src\\Test.kt" 1)
+ (gradle-android
+ " ERROR:/Users/salutis/src/AndroidSchemeExperiment/app/build/intermediates/incremental/debug/mergeDebugResources/stripped.dir/layout/item.xml:3: AAPT: error: '16dpw' is incompatible with attribute padding (attr) dimension."
+ 1 nil 3 "/Users/salutis/src/AndroidSchemeExperiment/app/build/intermediates/incremental/debug/mergeDebugResources/stripped.dir/layout/item.xml" 2)
;; Guile
(guile-file "In foo.scm:\n" 1 nil nil "foo.scm")
(guile-line " 63:4 [call-with-prompt prompt0 ...]" 1 4 63 nil)
@@ -491,7 +495,7 @@ The test data is in `compile-tests--test-regexps-data'."
(compilation-num-warnings-found 0)
(compilation-num-infos-found 0))
(mapc #'compile--test-error-line compile-tests--test-regexps-data)
- (should (eq compilation-num-errors-found 96))
+ (should (eq compilation-num-errors-found 98))
(should (eq compilation-num-warnings-found 35))
(should (eq compilation-num-infos-found 28)))))
diff --git a/test/lisp/progmodes/cperl-mode-resources/proto-and-attrs.pl b/test/lisp/progmodes/cperl-mode-resources/proto-and-attrs.pl
new file mode 100644
index 00000000000..7138bf631df
--- /dev/null
+++ b/test/lisp/progmodes/cperl-mode-resources/proto-and-attrs.pl
@@ -0,0 +1,50 @@
+# The next two lines are required as of 2022, but obsolescent
+# as soon as signatures leave their "experimental" state
+use feature 'signatures';
+no warnings 'experimental::signatures';
+
+# Tests for subroutine prototypes, signatures and the like
+
+# Prototypes have syntactical properties different from "normal" Perl:
+# Perl has a variable $), so ($)) is not an unbalanced parenthesis.
+# On the other hand, in a prototype ($) is _not_ an open paren
+# followed by the variable $), so the parens are balanced. Prototypes
+# are somewhat frowned upon most of the times, but they are required
+# for some Perl magic
+
+# FIXME: 2022-02-02 CPerl mode does not handle subroutine signatures.
+# In simple cases it mistakes them as prototypes, when attributes are
+# present, it doesn't handle them at all. Variables in signatures
+# SHOULD be fontified like variable declarations.
+
+# Part 1: Named subroutines
+# A prototype and a trivial subroutine attribute
+{
+ no feature 'signatures'; # that's a prototype, not a signature
+ sub sub_1 ($) :lvalue { local $); }
+}
+
+# A prototype as an attribute (how it should be written these days)
+sub sub_2 :prototype($) { ...; }
+
+# A signature (these will soon-ish leave the experimental state)
+sub sub_3 ($foo,$bar) { ...; }
+
+# Attribute plus signature FIXME: Not yet supported
+sub bad_sub_4 :prototype($$$) ($foo,$bar,$baz) { ...; }
+
+# Part 2: Same constructs for anonymous subs
+# A prototype and a trivial subroutine attribute
+{
+ no feature 'signatures'; # that's a prototype, not a signature
+ my $subref_1 = sub ($) :lvalue { local $); };
+}
+
+# A prototype as an attribute (how it should be written these days)
+my $subref_2 = sub :prototype($) { ...; };
+
+# A signature (these will soon-ish leave the experimental state)
+my $subref_3 = sub ($foo,$bar) { ...; };
+
+# Attribute plus signature
+my $subref_4 = sub :prototype($$$) ($foo,$bar,$baz) { ...; };
diff --git a/test/lisp/progmodes/cperl-mode-tests.el b/test/lisp/progmodes/cperl-mode-tests.el
index 0124dad6f17..7eb2d9be756 100644
--- a/test/lisp/progmodes/cperl-mode-tests.el
+++ b/test/lisp/progmodes/cperl-mode-tests.el
@@ -5,7 +5,7 @@
;; Author: Harald Jörg <haj@posteo.de>
;; Maintainer: Harald Jörg
;; Keywords: internal
-;; Homepage: https://github.com/HaraldJoerg/cperl-mode
+;; URL: https://github.com/HaraldJoerg/cperl-mode
;; This file is part of GNU Emacs.
@@ -64,7 +64,7 @@ The expected output from running BODY on the input goes here.
# -------- NAME: end --------
You can have many of these blocks in one test file. You can
-chose a NAME for each block, which is passed to the 'should'
+chose a NAME for each block, which is passed to the `should'
clause for easy identification of the first test case that
failed (if any). Text outside these the blocks is ignored by the
tests, so you can use it to document the test cases if you wish."
@@ -154,6 +154,55 @@ point in the distant past, and is still broken in perl-mode. "
(should (equal (get-text-property (match-beginning 0) 'face)
'font-lock-keyword-face))))
+(ert-deftest cperl-test-fontify-attrs-and-signatures ()
+ "Test fontification of the various combinations of subroutine
+attributes, prototypes and signatures."
+ (skip-unless (eq cperl-test-mode #'cperl-mode))
+ (let ((file (ert-resource-file "proto-and-attrs.pl")))
+ (with-temp-buffer
+ (insert-file-contents file)
+ (goto-char (point-min))
+ (funcall cperl-test-mode)
+ (font-lock-ensure)
+
+ ;; Named subroutines
+ (while (search-forward-regexp "\\_<sub_[[:digit:]]+" nil t)
+ (should (equal (get-text-property (match-beginning 0) 'face)
+ 'font-lock-function-name-face))
+ (let ((start-of-sub (match-beginning 0))
+ (end-of-sub (save-excursion (search-forward "}") (point))))
+
+ ;; Prototypes are shown as strings
+ (when (search-forward-regexp " ([$%@*]*) " end-of-sub t)
+ (should (equal (get-text-property (1+ (match-beginning 0)) 'face)
+ 'font-lock-string-face)))
+ (goto-char start-of-sub)
+ (when (search-forward-regexp "\\(:[a-z]+\\)\\((.*?)\\)?" end-of-sub t)
+ (should (equal (get-text-property (match-beginning 1) 'face)
+ 'font-lock-constant-face))
+ (when (match-beginning 2)
+ (should (equal (get-text-property (match-beginning 2) 'face)
+ 'font-lock-string-face))))
+ (goto-char end-of-sub)))
+
+ ;; Anonymous subroutines
+ (while (search-forward-regexp "= sub" nil t)
+ (let ((start-of-sub (match-beginning 0))
+ (end-of-sub (save-excursion (search-forward "}") (point))))
+
+ ;; Prototypes are shown as strings
+ (when (search-forward-regexp " ([$%@*]*) " end-of-sub t)
+ (should (equal (get-text-property (1+ (match-beginning 0)) 'face)
+ 'font-lock-string-face)))
+ (goto-char start-of-sub)
+ (when (search-forward-regexp "\\(:[a-z]+\\)\\((.*?)\\)?" end-of-sub t)
+ (should (equal (get-text-property (match-beginning 1) 'face)
+ 'font-lock-constant-face))
+ (when (match-beginning 2)
+ (should (equal (get-text-property (match-beginning 2) 'face)
+ 'font-lock-string-face))))
+ (goto-char end-of-sub))))))
+
(ert-deftest cperl-test-fontify-special-variables ()
"Test fontification of variables like $^T or ${^ENCODING}.
These can occur as \"local\" aliases."
@@ -698,7 +747,6 @@ without a statement terminator on the same line does not loop
forever. The test starts an asynchronous Emacs batch process
under timeout control."
:tags '(:expensive-test)
- (interactive)
(skip-unless (not (getenv "EMACS_HYDRA_CI"))) ; FIXME times out
(skip-unless (not (< emacs-major-version 28))) ; times out in older Emacsen
(skip-unless (eq cperl-test-mode #'cperl-mode))
diff --git a/test/lisp/progmodes/elisp-mode-resources/elisp-indents.erts b/test/lisp/progmodes/elisp-mode-resources/elisp-indents.erts
new file mode 100644
index 00000000000..2c0d51edae8
--- /dev/null
+++ b/test/lisp/progmodes/elisp-mode-resources/elisp-indents.erts
@@ -0,0 +1,88 @@
+Code:
+ (lambda ()
+ (emacs-lisp-mode)
+ (indent-region (point-min) (point-max)))
+
+Name: defun
+
+=-=
+(defun foo ()
+"doc"
+(+ 1 2))
+=-=
+(defun foo ()
+ "doc"
+ (+ 1 2))
+=-=-=
+
+Name: function call
+
+=-=
+(foo zot
+bar
+(zot bar))
+=-=
+(foo zot
+ bar
+ (zot bar))
+=-=-=
+
+Name: lisp data
+
+=-=
+( foo zot
+bar
+(zot bar))
+=-=
+( foo zot
+ bar
+ (zot bar))
+=-=-=
+
+Name: defun-space
+
+=-=
+(defun x ()
+ (print (quote ( thingy great
+ stuff)))
+ (print (quote (thingy great
+ stuff))))
+=-=-=
+
+Name: defvar-keymap
+
+=-=
+(defvar-keymap eww-link-keymap
+ :copy shr-map
+ :foo bar
+ "\r" #'eww-follow-link)
+=-=-=
+
+Name: def-indent1
+
+=-=
+(defzot-does-not-exist 1
+ 2 3)
+=-=-=
+
+Name: def-indent2
+
+=-=
+(define-keymap 1
+ 2 3)
+=-=-=
+
+Name: elisp-indents1
+
+=-=
+(defvar foo
+ ()
+ "bar")
+=-=-=
+
+Name: elisp-indents2
+
+=-=
+(defvar foo ()
+ "bar")
+=-=-=
diff --git a/test/lisp/progmodes/elisp-mode-resources/flet.erts b/test/lisp/progmodes/elisp-mode-resources/flet.erts
new file mode 100644
index 00000000000..da3dcb6ec3e
--- /dev/null
+++ b/test/lisp/progmodes/elisp-mode-resources/flet.erts
@@ -0,0 +1,353 @@
+Name: flet1
+
+=-=
+(cl-flet ()
+ (a (dangerous-position
+ b)))
+=-=-=
+
+Name: flet2
+
+=-=
+(cl-flet wrong-syntax-but-should-not-obstruct-indentation
+ (a (dangerous-position
+ b)))
+=-=-=
+
+Name: flet3
+
+=-=
+(cl-flet ((a (arg-of-flet-a)
+ b
+ c)))
+=-=-=
+
+Name: flet4
+
+=-=
+(cl-flet ((a (arg-of-flet-a)
+ b
+ c
+ (if d
+ e
+ f))
+ (irregular-local-def (form
+ returning
+ lambda))
+ (g (arg-of--flet-g)
+ h
+ i))
+ (let ((j k))
+ (if dangerous-position
+ l
+ m)))
+=-=-=
+
+Name: flet5
+
+=-=
+(cl-flet ((a (arg-of-flet-a)
+ b
+ c
+ (if d
+ e
+ f))
+ (irregular-local-def (form
+ returning
+ lambda))
+ (g (arg-of--flet-g)
+ h
+ i))
+ (let ((j k))
+ (if dangerous-position
+ l
+ m)))
+=-=-=
+
+Name: flet6
+
+=-=
+(cl-flet ((a (arg-of-flet-a)
+ b
+ c
+ (if d
+ e
+ f))
+ (irregular-local-def (form
+ returning
+ lambda))
+ (irregular-local-def (form returning
+ lambda))
+ wrong-syntax-but-should-not-osbtruct-indentation
+ (g (arg-of--flet-g)
+ h
+ i))
+ (let ((j k))
+ (if dangerous-position
+ l
+ m)))
+=-=-=
+
+Name: flet7
+
+=-=
+(cl-flet ((a (arg-of-flet-a)
+ b
+ c
+ (if d
+ e
+ f))
+ (irregular-local-def (form
+ returning
+ lambda))
+ wrong-syntax-but-should-not-osbtruct-indentation
+ (g (arg-of--flet-g)
+ h
+ i))
+ (let ((j k))
+ (if dangerous-position
+ l
+ m)))
+=-=-=
+
+Name: flet8
+
+=-=
+(cl-flet (wrong-syntax-but-should-not-obstruct-indentation
+ (g (arg-of--flet-g)
+ h
+ i))
+ (let ((j k))
+ (if dangerous-position
+ l
+ m)))
+=-=-=
+
+;; (setf _) not yet supported but looks like it will be
+Name: flet9
+
+=-=
+(cl-flet (((setf a) (new value)
+ stuff)
+ wrong-syntax-but-should-not-obstruct-indentation
+ (g (arg-of--flet-g)
+ h
+ i))
+ (let ((j k))
+ (if dangerous-position
+ l
+ m)))
+=-=-=
+
+Name: flet10
+
+=-=
+(cl-flet ( (a (arg-of-flet-a)
+ b
+ c
+ (if d
+ e
+ f))
+ (irregular-local-def (form
+ returning
+ lambda))
+ (g (arg-of--flet-g)
+ h
+ i))
+ (let ((j k))
+ (if dangerous-position
+ l
+ m)))
+=-=-=
+
+Name: flet11
+
+=-=
+(cl-flet ( wrong-syntax-but-should-not-obstruct-indentation
+ (g (arg-of--flet-g)
+ h
+ i))
+ (let ((j k))
+ (if dangerous-position
+ l
+ m)))
+=-=-=
+
+Name: flet12
+
+=-=
+(cl-flet ( wrong-syntax-but-should-not-obstruct-indentation
+ (g (arg-of--flet-g)
+ h
+ i))
+ (let ((j k))
+ (if dangerous-position
+ l
+ m)))
+=-=-=
+
+Name: flet13
+
+=-=
+(cl-flet (wrong-syntax-but-should-not-obstruct-indentation
+ (g (arg-of--flet-g)
+ h
+ i)
+ wrong-syntax-but-should-not-obstruct-indentation
+ (g (arg-of--flet-g)
+ h
+ i)))
+=-=-=
+
+Name: flet14
+
+=-=
+(cl-flet (wrong-syntax-but-should-not-obstruct-indentation
+ wrong-syntax-but-should-not-obstruct-indentation
+ (g (arg-of--flet-g)
+ h
+ i)
+ wrong-syntax-but-should-not-obstruct-indentation))
+=-=-=
+
+Name: flet15
+
+=-=
+(cl-flet (wrong-syntax-but-should-not-obstruct-indentation
+ wrong-syntax-but-should-not-obstruct-indentation
+ wrong-syntax-but-should-not-obstruct-indentation
+ (g (arg-of--flet-g)
+ h
+ i)))
+=-=-=
+
+Name: flet16
+
+=-=
+(cl-flet ((f (x)
+ (g x)))
+ (pcase e
+ ((dangerous-expression)
+ (form))))
+=-=-=
+
+Name: flet-indentation-incomplete-sexp-no-side-effects-1
+Code: (lambda () (emacs-lisp-mode) (setq indent-tabs-mode nil) (newline nil t))
+Point-Char: |
+
+=-=
+(let ((x (and y|
+=-=
+(let ((x (and y
+ |
+=-=-=
+
+Name: flet-indentation-incomplete-sexp-no-side-effects-2
+
+=-=
+(let ((x|
+=-=
+(let ((x
+ |
+=-=-=
+
+Name: flet-indentation-incomplete-sexp-missing-whitespace-1
+Point-Char: |
+
+=-=
+(cl-flet((f (x)|
+=-=
+(cl-flet((f (x)
+ |
+=-=-=
+
+Name: flet-indentation-incomplete-sexp-missing-whitespace-2
+Point-Char: |
+
+=-=
+(cl-flet((f(x)|
+=-=
+(cl-flet((f(x)
+ |
+=-=-=
+
+Name: flet-indentation-incomplete-sexp-missing-whitespace-3
+
+=-=
+(cl-flet ((f(x)|
+=-=
+(cl-flet ((f(x)
+ |
+=-=-=
+
+Name: flet-indentation-incomplete-sexp-missing-whitespace-4
+
+=-=
+(cl-flet( (f (x)|
+=-=
+(cl-flet( (f (x)
+ |
+=-=-=
+
+Name: flet-indentation-incomplete-sexp-missing-whitespace-5
+
+=-=
+(cl-flet( (f(x)|
+=-=
+(cl-flet( (f(x)
+ |
+=-=-=
+
+Name: flet-indentation-incomplete-sexp-missing-and-excessive-whitespace-1
+
+=-=
+(cl-flet((f (x)|
+=-=
+(cl-flet((f (x)
+ |
+=-=-=
+
+Name: flet-indentation-incomplete-sexp-missing-and-excessive-whitespace-2
+
+=-=
+(cl-flet ((f(x)|
+=-=
+(cl-flet ((f(x)
+ |
+=-=-=
+
+Name: flet-indentation-incomplete-sexp-missing-and-excessive-whitespace-3
+
+=-=
+(cl-flet( (f (x)|
+=-=
+(cl-flet( (f (x)
+ |
+=-=-=
+
+Name: flet-indentation-incomplete-sexp-missing-and-excessive-whitespace-4
+
+=-=
+(cl-flet( (f (x)|
+=-=
+(cl-flet( (f (x)
+ |
+=-=-=
+
+Name: flet-indentation-incomplete-sexp-missing-and-excessive-whitespace-5
+
+=-=
+(cl-flet( (f (x)|
+=-=
+(cl-flet( (f (x)
+ |
+=-=-=
+
+Name: flet-indentation-incomplete-sexp-missing-and-excessive-whitespace-6
+
+=-=
+(cl-flet( (f(x)|
+=-=
+(cl-flet( (f(x)
+ |
+=-=-=
diff --git a/test/lisp/progmodes/elisp-mode-resources/simple-shorthand-test.el b/test/lisp/progmodes/elisp-mode-resources/simple-shorthand-test.el
index 14c8e845d11..9b41fb5426c 100644
--- a/test/lisp/progmodes/elisp-mode-resources/simple-shorthand-test.el
+++ b/test/lisp/progmodes/elisp-mode-resources/simple-shorthand-test.el
@@ -1,3 +1,5 @@
+;;; simple-shorthand-test.el --- -*- lexical-binding: t; -*-
+
(defun f-test ()
(let ((read-symbol-shorthands '(("foo-" . "bar-"))))
(with-temp-buffer
diff --git a/test/lisp/progmodes/elisp-mode-tests.el b/test/lisp/progmodes/elisp-mode-tests.el
index d2230583066..8e4dfa8bb83 100644
--- a/test/lisp/progmodes/elisp-mode-tests.el
+++ b/test/lisp/progmodes/elisp-mode-tests.el
@@ -26,6 +26,7 @@
(require 'ert-x)
(require 'xref)
(eval-when-compile (require 'cl-lib))
+(require 'ert-x)
;;; Completion
@@ -108,7 +109,7 @@
(should (member "backup-inhibited" comps))
(should-not (member "backup-buffer" comps))))))
-(ert-deftest elisp-completes-functions-after-let-bindings ()
+(ert-deftest elisp-completes-functions-after-let-bindings-2 ()
(with-temp-buffer
(emacs-lisp-mode)
(insert "(let ((bar 1) (baz 2)) (ba")
@@ -301,12 +302,9 @@
;; tmp may be on a different filesystem to the tests, but, ehh.
(defvar xref--case-insensitive
- (let ((dir (make-temp-file "xref-test" t)))
- (unwind-protect
- (progn
- (with-temp-file (expand-file-name "hElLo" dir) "hello")
- (file-exists-p (expand-file-name "HELLO" dir)))
- (delete-directory dir t)))
+ (ert-with-temp-directory dir
+ (with-temp-file (expand-file-name "hElLo" dir) "hello")
+ (file-exists-p (expand-file-name "HELLO" dir)))
"Non-nil if file system seems to be case-insensitive.")
(defun xref-elisp-test-run (xrefs expected-xrefs)
@@ -440,7 +438,8 @@ to (xref-elisp-test-descr-to-target xref)."
;; track down the problem.
(cl-defmethod xref-elisp-generic-no-default ((this xref-elisp-root-type) arg2)
"Doc string generic no-default xref-elisp-root-type."
- "non-default for no-default")
+ "non-default for no-default"
+ (list this arg2)) ; silence byte-compiler
;; defgeneric after defmethod in file to ensure the fallback search
;; method of just looking for the function name will fail.
@@ -450,13 +449,15 @@ to (xref-elisp-test-descr-to-target xref)."
;; dispatching code.
)
-(cl-defgeneric xref-elisp-generic-co-located-default (arg1 arg2)
- "Doc string generic co-located-default."
- "co-located default")
+(with-no-warnings ; FIXME: Make more specific.
+ (cl-defgeneric xref-elisp-generic-co-located-default (arg1 arg2)
+ "Doc string generic co-located-default."
+ "co-located default"))
-(cl-defmethod xref-elisp-generic-co-located-default ((this xref-elisp-root-type) arg2)
- "Doc string generic co-located-default xref-elisp-root-type."
- "non-default for co-located-default")
+(with-no-warnings ; FIXME: Make more specific.
+ (cl-defmethod xref-elisp-generic-co-located-default ((this xref-elisp-root-type) arg2)
+ "Doc string generic co-located-default xref-elisp-root-type."
+ "non-default for co-located-default"))
(cl-defgeneric xref-elisp-generic-separate-default (arg1 arg2)
"Doc string generic separate-default."
@@ -465,19 +466,23 @@ to (xref-elisp-test-descr-to-target xref)."
(cl-defmethod xref-elisp-generic-separate-default (arg1 arg2)
"Doc string generic separate-default default."
- "separate default")
+ "separate default"
+ (list arg1 arg2)) ; silence byte-compiler
(cl-defmethod xref-elisp-generic-separate-default ((this xref-elisp-root-type) arg2)
"Doc string generic separate-default xref-elisp-root-type."
- "non-default for separate-default")
+ "non-default for separate-default"
+ (list this arg2)) ; silence byte-compiler
(cl-defmethod xref-elisp-generic-implicit-generic (arg1 arg2)
"Doc string generic implicit-generic default."
- "default for implicit generic")
+ "default for implicit generic"
+ (list arg1 arg2)) ; silence byte-compiler
(cl-defmethod xref-elisp-generic-implicit-generic ((this xref-elisp-root-type) arg2)
"Doc string generic implicit-generic xref-elisp-root-type."
- "non-default for implicit generic")
+ "non-default for implicit generic"
+ (list this arg2)) ; silence byte-compiler
(xref-elisp-deftest find-defs-defgeneric-no-methods
@@ -612,7 +617,7 @@ to (xref-elisp-test-descr-to-target xref)."
))
(xref-elisp-deftest find-defs-defgeneric-eval
- (elisp--xref-find-definitions (eval '(cl-defgeneric stephe-leake-cl-defgeneric ())))
+ (elisp--xref-find-definitions (eval '(cl-defgeneric stephe-leake-cl-defgeneric ()) t))
nil)
;; Define some mode-local overloadable/overridden functions for xref to find
@@ -714,7 +719,7 @@ to (xref-elisp-test-descr-to-target xref)."
(expand-file-name "../../../lisp/progmodes/xref.el" emacs-test-dir)))))
(xref-elisp-deftest find-defs-defun-eval
- (elisp--xref-find-definitions (eval '(defun stephe-leake-defun ())))
+ (elisp--xref-find-definitions (eval '(defun stephe-leake-defun ()) t))
nil)
(xref-elisp-deftest find-defs-defun-c
@@ -781,11 +786,11 @@ to (xref-elisp-test-descr-to-target xref)."
))
(xref-elisp-deftest find-defs-defvar-el
- (elisp--xref-find-definitions 'xref--marker-ring)
+ (elisp--xref-find-definitions 'xref--history)
(list
- (xref-make "(defvar xref--marker-ring)"
+ (xref-make "(defvar xref--history)"
(xref-make-elisp-location
- 'xref--marker-ring 'defvar
+ 'xref--history 'defvar
(expand-file-name "../../../lisp/progmodes/xref.el" emacs-test-dir)))
))
@@ -799,7 +804,7 @@ to (xref-elisp-test-descr-to-target xref)."
"DEFVAR_PER_BUFFER (\"default-directory\"")))
(xref-elisp-deftest find-defs-defvar-eval
- (elisp--xref-find-definitions (eval '(defvar stephe-leake-defvar nil)))
+ (elisp--xref-find-definitions (eval '(defvar stephe-leake-defvar nil) t))
nil)
(xref-elisp-deftest find-defs-face-el
@@ -817,7 +822,7 @@ to (xref-elisp-test-descr-to-target xref)."
))
(xref-elisp-deftest find-defs-face-eval
- (elisp--xref-find-definitions (eval '(defface stephe-leake-defface nil "")))
+ (elisp--xref-find-definitions (eval '(defface stephe-leake-defface nil "") t))
nil)
(xref-elisp-deftest find-defs-feature-el
@@ -832,7 +837,7 @@ to (xref-elisp-test-descr-to-target xref)."
))
(xref-elisp-deftest find-defs-feature-eval
- (elisp--xref-find-definitions (eval '(provide 'stephe-leake-feature)))
+ (elisp--xref-find-definitions (eval '(provide 'stephe-leake-feature) t))
nil)
(ert-deftest elisp--preceding-sexp--char-name ()
@@ -841,25 +846,14 @@ to (xref-elisp-test-descr-to-target xref)."
(insert "?\\N{HEAVY CHECK MARK}")
(should (equal (elisp--preceding-sexp) ?\N{HEAVY CHECK MARK}))))
-(ert-deftest elisp-indent-basic ()
- (with-temp-buffer
- (emacs-lisp-mode)
- (let ((orig "(defun x ()
- (print (quote ( thingy great
- stuff)))
- (print (quote (thingy great
- stuff))))"))
- (insert orig)
- (indent-region (point-min) (point-max))
- (should (equal (buffer-string) orig)))))
-
(defun test--font (form search)
(with-temp-buffer
(emacs-lisp-mode)
(if (stringp form)
(insert form)
(pp form (current-buffer)))
- (font-lock-debug-fontify)
+ (with-suppressed-warnings ((interactive-only font-lock-debug-fontify))
+ (font-lock-debug-fontify))
(goto-char (point-min))
(and (re-search-forward search nil t)
(get-text-property (match-beginning 1) 'face))))
@@ -1115,17 +1109,12 @@ evaluation of BODY."
(buffer-string)))))))
(should (equal observed expected-longhand-form))))
-(ert-deftest test-cl-flet-indentation ()
- :expected-result :failed ; FIXME: bug#9622
- (should (equal
- (with-temp-buffer
- (emacs-lisp-mode)
- (insert "(cl-flet ((bla (x)\n(* x x)))\n(bla 42))")
- (indent-region (point-min) (point-max))
- (buffer-string))
- "(cl-flet ((bla (x)
- (* x x)))
- (bla 42))")))
+(ert-deftest test-indentation ()
+ (ert-test-erts-file (ert-resource-file "elisp-indents.erts"))
+ (ert-test-erts-file (ert-resource-file "flet.erts")
+ (lambda ()
+ (emacs-lisp-mode)
+ (indent-region (point-min) (point-max)))))
(provide 'elisp-mode-tests)
;;; elisp-mode-tests.el ends here
diff --git a/test/lisp/progmodes/etags-tests.el b/test/lisp/progmodes/etags-tests.el
index b25958148d3..673c582cc7a 100644
--- a/test/lisp/progmodes/etags-tests.el
+++ b/test/lisp/progmodes/etags-tests.el
@@ -22,6 +22,7 @@
;;; Code:
(require 'ert)
+(require 'ert-x)
(require 'etags)
(eval-when-compile (require 'cl-lib))
@@ -95,21 +96,19 @@
(ert-deftest etags-buffer-local-tags-table-list ()
"Test that a buffer-local value of `tags-table-list' is used."
- (let ((file (make-temp-file "etag-test-tmpfile")))
- (unwind-protect
- (progn
- (set-buffer (find-file-noselect file))
- (fundamental-mode)
- (setq-local tags-table-list
- (list (expand-file-name "manual/etags/ETAGS.good_3"
- etags-tests--test-dir)))
- (cl-letf ((tag-tables tags-table-list)
- (tags-file-name nil)
- ((symbol-function 'read-file-name)
- (lambda (&rest _)
- (error "We should not prompt the user"))))
- (should (visit-tags-table-buffer))
- (should (equal tags-file-name (car tag-tables)))))
- (delete-file file))))
+ (ert-with-temp-file file
+ :suffix "etag-test-tmpfile"
+ (set-buffer (find-file-noselect file))
+ (fundamental-mode)
+ (setq-local tags-table-list
+ (list (expand-file-name "manual/etags/ETAGS.good_3"
+ etags-tests--test-dir)))
+ (cl-letf ((tag-tables tags-table-list)
+ (tags-file-name nil)
+ ((symbol-function 'read-file-name)
+ (lambda (&rest _)
+ (error "We should not prompt the user"))))
+ (should (visit-tags-table-buffer))
+ (should (equal tags-file-name (car tag-tables))))))
;;; etags-tests.el ends here
diff --git a/test/lisp/progmodes/flymake-tests.el b/test/lisp/progmodes/flymake-tests.el
index 45cabf2efba..71b03b21e5c 100644
--- a/test/lisp/progmodes/flymake-tests.el
+++ b/test/lisp/progmodes/flymake-tests.el
@@ -23,6 +23,7 @@
;;; Code:
(require 'ert)
+(require 'ert-x)
(require 'flymake)
(eval-when-compile (require 'subr-x)) ; string-trim
@@ -123,32 +124,26 @@ SEVERITY-PREDICATE is used to setup
"Test the ruby backend."
(skip-unless (executable-find "ruby"))
;; Some versions of ruby fail if HOME doesn't exist (bug#29187).
- (let* ((tempdir (make-temp-file "flymake-tests-ruby" t))
- (process-environment (cons (format "HOME=%s" tempdir)
- process-environment))
- ;; And see https://debbugs.gnu.org/cgi/bugreport.cgi?bug=19657#20
- ;; for this particular yuckiness
- (abbreviated-home-dir nil))
- (unwind-protect
- (let ((ruby-mode-hook
- (lambda ()
- (setq flymake-diagnostic-functions '(ruby-flymake-simple)))))
- (flymake-tests--with-flymake ("test.rb")
- (flymake-goto-next-error)
- (should (eq 'flymake-warning (face-at-point)))
- (flymake-goto-next-error)
- (should (eq 'flymake-error (face-at-point)))))
- (delete-directory tempdir t))))
-
-(defun flymake-tests--gcc-is-clang ()
- "Whether the `gcc' command actually runs the Clang compiler."
- (string-match "[Cc]lang version "
- (shell-command-to-string "gcc --version")))
+ (ert-with-temp-directory tempdir
+ :suffix "flymake-tests-ruby"
+ (let* ((process-environment (cons (format "HOME=%s" tempdir)
+ process-environment))
+ ;; And see https://debbugs.gnu.org/cgi/bugreport.cgi?bug=19657#20
+ ;; for this particular yuckiness
+ (abbreviated-home-dir nil)
+ (ruby-mode-hook
+ (lambda ()
+ (setq flymake-diagnostic-functions '(ruby-flymake-simple)))))
+ (flymake-tests--with-flymake ("test.rb")
+ (flymake-goto-next-error)
+ (should (eq 'flymake-warning (face-at-point)))
+ (flymake-goto-next-error)
+ (should (eq 'flymake-error (face-at-point)))))))
(ert-deftest different-diagnostic-types ()
"Test GCC warning via function predicate."
(skip-unless (and (executable-find "gcc")
- (not (flymake-tests--gcc-is-clang))
+ (not (ert-gcc-is-clang-p))
(version<=
"5" (string-trim
(shell-command-to-string "gcc -dumpversion")))
@@ -173,7 +168,7 @@ SEVERITY-PREDICATE is used to setup
(ert-deftest included-c-header-files ()
"Test inclusion of .h header files."
(skip-unless (and (executable-find "gcc")
- (not (flymake-tests--gcc-is-clang))
+ (not (ert-gcc-is-clang-p))
(executable-find "make")))
(let ((flymake-wrap-around nil))
(flymake-tests--with-flymake
diff --git a/test/lisp/progmodes/perl-mode-tests.el b/test/lisp/progmodes/perl-mode-tests.el
index e2286349359..91f1db23d62 100644
--- a/test/lisp/progmodes/perl-mode-tests.el
+++ b/test/lisp/progmodes/perl-mode-tests.el
@@ -37,4 +37,6 @@
(file-name-directory (or load-file-name
buffer-file-name)))))
+(setq ert-load-file-name load-file-name)
+
;;; perl-mode-tests.el ends here
diff --git a/test/lisp/progmodes/project-tests.el b/test/lisp/progmodes/project-tests.el
index fe4fb2912fa..d4b6bca7e8f 100644
--- a/test/lisp/progmodes/project-tests.el
+++ b/test/lisp/progmodes/project-tests.el
@@ -29,29 +29,17 @@
(require 'cl-lib)
(require 'ert)
+(require 'ert-x) ; ert-with-temp-directory
(require 'grep)
(require 'xref)
-(defmacro project-tests--with-temporary-directory (var &rest body)
- "Create a new temporary directory.
-Bind VAR to the name of the directory, and evaluate BODY. Delete
-the directory after BODY exits."
- (declare (debug (symbolp body)) (indent 1))
- (cl-check-type var symbol)
- (let ((directory (make-symbol "directory")))
- `(let ((,directory (make-temp-file "project-tests-" :directory)))
- (unwind-protect
- (let ((,var ,directory))
- ,@body)
- (delete-directory ,directory :recursive)))))
-
(ert-deftest project/quoted-directory ()
"Check that `project-files' and `project-find-regexp' deal with
quoted directory names (Bug#47799)."
(skip-unless (executable-find find-program))
(skip-unless (executable-find "xargs"))
(skip-unless (executable-find "grep"))
- (project-tests--with-temporary-directory directory
+ (ert-with-temp-directory directory
(let ((default-directory directory)
(project-current-inhibit-prompt t)
(project-find-functions nil)
@@ -95,7 +83,7 @@ quoted directory names (Bug#47799)."
returned by `project-ignores' if the root directory is a
directory name (Bug#48471)."
(skip-unless (executable-find find-program))
- (project-tests--with-temporary-directory dir
+ (ert-with-temp-directory dir
(make-empty-file (expand-file-name "some-file" dir))
(make-empty-file (expand-file-name "ignored-file" dir))
(let* ((project (make-project-tests--trivial
@@ -111,7 +99,7 @@ directory name (Bug#48471)."
"Check that `project-files' does not ignore all files.
When `project-ignores' includes a name matching project dir."
(skip-unless (executable-find find-program))
- (project-tests--with-temporary-directory dir
+ (ert-with-temp-directory dir
(make-empty-file (expand-file-name "some-file" dir))
(let* ((project (make-project-tests--trivial
:root (file-name-as-directory dir)
diff --git a/test/lisp/progmodes/python-tests.el b/test/lisp/progmodes/python-tests.el
index bfb931851de..d7b3c102f2d 100644
--- a/test/lisp/progmodes/python-tests.el
+++ b/test/lisp/progmodes/python-tests.el
@@ -22,6 +22,7 @@
;;; Code:
(require 'ert)
+(require 'ert-x)
(require 'python)
;; Dependencies for testing:
@@ -48,17 +49,17 @@ BODY is code to be executed within the temp buffer. Point is
always located at the beginning of buffer."
(declare (indent 1) (debug t))
;; temp-file never actually used for anything?
- `(let* ((temp-file (make-temp-file "python-tests" nil ".py"))
- (buffer (find-file-noselect temp-file))
- (python-indent-guess-indent-offset nil))
- (unwind-protect
- (with-current-buffer buffer
- (python-mode)
- (insert ,contents)
- (goto-char (point-min))
- ,@body)
- (and buffer (kill-buffer buffer))
- (delete-file temp-file))))
+ `(ert-with-temp-file temp-file
+ :suffix "-python.py"
+ (let ((buffer (find-file-noselect temp-file))
+ (python-indent-guess-indent-offset nil))
+ (unwind-protect
+ (with-current-buffer buffer
+ (python-mode)
+ (insert ,contents)
+ (goto-char (point-min))
+ ,@body)
+ (and buffer (kill-buffer buffer))))))
(defun python-tests-look-at (string &optional num restore-point)
"Move point at beginning of STRING in the current buffer.
@@ -94,6 +95,19 @@ STRING, it is skipped so the next STRING occurrence is selected."
found-point
(and restore-point (goto-char starting-point)))))
+(defun python-tests-assert-faces (content faces)
+ "Assert that font faces for CONTENT are equal to FACES."
+ (python-tests-with-temp-buffer content
+ (font-lock-ensure nil nil)
+ (should (equal faces (python-tests-get-buffer-faces)))))
+
+(defun python-tests-get-buffer-faces ()
+ "Return a list of (position . face) for each face change positions."
+ (cl-loop for pos = (point-min)
+ then (next-single-property-change pos 'face)
+ while pos
+ collect (cons pos (get-text-property pos 'face))))
+
(defun python-tests-self-insert (char-or-str)
"Call `self-insert-command' for chars in CHAR-OR-STR."
(let ((chars
@@ -200,6 +214,172 @@ aliqua."
(should (string= (buffer-string) "\"\""))
(should (null (nth 3 (syntax-ppss))))))
+(ert-deftest python-font-lock-keywords-level-1-1 ()
+ (python-tests-assert-faces
+ "def func():"
+ '((1 . font-lock-keyword-face) (4)
+ (5 . font-lock-function-name-face) (9))))
+
+(ert-deftest python-font-lock-keywords-level-1-2 ()
+ "Invalid function name should not be font-locked."
+ (python-tests-assert-faces
+ "def 1func():"
+ '((1 . font-lock-keyword-face) (4))))
+
+(ert-deftest python-font-lock-assignment-statement-1 ()
+ (python-tests-assert-faces
+ "a, b, c = 1, 2, 3"
+ '((1 . font-lock-variable-name-face) (2)
+ (4 . font-lock-variable-name-face) (5)
+ (7 . font-lock-variable-name-face) (8))))
+
+(ert-deftest python-font-lock-assignment-statement-2 ()
+ (python-tests-assert-faces
+ "a, *b, c = 1, 2, 3, 4, 5"
+ '((1 . font-lock-variable-name-face) (2)
+ (5 . font-lock-variable-name-face) (6)
+ (8 . font-lock-variable-name-face) (9))))
+
+(ert-deftest python-font-lock-assignment-statement-3 ()
+ (python-tests-assert-faces
+ "[a, b] = (1, 2)"
+ '((1)
+ (2 . font-lock-variable-name-face) (3)
+ (5 . font-lock-variable-name-face) (6))))
+
+(ert-deftest python-font-lock-assignment-statement-4 ()
+ (python-tests-assert-faces
+ "(l[1], l[2]) = (10, 11)"
+ '((1)
+ (2 . font-lock-variable-name-face) (3)
+ (8 . font-lock-variable-name-face) (9))))
+
+(ert-deftest python-font-lock-assignment-statement-5 ()
+ (python-tests-assert-faces
+ "(a, b, c, *d) = *x, y = 5, 6, 7, 8, 9"
+ '((1)
+ (2 . font-lock-variable-name-face) (3)
+ (5 . font-lock-variable-name-face) (6)
+ (8 . font-lock-variable-name-face) (9)
+ (12 . font-lock-variable-name-face) (13)
+ (18 . font-lock-variable-name-face) (19)
+ (21 . font-lock-variable-name-face) (22))))
+
+(ert-deftest python-font-lock-assignment-statement-6 ()
+ (python-tests-assert-faces
+ "(a,) = 'foo',"
+ '((1)
+ (2 . font-lock-variable-name-face) (3)
+ (8 . font-lock-string-face) (13))))
+
+(ert-deftest python-font-lock-assignment-statement-7 ()
+ (python-tests-assert-faces
+ "(*a,) = ['foo', 'bar', 'baz']"
+ '((1)
+ (3 . font-lock-variable-name-face) (4)
+ (10 . font-lock-string-face) (15)
+ (17 . font-lock-string-face) (22)
+ (24 . font-lock-string-face) (29))))
+
+(ert-deftest python-font-lock-assignment-statement-8 ()
+ (python-tests-assert-faces
+ "d = D('a', ['b'], 'c')"
+ '((1 . font-lock-variable-name-face) (2)
+ (7 . font-lock-string-face) (10)
+ (13 . font-lock-string-face) (16)
+ (19 . font-lock-string-face) (22))))
+
+(ert-deftest python-font-lock-assignment-statement-9 ()
+ (python-tests-assert-faces
+ "d.x, d.y[0], *d.z = 'a', 'b', 'c', 'd', 'e'"
+ '((1)
+ (3 . font-lock-variable-name-face) (4)
+ (8 . font-lock-variable-name-face) (9)
+ (17 . font-lock-variable-name-face) (18)
+ (21 . font-lock-string-face) (24)
+ (26 . font-lock-string-face) (29)
+ (31 . font-lock-string-face) (34)
+ (36 . font-lock-string-face) (39)
+ (41 . font-lock-string-face))))
+
+(ert-deftest python-font-lock-assignment-statement-10 ()
+ (python-tests-assert-faces
+ "a: int = 5"
+ '((1 . font-lock-variable-name-face) (2)
+ (4 . font-lock-builtin-face) (7))))
+
+(ert-deftest python-font-lock-assignment-statement-11 ()
+ (python-tests-assert-faces
+ "b: Tuple[Optional[int], Union[Sequence[str], str]] = (None, 'foo')"
+ '((1 . font-lock-variable-name-face) (2)
+ (19 . font-lock-builtin-face) (22)
+ (40 . font-lock-builtin-face) (43)
+ (46 . font-lock-builtin-face) (49)
+ (55 . font-lock-constant-face) (59)
+ (61 . font-lock-string-face) (66))))
+
+(ert-deftest python-font-lock-assignment-statement-12 ()
+ (python-tests-assert-faces
+ "c: Collection = {1, 2, 3}"
+ '((1 . font-lock-variable-name-face) (2))))
+
+(ert-deftest python-font-lock-assignment-statement-13 ()
+ (python-tests-assert-faces
+ "d: Mapping[int, str] = {1: 'bar', 2: 'baz'}"
+ '((1 . font-lock-variable-name-face) (2)
+ (12 . font-lock-builtin-face) (15)
+ (17 . font-lock-builtin-face) (20)
+ (28 . font-lock-string-face) (33)
+ (38 . font-lock-string-face) (43))))
+
+(ert-deftest python-font-lock-assignment-statement-14 ()
+ (python-tests-assert-faces
+ "(a) = 5; (b) = 6"
+ '((1)
+ (2 . font-lock-variable-name-face) (3)
+ (11 . font-lock-variable-name-face) (12))))
+
+(ert-deftest python-font-lock-assignment-statement-15 ()
+ (python-tests-assert-faces
+ "[a] = 5,; [b] = 6,"
+ '((1)
+ (2 . font-lock-variable-name-face) (3)
+ (12 . font-lock-variable-name-face) (13))))
+
+(ert-deftest python-font-lock-assignment-statement-16 ()
+ (python-tests-assert-faces
+ "[*a] = 5, 6; [*b] = 7, 8"
+ '((1)
+ (3 . font-lock-variable-name-face) (4)
+ (16 . font-lock-variable-name-face) (17))))
+
+(ert-deftest python-font-lock-assignment-statement-17 ()
+ (python-tests-assert-faces
+ "(a) = (b) = 1"
+ `((1)
+ (2 . font-lock-variable-name-face) (3)
+ (8 . font-lock-variable-name-face) (9))))
+
+(ert-deftest python-font-lock-assignment-statement-18 ()
+ (python-tests-assert-faces
+ "CustomInt = int
+
+def f(x: CustomInt) -> CustomInt:
+ y = x + 1
+ ys: Sequence[CustomInt] = [y, y + 1]
+ res: CustomInt = sum(ys) + 1
+ return res
+"
+ '((1 . font-lock-variable-name-face) (10)
+ (13 . font-lock-builtin-face) (16)
+ (18 . font-lock-keyword-face) (21)
+ (22 . font-lock-function-name-face) (23)
+ (56 . font-lock-variable-name-face) (57)
+ (70 . font-lock-variable-name-face) (72)
+ (111 . font-lock-variable-name-face) (114)
+ (128 . font-lock-builtin-face) (131)
+ (144 . font-lock-keyword-face) (150))))
+
;;; Indentation
@@ -1348,6 +1528,31 @@ this is an arbitrarily
(should (string= (buffer-substring-no-properties (point-min) (point-max))
expected)))))
+(ert-deftest python-indent-after-match-block ()
+ "Test PEP634 match."
+ (python-tests-with-temp-buffer
+ "
+match foo:
+"
+ (should (eq (car (python-indent-context)) :no-indent))
+ (should (= (python-indent-calculate-indentation) 0))
+ (goto-char (point-max))
+ (should (eq (car (python-indent-context)) :after-block-start))
+ (should (= (python-indent-calculate-indentation) 4))))
+
+(ert-deftest python-indent-after-case-block ()
+ "Test PEP634 case."
+ (python-tests-with-temp-buffer
+ "
+match foo:
+ case 1:
+"
+ (should (eq (car (python-indent-context)) :no-indent))
+ (should (= (python-indent-calculate-indentation) 0))
+ (goto-char (point-max))
+ (should (eq (car (python-indent-context)) :after-block-start))
+ (should (= (python-indent-calculate-indentation) 8))))
+
;;; Filling
@@ -1531,6 +1736,57 @@ class C:
(should (= (marker-position (mark-marker))
expected-mark-end-position)))))
+(ert-deftest python-mark-defun-4 ()
+ "Test `python-mark-defun' with nested functions."
+ (python-tests-with-temp-buffer
+ "
+def foo(x):
+ def bar():
+ return x
+ if True:
+ return bar
+"
+ (let ((expected-mark-beginning-position
+ (progn
+ (python-tests-look-at "def foo(x):")
+ (1- (line-beginning-position))))
+ (expected-mark-end-position (point-max)))
+ (python-tests-look-at "return bar")
+ (python-mark-defun 1)
+ (should (= (point) expected-mark-beginning-position))
+ (should (= (marker-position (mark-marker))
+ expected-mark-end-position)))))
+
+(ert-deftest python-mark-defun-5 ()
+ "Test `python-mark-defun' with point inside backslash escaped defun."
+ (python-tests-with-temp-buffer
+ "
+def \\
+ foo(x):
+ return x
+"
+ (let ((transient-mark-mode t)
+ (expected-mark-beginning-position
+ (progn
+ (python-tests-look-at "def ")
+ (1- (line-beginning-position))))
+ (expected-mark-end-position
+ (save-excursion
+ (python-tests-look-at "return x")
+ (forward-line)
+ (point))))
+ (python-tests-look-at "def ")
+ (python-mark-defun 1)
+ (should (= (point) expected-mark-beginning-position))
+ (should (= (marker-position (mark-marker))
+ expected-mark-end-position))
+ (deactivate-mark)
+ (python-tests-look-at "foo(x)")
+ (python-mark-defun 1)
+ (should (= (point) expected-mark-beginning-position))
+ (should (= (marker-position (mark-marker))
+ expected-mark-end-position)))))
+
;;; Navigation
@@ -1557,12 +1813,20 @@ def decoratorFunctionWithArguments(arg1, arg2, arg3):
return wrapped_f
return wwrap
"
- (python-tests-look-at "return wrap")
+ (python-tests-look-at "return wwrap")
(should (= (save-excursion
(python-nav-beginning-of-defun)
(point))
(save-excursion
- (python-tests-look-at "def wrapped_f(*args):" -1)
+ (python-tests-look-at "def decoratorFunctionWithArguments" -1)
+ (beginning-of-line)
+ (point))))
+ (python-tests-look-at "return wrap" -1)
+ (should (= (save-excursion
+ (python-nav-beginning-of-defun)
+ (point))
+ (save-excursion
+ (python-tests-look-at "def wwrap(f):" -1)
(beginning-of-line)
(point))))
(python-tests-look-at "def wrapped_f(*args):" -1)
@@ -1596,6 +1860,9 @@ class C(object):
def a():
pass
+ if True:
+ return a
+
def c(self):
pass
"
@@ -1608,6 +1875,15 @@ class C(object):
(python-tests-look-at "def m(self):" -1)
(beginning-of-line)
(point))))
+ ;; Nested defuns shuld be skipped.
+ (python-tests-look-at "return a" -1)
+ (should (= (save-excursion
+ (python-nav-beginning-of-defun)
+ (point))
+ (save-excursion
+ (python-tests-look-at "def m(self):" -1)
+ (beginning-of-line)
+ (point))))
;; Defuns on same levels should be respected.
(python-tests-look-at "def a():" -1)
(should (= (save-excursion
@@ -1656,6 +1932,52 @@ class C(object):
(beginning-of-line)
(point))))))
+(ert-deftest python-nav-beginning-of-defun-4 ()
+ (python-tests-with-temp-buffer
+ "
+def a():
+ pass
+
+def \\
+ b():
+ return 0
+
+def c():
+ pass
+"
+ (python-tests-look-at "def c():")
+ (should (= (save-excursion
+ (python-nav-beginning-of-defun)
+ (point))
+ (save-excursion
+ (python-tests-look-at "def \\" -1)
+ (beginning-of-line)
+ (point))))
+ (python-tests-look-at "return 0" -1)
+ (should (= (save-excursion
+ (python-nav-beginning-of-defun)
+ (point))
+ (save-excursion
+ (python-tests-look-at "def \\" -1)
+ (beginning-of-line)
+ (point))))
+ (python-tests-look-at "b():" -1)
+ (should (= (save-excursion
+ (python-nav-beginning-of-defun)
+ (point))
+ (save-excursion
+ (python-tests-look-at "def \\" -1)
+ (beginning-of-line)
+ (point))))
+ (python-tests-look-at "def a():" -1)
+ (should (= (save-excursion
+ (python-nav-beginning-of-defun -1)
+ (point))
+ (save-excursion
+ (python-tests-look-at "def \\")
+ (beginning-of-line)
+ (point))))))
+
(ert-deftest python-nav-end-of-defun-1 ()
(python-tests-with-temp-buffer
"
@@ -1759,6 +2081,20 @@ def decoratorFunctionWithArguments(arg1, arg2, arg3):
(python-tests-look-at "return wrapped_f")
(line-beginning-position))))))
+(ert-deftest python-nav-end-of-defun-3 ()
+ (python-tests-with-temp-buffer
+ "
+def \\
+ a():
+ return 0
+"
+ (should (= (save-excursion
+ (python-tests-look-at "def \\")
+ (python-nav-end-of-defun)
+ (point))
+ (save-excursion
+ (point-max))))))
+
(ert-deftest python-nav-backward-defun-1 ()
(python-tests-with-temp-buffer
"
@@ -1857,6 +2193,18 @@ class A(object):
(should (not (python-nav-backward-defun)))
(should (= point (point))))))
+(ert-deftest python-nav-backward-defun-4 ()
+ (python-tests-with-temp-buffer
+ "
+def \\
+ a():
+ return 0
+"
+ (goto-char (point-max))
+ (should (= (save-excursion (python-nav-backward-defun))
+ (python-tests-look-at "def \\" -1)))
+ (should (not (python-nav-backward-defun)))))
+
(ert-deftest python-nav-forward-defun-1 ()
(python-tests-with-temp-buffer
"
@@ -1955,6 +2303,18 @@ class A(object):
(should (not (python-nav-forward-defun)))
(should (= point (point))))))
+(ert-deftest python-nav-forward-defun-4 ()
+ (python-tests-with-temp-buffer
+ "
+def \\
+ a():
+ return 0
+"
+ (goto-char (point-min))
+ (should (= (save-excursion (python-nav-forward-defun))
+ (python-tests-look-at "():")))
+ (should (not (python-nav-forward-defun)))))
+
(ert-deftest python-nav-beginning-of-statement-1 ()
(python-tests-with-temp-buffer
"
@@ -2265,6 +2625,18 @@ def decoratorFunctionWithArguments(arg1, arg2, arg3):
(python-tests-look-at "print 'After f(*args)'")
(line-end-position))))))
+(ert-deftest python-nav-end-of-block-2 ()
+ "Ensure that `python-nav-end-of-block' does not enter an infinite loop."
+ (python-tests-with-temp-buffer
+ "def
+ =''
+ '
+\"\"\"\"\"\"
+ #
+''
+"
+ (python-nav-end-of-block)))
+
(ert-deftest python-nav-forward-block-1 ()
"This also accounts as a test for `python-nav-backward-block'."
(python-tests-with-temp-buffer
@@ -2633,58 +3005,59 @@ if x:
"Test `python-shell-process-environment' modification."
(let* ((python-shell-process-environment
'("TESTVAR1=value1" "TESTVAR2=value2"))
- (process-environment (python-shell-calculate-process-environment)))
- (should (equal (getenv "TESTVAR1") "value1"))
- (should (equal (getenv "TESTVAR2") "value2"))))
+ (env (python-shell--calculate-process-environment)))
+ (should (equal (getenv-internal "TESTVAR1" env) "value1"))
+ (should (equal (getenv-internal "TESTVAR2" env) "value2"))))
(ert-deftest python-shell-calculate-process-environment-2 ()
"Test `python-shell-extra-pythonpaths' modification."
(let* ((process-environment process-environment)
(_original-pythonpath (setenv "PYTHONPATH" "/path0"))
(python-shell-extra-pythonpaths '("/path1" "/path2"))
- (process-environment (python-shell-calculate-process-environment)))
- (should (equal (getenv "PYTHONPATH")
+ (env (python-shell--calculate-process-environment)))
+ (should (equal (getenv-internal "PYTHONPATH" env)
(concat "/path1" path-separator
"/path2" path-separator "/path0")))))
(ert-deftest python-shell-calculate-process-environment-3 ()
"Test `python-shell-virtualenv-root' modification."
(let* ((python-shell-virtualenv-root "/env")
- (process-environment
+ (env
(let ((process-environment process-environment))
(setenv "PYTHONHOME" "/home")
(setenv "VIRTUAL_ENV")
- (python-shell-calculate-process-environment))))
- (should (not (getenv "PYTHONHOME")))
- (should (string= (getenv "VIRTUAL_ENV") "/env"))))
+ (python-shell--calculate-process-environment))))
+ (should (member "PYTHONHOME" env))
+ (should (string= (getenv-internal "VIRTUAL_ENV" env) "/env"))))
(ert-deftest python-shell-calculate-process-environment-4 ()
"Test PYTHONUNBUFFERED when `python-shell-unbuffered' is non-nil."
(let* ((python-shell-unbuffered t)
- (process-environment
+ (env
(let ((process-environment process-environment))
(setenv "PYTHONUNBUFFERED")
- (python-shell-calculate-process-environment))))
- (should (string= (getenv "PYTHONUNBUFFERED") "1"))))
+ (python-shell--calculate-process-environment))))
+ (should (string= (getenv-internal "PYTHONUNBUFFERED" env) "1"))))
(ert-deftest python-shell-calculate-process-environment-5 ()
"Test PYTHONUNBUFFERED when `python-shell-unbuffered' is nil."
(let* ((python-shell-unbuffered nil)
- (process-environment
+ (env
(let ((process-environment process-environment))
(setenv "PYTHONUNBUFFERED")
- (python-shell-calculate-process-environment))))
- (should (not (getenv "PYTHONUNBUFFERED")))))
+ (python-shell--calculate-process-environment))))
+ (should (not (getenv-internal "PYTHONUNBUFFERED" env)))))
(ert-deftest python-shell-calculate-process-environment-6 ()
"Test PYTHONUNBUFFERED=1 when `python-shell-unbuffered' is nil."
(let* ((python-shell-unbuffered nil)
- (process-environment
+ (env
(let ((process-environment process-environment))
(setenv "PYTHONUNBUFFERED" "1")
- (python-shell-calculate-process-environment))))
+ (append (python-shell--calculate-process-environment)
+ process-environment))))
;; User default settings must remain untouched:
- (should (string= (getenv "PYTHONUNBUFFERED") "1"))))
+ (should (string= (getenv-internal "PYTHONUNBUFFERED" env) "1"))))
(ert-deftest python-shell-calculate-process-environment-7 ()
"Test no side-effects on `process-environment'."
@@ -2694,7 +3067,7 @@ if x:
(python-shell-unbuffered t)
(python-shell-extra-pythonpaths'("/path1" "/path2"))
(original-process-environment (copy-sequence process-environment)))
- (python-shell-calculate-process-environment)
+ (python-shell--calculate-process-environment)
(should (equal process-environment original-process-environment))))
(ert-deftest python-shell-calculate-process-environment-8 ()
@@ -2707,7 +3080,7 @@ if x:
(python-shell-extra-pythonpaths'("/path1" "/path2"))
(original-process-environment
(copy-sequence tramp-remote-process-environment)))
- (python-shell-calculate-process-environment)
+ (python-shell--calculate-process-environment)
(should (equal tramp-remote-process-environment original-process-environment))))
(ert-deftest python-shell-calculate-exec-path-1 ()
@@ -2779,23 +3152,43 @@ if x:
(should (string= (getenv "VIRTUAL_ENV") "/env")))
(should (equal exec-path original-exec-path))))
+(defun python--tests-process-env-canonical (pe)
+ ;; `process-environment' can contain various entries for the same
+ ;; var, and the first in the list hides the others.
+ (let ((process-environment '()))
+ (dolist (x (reverse pe))
+ (if (string-match "=" x)
+ (setenv (substring x 0 (match-beginning 0))
+ (substring x (match-end 0)))
+ (setenv x nil)))
+ process-environment))
+
+(defun python--tests-process-env-eql (pe1 pe2)
+ (equal (python--tests-process-env-canonical pe1)
+ (python--tests-process-env-canonical pe2)))
+
(ert-deftest python-shell-with-environment-2 ()
"Test environment with remote `default-directory'."
(let* ((default-directory "/ssh::/example/dir/")
(python-shell-remote-exec-path '("/remote1" "/remote2"))
(python-shell-exec-path '("/path1" "/path2"))
(tramp-remote-process-environment '("EMACS=t"))
- (original-process-environment (copy-sequence tramp-remote-process-environment))
+ (original-process-environment
+ (copy-sequence tramp-remote-process-environment))
(python-shell-virtualenv-root "/env"))
(python-shell-with-environment
(should (equal (python-shell-calculate-exec-path)
(list (python-virt-bin)
"/path1" "/path2" "/remote1" "/remote2")))
- (let ((process-environment (python-shell-calculate-process-environment)))
+ (let ((process-environment
+ (append (python-shell--calculate-process-environment)
+ tramp-remote-process-environment)))
(should (not (getenv "PYTHONHOME")))
(should (string= (getenv "VIRTUAL_ENV") "/env"))
- (should (equal tramp-remote-process-environment process-environment))))
- (should (equal tramp-remote-process-environment original-process-environment))))
+ (should (python--tests-process-env-eql
+ tramp-remote-process-environment process-environment))))
+ (should (equal tramp-remote-process-environment
+ original-process-environment))))
(ert-deftest python-shell-with-environment-3 ()
"Test `python-shell-with-environment' is idempotent."
@@ -2804,11 +3197,14 @@ if x:
(python-shell-virtualenv-root "/home/user/env")
(single-call
(python-shell-with-environment
- (list exec-path process-environment)))
+ (list exec-path
+ (python--tests-process-env-canonical process-environment))))
(nested-call
(python-shell-with-environment
(python-shell-with-environment
- (list exec-path process-environment)))))
+ (list exec-path
+ (python--tests-process-env-canonical
+ process-environment))))))
(should (equal single-call nested-call))))
(ert-deftest python-shell-make-comint-1 ()
@@ -3478,10 +3874,7 @@ def foo():
(should (string= (python-shell-buffer-substring
(python-tests-look-at "print ('a')")
(point-max))
- "if True:
-
- print ('a')
-"))))
+ "# -*- coding: utf-8 -*-\nif True:\n print ('a')\n\n"))))
(ert-deftest python-shell-buffer-substring-11 ()
"Check substring from partial block and point within indentation."
@@ -3496,10 +3889,7 @@ def foo():
(backward-char 1)
(point))
(point-max))
- "if True:
-
- print ('a')
-"))))
+ "# -*- coding: utf-8 -*-\nif True:\n print ('a')\n\n"))))
(ert-deftest python-shell-buffer-substring-12 ()
"Check substring from partial block and point in whitespace."
@@ -3514,13 +3904,7 @@ def foo():
(should (string= (python-shell-buffer-substring
(python-tests-look-at "# Whitespace")
(point-max))
- "if True:
-
-
- # Whitespace
-
- print ('a')
-"))))
+ "# -*- coding: utf-8 -*-\n\nif True:\n # Whitespace\n\n print ('a')\n\n"))))
@@ -4918,6 +5302,23 @@ def decorat0r(deff):
(python-tests-look-at "deff()")
(should (not (python-info-looking-at-beginning-of-defun)))))
+(ert-deftest python-info-looking-at-beginning-of-defun-2 ()
+ (python-tests-with-temp-buffer
+ "
+def \\
+ foo(arg):
+ pass
+"
+ (python-tests-look-at "def \\")
+ (should (python-info-looking-at-beginning-of-defun))
+ (should (python-info-looking-at-beginning-of-defun nil t))
+ (python-tests-look-at "foo(arg):")
+ (should (not (python-info-looking-at-beginning-of-defun)))
+ (should (python-info-looking-at-beginning-of-defun nil t))
+ (python-tests-look-at "pass")
+ (should (not (python-info-looking-at-beginning-of-defun)))
+ (should (not (python-info-looking-at-beginning-of-defun nil t)))))
+
(ert-deftest python-info-current-line-comment-p-1 ()
(python-tests-with-temp-buffer
"
diff --git a/test/lisp/progmodes/ruby-mode-resources/ruby.rb b/test/lisp/progmodes/ruby-mode-resources/ruby.rb
index 8c698e4fac8..0c206b1e0c2 100644
--- a/test/lisp/progmodes/ruby-mode-resources/ruby.rb
+++ b/test/lisp/progmodes/ruby-mode-resources/ruby.rb
@@ -483,3 +483,20 @@ foo bar, {
2 = 3
:foo= if true
{:abc=>4} # not indented, and '=' is not highlighted
+
+# Pattern matching
+case translation
+in ['th', orig_text, 'en', trans_text]
+ puts "English translation: #{orig_text} => #{trans_text}"
+in {'th' => orig_text, 'ja' => trans_text}
+ puts "Japanese translation: #{orig_text} => #{trans_text}"
+end
+
+# Tokenizing "**" and "|" separately.
+def resolve(**args)
+ members = proc do |**args|
+ p(**args)
+ end
+
+ member.call(**args)
+end
diff --git a/test/lisp/progmodes/ruby-mode-tests.el b/test/lisp/progmodes/ruby-mode-tests.el
index 23e13b94e6b..33fded5a59b 100644
--- a/test/lisp/progmodes/ruby-mode-tests.el
+++ b/test/lisp/progmodes/ruby-mode-tests.el
@@ -407,6 +407,13 @@ VALUES-PLIST is a list with alternating index and value elements."
(ruby-toggle-block)
(should (string= "foo { \"#{bar}\" }" (buffer-string)))))
+(ert-deftest ruby-toggle-block-to-brace-no-space ()
+ (ruby-with-temp-buffer "foo do |b|\n b + 2\nend"
+ (beginning-of-line)
+ (let (ruby-toggle-block-space-before-parameters)
+ (ruby-toggle-block))
+ (should (string= "foo {|b| b + 2 }" (buffer-string)))))
+
(ert-deftest ruby-recognize-symbols-starting-with-at-character ()
(ruby-assert-face ":@abc" 3 font-lock-constant-face))
diff --git a/test/lisp/progmodes/sh-script-resources/sh-indents.erts b/test/lisp/progmodes/sh-script-resources/sh-indents.erts
new file mode 100644
index 00000000000..1f92610b3aa
--- /dev/null
+++ b/test/lisp/progmodes/sh-script-resources/sh-indents.erts
@@ -0,0 +1,40 @@
+Code:
+ (lambda ()
+ (shell-script-mode)
+ (indent-region (point-min) (point-max)))
+
+Name: sh-indents1
+
+=-=
+if test;then
+ something
+fi
+other
+=-=-=
+
+Name: sh-indents2
+
+=-=
+if test; then
+ something
+fi
+other
+=-=-=
+
+Name: sh-indents3
+
+=-=
+if test ; then
+ something
+fi
+other
+=-=-=
+
+Name: sh-indents4
+
+=-=
+if test ;then
+ something
+fi
+other
+=-=-=
diff --git a/test/lisp/progmodes/sh-script-tests.el b/test/lisp/progmodes/sh-script-tests.el
index ebd26ab4295..5d01cc1c226 100644
--- a/test/lisp/progmodes/sh-script-tests.el
+++ b/test/lisp/progmodes/sh-script-tests.el
@@ -23,6 +23,7 @@
(require 'sh-script)
(require 'ert)
+(require 'ert-x)
(ert-deftest test-sh-script-indentation ()
(with-temp-buffer
@@ -48,4 +49,24 @@
}
"))))
+(ert-deftest test-indentation ()
+ (ert-test-erts-file (ert-resource-file "sh-indents.erts")))
+
+(defun test-sh-back (string &optional pos)
+ (with-temp-buffer
+ (shell-script-mode)
+ (insert string)
+ (sh-smie--default-backward-token)
+ (= (point) (or pos 1))))
+
+(ert-deftest test-backward-token ()
+ (should (test-sh-back "foo"))
+ (should (test-sh-back "foo.bar"))
+ (should (test-sh-back "foo\\1bar"))
+ (should (test-sh-back "foo\\\nbar"))
+ (should (test-sh-back "foo\\\n\\\n\\\nbar"))
+ (should (test-sh-back "foo"))
+ (should-not (test-sh-back "foo;bar"))
+ (should (test-sh-back "foo#zot")))
+
;;; sh-script-tests.el ends here
diff --git a/test/lisp/progmodes/sql-tests.el b/test/lisp/progmodes/sql-tests.el
index 51d76fba727..c644d115df6 100644
--- a/test/lisp/progmodes/sql-tests.el
+++ b/test/lisp/progmodes/sql-tests.el
@@ -28,6 +28,7 @@
(require 'cl-lib)
(require 'ert)
+(require 'ert-x)
(require 'sql)
(ert-deftest sql-tests-postgres-list-databases ()
@@ -63,52 +64,49 @@ Identify tests by ID. Set :sql-login dialect attribute to
LOGIN-PARAMS. Provide the CONNECTION parameters and the EXPECTED
string of values passed to the comint function for validation."
(declare (indent 2))
- `(cl-letf
- ((sql-test-login-params ' ,login-params)
- ((symbol-function 'sql-comint-test)
- (lambda (product options &optional buf-name)
- (with-current-buffer (get-buffer-create buf-name)
- (insert (pp-to-string (list product options sql-user sql-password sql-server sql-database))))))
- ((symbol-function 'sql-run-test)
- (lambda (&optional buffer)
- (interactive "P")
- (sql-product-interactive 'sqltest buffer)))
- (sql-user nil)
- (sql-server nil)
- (sql-database nil)
- (sql-product-alist
- '((ansi)
- (sqltest
- :name "SqlTest"
- :sqli-login sql-test-login-params
- :sqli-comint-func sql-comint-test)))
- (sql-connection-alist
- '((,(format "test-%s" id)
- ,@connection)))
- (sql-password-wallet
- (list
- (make-temp-file
- "sql-test-netrc" nil nil
- (mapconcat #'identity
- '("machine aMachine user aUserName password \"netrc-A aPassword\""
- "machine aServer user aUserName password \"netrc-B aPassword\""
- "machine aMachine server aServer user aUserName password \"netrc-C aPassword\""
- "machine aMachine database aDatabase user aUserName password \"netrc-D aPassword\""
- "machine aDatabase user aUserName password \"netrc-E aPassword\""
- "machine aMachine server aServer database aDatabase user aUserName password \"netrc-F aPassword\""
- "machine \"aServer/aDatabase\" user aUserName password \"netrc-G aPassword\""
- ) "\n")))))
-
- (let* ((connection ,(format "test-%s" id))
- (buffername (format "*SQL: ERT TEST <%s>*" connection)))
- (when (get-buffer buffername)
- (kill-buffer buffername))
- (sql-connect connection buffername)
- (should (get-buffer buffername))
- (should (string-equal (with-current-buffer buffername (buffer-string)) ,expected))
- (when (get-buffer buffername)
- (kill-buffer buffername))
- (delete-file (car sql-password-wallet)))))
+ `(ert-with-temp-file tempfile
+ :suffix "sql-test-netrc"
+ :text (concat
+ "machine aMachine user aUserName password \"netrc-A aPassword\""
+ "machine aServer user aUserName password \"netrc-B aPassword\""
+ "machine aMachine server aServer user aUserName password \"netrc-C aPassword\""
+ "machine aMachine database aDatabase user aUserName password \"netrc-D aPassword\""
+ "machine aDatabase user aUserName password \"netrc-E aPassword\""
+ "machine aMachine server aServer database aDatabase user aUserName password \"netrc-F aPassword\""
+ "machine \"aServer/aDatabase\" user aUserName password \"netrc-G aPassword\""
+ "\n")
+ (cl-letf
+ ((sql-test-login-params ' ,login-params)
+ ((symbol-function 'sql-comint-test)
+ (lambda (product options &optional buf-name)
+ (with-current-buffer (get-buffer-create buf-name)
+ (insert (pp-to-string (list product options sql-user sql-password sql-server sql-database))))))
+ ((symbol-function 'sql-run-test)
+ (lambda (&optional buffer)
+ (interactive "P")
+ (sql-product-interactive 'sqltest buffer)))
+ (sql-user nil)
+ (sql-server nil)
+ (sql-database nil)
+ (sql-product-alist
+ '((ansi)
+ (sqltest
+ :name "SqlTest"
+ :sqli-login sql-test-login-params
+ :sqli-comint-func sql-comint-test)))
+ (sql-connection-alist
+ '((,(format "test-%s" id)
+ ,@connection)))
+ (sql-password-wallet (list tempfile)))
+ (let* ((connection ,(format "test-%s" id))
+ (buffername (format "*SQL: ERT TEST <%s>*" connection)))
+ (when (get-buffer buffername)
+ (kill-buffer buffername))
+ (sql-connect connection buffername)
+ (should (get-buffer buffername))
+ (should (string-equal (with-current-buffer buffername (buffer-string)) ,expected))
+ (when (get-buffer buffername)
+ (kill-buffer buffername))))))
(ert-deftest sql-test-connect ()
"Test of basic `sql-connect'."
@@ -416,6 +414,96 @@ The ACTION will be tested after set-up of PRODUCT."
(kill-buffer "*SQL: exist*")))
+(ert-deftest sql-tests-comint-automatic-password ()
+ (let ((sql-password nil))
+ (should-not (sql-comint-automatic-password "Password: ")))
+ (let ((sql-password ""))
+ (should-not (sql-comint-automatic-password "Password: ")))
+ (let ((sql-password "password"))
+ (should (equal "password" (sql-comint-automatic-password "Password: "))))
+ ;; Also, we shouldn't care what the password is - we rely on comint for that.
+ (let ((sql-password "password"))
+ (should (equal "password" (sql-comint-automatic-password "")))))
+
+
+
+;; Tests for sql-interactive-remove-continuation-prompt
+
+(defmacro sql-tests-remove-cont-prompts-harness (&rest body)
+ "Set-up and tear-down for tests of
+`sql-interactive-remove-continuation-prompt'."
+ (declare (indent 0))
+ `(let ((comint-prompt-regexp "^ +\\.\\{3\\} ")
+ (sql-output-newline-count nil)
+ (sql-preoutput-hold nil))
+ ,@body
+ (should (null sql-output-newline-count))
+ (should (null sql-preoutput-hold))))
+
+(ert-deftest sql-tests-remove-cont-prompts-pass-through ()
+ "Test that `sql-interactive-remove-continuation-prompt' just
+passes the output line through when it doesn't expect prompts."
+ (sql-tests-remove-cont-prompts-harness
+ (should
+ (equal " ... "
+ (sql-interactive-remove-continuation-prompt
+ " ... ")))))
+
+(ert-deftest sql-tests-remove-cont-prompts-anchored-successive ()
+ "Test that `sql-interactive-remove-continuation-prompt' is able
+to delete multiple prompts (anchored to bol) even if they appear
+in a single line, but not more than `sql-output-newline-count'."
+ (sql-tests-remove-cont-prompts-harness
+ (setq sql-output-newline-count 2)
+ (should
+ (equal
+ ;; 2 of 3 prompts are deleted
+ "some output ... more output...\n\
+ ... \n\
+output after prompt"
+ (sql-interactive-remove-continuation-prompt
+ "some output ... more output...\n\
+ ... ... ... \n\
+output after prompt")))))
+
+(ert-deftest sql-tests-remove-cont-prompts-collect-chunked-output ()
+ "Test that `sql-interactive-remove-continuation-prompt' properly
+collects output when output arrives in chunks, with prompts
+intermixed."
+ (sql-tests-remove-cont-prompts-harness
+ (setq sql-output-newline-count 2)
+
+ ;; Part of first prompt gets held. Complete line is passed
+ ;; through.
+ (should (equal "line1\n"
+ (sql-interactive-remove-continuation-prompt
+ "line1\n ..")))
+ (should (equal " .." sql-preoutput-hold))
+ (should (equal 2 sql-output-newline-count))
+
+ ;; First prompt is complete - remove it. Hold part of line2.
+ (should (equal ""
+ (sql-interactive-remove-continuation-prompt ". li")))
+ (should (equal "li" sql-preoutput-hold))
+ (should (equal 1 sql-output-newline-count))
+
+ ;; Remove second prompt. Flush output & don't hold / process any
+ ;; output further on.
+ (should (equal "line2\nli"
+ (sql-interactive-remove-continuation-prompt "ne2\n ... li")))
+ (should (null sql-preoutput-hold))
+ (should (null sql-output-newline-count))
+ (should (equal "line3\n ... "
+ (sql-interactive-remove-continuation-prompt "line3\n ... ")))))
+
+(ert-deftest sql-tests-remove-cont-prompts-flush-held ()
+ "Test that when we don't wait for prompts,
+ `sql-interactive-remove-continuation-prompt' just 'flushes' held
+ output, with no prompt processing."
+ (sql-tests-remove-cont-prompts-harness
+ (setq sql-preoutput-hold "line1\n ..")
+ (should (equal "line1\n ... line2 .."
+ (sql-interactive-remove-continuation-prompt ". line2 ..")))))
(provide 'sql-tests)
;;; sql-tests.el ends here
diff --git a/test/lisp/repeat-tests.el b/test/lisp/repeat-tests.el
index b71c333a2da..1382d003599 100644
--- a/test/lisp/repeat-tests.el
+++ b/test/lisp/repeat-tests.el
@@ -34,20 +34,16 @@
(interactive "p")
(push `(,arg b) repeat-tests-calls))
-(defvar repeat-tests-map
- (let ((map (make-sparse-keymap)))
- (define-key map (kbd "C-x w a") 'repeat-tests-call-a)
- (define-key map (kbd "M-C-a") 'repeat-tests-call-a)
- (define-key map (kbd "M-C-z") 'repeat-tests-call-a)
- map)
- "Keymap for keys that initiate repeating sequences.")
-
-(defvar repeat-tests-repeat-map
- (let ((map (make-sparse-keymap)))
- (define-key map "a" 'repeat-tests-call-a)
- (define-key map "b" 'repeat-tests-call-b)
- map)
- "Keymap for repeating sequences.")
+(defvar-keymap repeat-tests-map
+ :doc "Keymap for keys that initiate repeating sequences."
+ "C-x w a" 'repeat-tests-call-a
+ "C-M-a" 'repeat-tests-call-a
+ "C-M-z" 'repeat-tests-call-a)
+
+(defvar-keymap repeat-tests-repeat-map
+ :doc "Keymap for repeating sequences."
+ "a" 'repeat-tests-call-a
+ "b" 'repeat-tests-call-b)
(put 'repeat-tests-call-a 'repeat-map 'repeat-tests-repeat-map)
(put 'repeat-tests-call-b 'repeat-map repeat-tests-repeat-map)
diff --git a/test/lisp/replace-tests.el b/test/lisp/replace-tests.el
index fa28789da99..ef1e5c3eafc 100644
--- a/test/lisp/replace-tests.el
+++ b/test/lisp/replace-tests.el
@@ -406,6 +406,102 @@ Each element has the format:
(kill-buffer temp-buffer)))))
+;;; General tests for `query-replace' and `query-replace-regexp'.
+
+(defconst query-replace-tests
+ '(
+ ;; query-replace
+ ("aaa" "M-% a RET 1 RET !" "111")
+ ("aaa" "M-% a RET 1 RET y n y" "1a1")
+ ;; Empty inputs
+ ("aaa" "M-% a RET RET !" "")
+ ("aaa" "M-% RET 1 RET !" "1a1a1a")
+ ("aaa" "M-% RET RET !" "aaa")
+ ;; Reuse the previous default
+ ("aaa" "M-% a RET 1 RET . M-% RET !" "111")
+
+ ;; query-replace-regexp
+ ("aaa" "C-M-% a* RET 1 RET !" "1")
+ ;; Empty inputs
+ ("aaa" "C-M-% a* RET RET !" "")
+ ("aaa" "C-M-% RET 1 RET !" "1a1a1a")
+ ("aaa" "C-M-% RET RET !" "aaa")
+ ;; Empty matches
+ ("aaa" "C-M-% b* RET 1 RET !" "1a1a1a")
+ ;; Complete matches
+ ("aaa" "C-M-% .* RET 1 RET !" "1")
+ ;; Adjacent non-empty matches
+ ("abaab" "C-M-% ab* RET 12 RET !" "121212")
+ ;; Adjacent non-empty and empty matches
+ ("abab" "C-M-% a* RET 1 RET !" "1b1b")
+ ("abab" "C-M-% b* RET 1 RET !" "1a1a1")
+ ;; Test case from commit 5632eb272c7
+ ("a a a " "C-M-% \\ba SPC RET c RET !" "ccc") ; not "ca c"
+ ))
+
+(defun query-replace--run-tests (tests)
+ (with-temp-buffer
+ (save-window-excursion
+ ;; `execute-kbd-macro' is applied to window only
+ (set-window-buffer nil (current-buffer))
+ (dolist (case tests)
+ ;; Ensure empty input means empty string to replace:
+ (setq query-replace-defaults nil)
+ (delete-region (point-min) (point-max))
+ (insert (nth 0 case))
+ (goto-char (point-min))
+ (execute-kbd-macro (kbd (nth 1 case)))
+ (should (equal (buffer-string) (nth 2 case)))))))
+
+(ert-deftest query-replace-tests ()
+ (query-replace--run-tests query-replace-tests))
+
+(ert-deftest query-replace-search-function-tests ()
+ (let* ((replace-re-search-function #'re-search-forward))
+ (query-replace--run-tests query-replace-tests))
+
+ (let* ((pairs '((1 . 2) (3 . 4)))
+ (replace-re-search-function
+ (lambda (string &optional _bound noerror count)
+ (let (found)
+ (while (and (not found) pairs)
+ (goto-char (caar pairs))
+ (when (re-search-forward string (cdar pairs) noerror count)
+ (setq found t))
+ (pop pairs))
+ found)))
+ (tests
+ '(
+ ;; FIXME: this test should pass after fixing bug#54733:
+ ;; ("aaaa" "C-M-% .* RET 1 RET !" "1a1a")
+ )))
+ (query-replace--run-tests tests)))
+
+
+;;; General tests for `perform-replace'.
+
+(defconst perform-replace-tests
+ '(
+ ;; Test case from commit 5632eb272c7
+ ("a a a " "\\ba " "c" nil t nil nil nil nil nil nil nil "ccc") ; not "ca c"
+ ;; The same with region inside the second match
+ ;; FIXME: this test should pass after fixing bug#54733:
+ ;; ("a a a " "\\ba " "c" nil t nil nil nil 1 4 nil nil "ca a ")
+ ))
+
+(defun perform-replace--run-tests (tests)
+ (with-temp-buffer
+ (dolist (case tests)
+ (delete-region (point-min) (point-max))
+ (insert (pop case))
+ (goto-char (point-min))
+ (apply 'perform-replace (butlast case))
+ (should (equal (buffer-string) (car (last case)))))))
+
+(ert-deftest perform-replace-tests ()
+ (perform-replace--run-tests perform-replace-tests))
+
+
;;; Tests for `query-replace' undo feature.
(defvar replace-tests-bind-read-string nil
@@ -599,11 +695,12 @@ bound to HIGHLIGHT-LOCUS."
(with-temp-buffer
(insert before)
(goto-char (point-min))
- (replace-regexp
- "\\(\\(L\\)\\|\\(R\\)\\)"
- '(replace-eval-replacement
- replace-quote
- (if (match-string 2) "R" "L")))
+ (with-suppressed-warnings ((interactive-only replace-regexp))
+ (replace-regexp
+ "\\(\\(L\\)\\|\\(R\\)\\)"
+ '(replace-eval-replacement
+ replace-quote
+ (if (match-string 2) "R" "L"))))
(should (equal (buffer-string) after)))))
(ert-deftest test-count-matches ()
diff --git a/test/lisp/saveplace-tests.el b/test/lisp/saveplace-tests.el
index 24cd5be5f5b..6f66f3fa345 100644
--- a/test/lisp/saveplace-tests.el
+++ b/test/lisp/saveplace-tests.el
@@ -41,49 +41,42 @@
(ert-deftest saveplace-test-save-place-to-alist/file ()
(save-place-mode)
- (let* ((tmpfile (make-temp-file "emacs-test-saveplace-"))
- (tmpfile (file-truename tmpfile))
- (save-place-alist nil)
- (save-place-loaded t)
- (loc tmpfile)
- (pos 4))
- (unwind-protect
- (save-window-excursion
- (find-file loc)
- (insert "abc") ; must insert something
- (save-place-to-alist)
- (should (equal save-place-alist (list (cons tmpfile pos)))))
- (delete-file tmpfile))))
+ (ert-with-temp-file tmpfile
+ (let* ((tmpfile (file-truename tmpfile))
+ (save-place-alist nil)
+ (save-place-loaded t)
+ (loc tmpfile)
+ (pos 4))
+ (save-window-excursion
+ (find-file loc)
+ (insert "abc") ; must insert something
+ (save-place-to-alist)
+ (should (equal save-place-alist (list (cons tmpfile pos))))))))
(ert-deftest saveplace-test-forget-unreadable-files ()
(save-place-mode)
- (let* ((save-place-loaded t)
- (tmpfile (make-temp-file "emacs-test-saveplace-"))
- (alist-orig (list (cons "/this/file/does/not/exist" 10)
- (cons tmpfile 1917)))
- (save-place-alist alist-orig))
- (unwind-protect
- (progn
- (save-place-forget-unreadable-files)
- (should (equal save-place-alist (cdr alist-orig))))
- (delete-file tmpfile))))
+ (ert-with-temp-file tmpfile
+ :suffix "-saveplace"
+ (let* ((save-place-loaded t)
+ (alist-orig (list (cons "/this/file/does/not/exist" 10)
+ (cons tmpfile 1917)))
+ (save-place-alist alist-orig))
+ (save-place-forget-unreadable-files)
+ (should (equal save-place-alist (cdr alist-orig))))))
(ert-deftest saveplace-test-place-alist-to-file ()
(save-place-mode)
- (let* ((tmpfile (make-temp-file "emacs-test-saveplace-"))
- (tmpfile2 (make-temp-file "emacs-test-saveplace-"))
- (save-place-file tmpfile)
- (save-place-alist (list (cons tmpfile2 99))))
- (unwind-protect
- (progn (save-place-alist-to-file)
- (setq save-place-alist nil)
- (save-window-excursion
- (find-file save-place-file)
- (unwind-protect
- (should (string-match tmpfile2 (buffer-string)))
- (kill-buffer))))
- (delete-file tmpfile)
- (delete-file tmpfile2))))
+ (ert-with-temp-file tmpfile
+ (ert-with-temp-file tmpfile2
+ (let* ((save-place-file tmpfile)
+ (save-place-alist (list (cons tmpfile2 99))))
+ (save-place-alist-to-file)
+ (setq save-place-alist nil)
+ (save-window-excursion
+ (find-file save-place-file)
+ (unwind-protect
+ (should (string-match tmpfile2 (buffer-string)))
+ (kill-buffer)))))))
(ert-deftest saveplace-test-load-alist-from-file ()
(save-place-mode)
diff --git a/test/lisp/ses-tests.el b/test/lisp/ses-tests.el
index 3fcb4ffa180..ea3f9d05d70 100644
--- a/test/lisp/ses-tests.el
+++ b/test/lisp/ses-tests.el
@@ -22,8 +22,24 @@
;;; Code:
(require 'ert)
+(eval-when-compile (require 'ert-x))
(require 'ses)
+;; Silence byte-compiler.
+(with-suppressed-warnings ((lexical ses--cells)
+ (lexical A2)
+ (lexical A3)
+ (lexical ses--foo)
+ (lexical ses--bar)
+ (lexical B2)
+ (lexical ses--toto))
+ (defvar ses--cells)
+ (defvar A2)
+ (defvar A3)
+ (defvar ses--foo)
+ (defvar ses--bar)
+ (defvar B2)
+ (defvar ses--toto))
;; PLAIN FORMULA TESTS
;; ======================================================================
@@ -54,9 +70,6 @@ equal to 2. This is done using interactive calls."
;; PLAIN CELL RENAMING TESTS
;; ======================================================================
-(defvar ses--foo)
-(defvar ses--cells)
-
(ert-deftest ses-tests-lowlevel-renamed-cell ()
"Check that renaming A1 to `ses--foo' and setting `ses--foo' to 1 and A2 to (1+ ses--foo), makes A2 value equal to 2.
This is done using low level functions, `ses-rename-cell' is not
@@ -150,7 +163,6 @@ to A2 and inserting a row, makes A2 value empty, and A3 equal to
(should-not (bound-and-true-p A2))
(should (eq (bound-and-true-p A3) 2)))))
-(defvar ses--bar)
(ert-deftest ses-tests-renamed-cells-row-insertion ()
"Check that setting A1 to 1 and A2 to (1+ A1), and then renaming A1 to `ses--foo' and A2 to `ses--bar' jumping
@@ -174,6 +186,61 @@ to `ses--bar' and inserting a row, makes A2 value empty, and `ses--bar' equal to
(should (eq ses--bar 2)))))
+;; JUMP tests
+;; ======================================================================
+(ert-deftest ses-jump-B2-prefix-arg ()
+ "Test jumping to cell B2 by use of prefix argument"
+ (let ((ses-initial-size '(3 . 3))
+ ses-after-entry-functions)
+ (with-temp-buffer
+ (ses-mode)
+ ;; C-u 4 M-x ses-jump
+ (let ((current-prefix-arg 4))
+ (call-interactively 'ses-jump))
+ (should (eq (ses--cell-at-pos (point)) 'B2)))))
+
+
+(ert-deftest ses-jump-B2-lowcase ()
+ "Test jumping to cell B2 by use of lowcase cell name string"
+ (let ((ses-initial-size '(3 . 3))
+ ses-after-entry-functions)
+ (with-temp-buffer
+ (ses-mode)
+ (funcall-interactively 'ses-jump "b2")
+ (ses-command-hook)
+ (should (eq (ses--cell-at-pos (point)) 'B2)))))
+
+(ert-deftest ses-jump-B2-lowcase-keys ()
+ "Test jumping to cell B2 by use of lowcase cell name string with simulating keys"
+ (let ((ses-initial-size '(3 . 3))
+ ses-after-entry-functions)
+ (with-temp-buffer
+ (ses-mode)
+ (ert-simulate-keys [ ?b ?2 return] (ses-jump))
+ (ses-command-hook)
+ (should (eq (ses--cell-at-pos (point)) 'B2)))))
+
+(ert-deftest ses-jump-B2-symbol ()
+ "Test jumping to cell B2 by use of cell name symbol"
+ (let ((ses-initial-size '(3 . 3))
+ ses-after-entry-functions)
+ (with-temp-buffer
+ (ses-mode)
+ (funcall-interactively 'ses-jump 'B2)
+ (ses-command-hook)
+ (should (eq (ses--cell-at-pos (point)) 'B2)))))
+
+(ert-deftest ses-jump-B2-renamed ()
+ "Test jumping to cell B2 after renaming it `ses--toto'."
+ (let ((ses-initial-size '(3 . 3))
+ ses-after-entry-functions)
+ (with-temp-buffer
+ (ses-mode)
+ (ses-rename-cell 'ses--toto (ses-get-cell 1 1))
+ (ses-jump 'ses--toto)
+ (ses-command-hook)
+ (should (eq (ses--cell-at-pos (point)) 'ses--toto)))))
+
(provide 'ses-tests)
;;; ses-tests.el ends here
diff --git a/test/lisp/shadowfile-tests.el b/test/lisp/shadowfile-tests.el
index 46ab34535d4..0916f7ce688 100644
--- a/test/lisp/shadowfile-tests.el
+++ b/test/lisp/shadowfile-tests.el
@@ -37,37 +37,9 @@
;;; Code:
-(require 'ert)
-(require 'shadowfile)
(require 'tramp)
-
-;; There is no default value on w32 systems, which could work out of the box.
-(defconst shadow-test-remote-temporary-file-directory
- (cond
- ((getenv "REMOTE_TEMPORARY_FILE_DIRECTORY"))
- ((eq system-type 'windows-nt) null-device)
- (t (add-to-list
- 'tramp-methods
- '("mock"
- (tramp-login-program "sh")
- (tramp-login-args (("-i")))
- (tramp-remote-shell "/bin/sh")
- (tramp-remote-shell-args ("-c"))
- (tramp-connection-timeout 10)))
- (add-to-list
- 'tramp-default-host-alist
- `("\\`mock\\'" nil ,(system-name)))
- ;; Emacs' Makefile sets $HOME to a nonexistent value. Needed in
- ;; batch mode only, therefore. `shadow-homedir' cannot be
- ;; `temporary-directory', because the tests with "~" would fail.
- (unless (and (null noninteractive) (file-directory-p "~/"))
- (setenv "HOME" (file-name-unquote temporary-file-directory))
- (setq shadow-homedir invocation-directory)
- (add-to-list
- 'tramp-connection-properties
- `(,(file-remote-p "/mock::") "~" ,invocation-directory)))
- (format "/mock::%s" temporary-file-directory)))
- "Temporary directory for Tramp tests.")
+(require 'ert-x)
+(require 'shadowfile)
(setq auth-source-save-behavior nil
password-cache-expiry nil
@@ -80,13 +52,8 @@
tramp-verbose 0
;; On macOS, `temporary-file-directory' is a symlinked directory.
temporary-file-directory (file-truename temporary-file-directory)
- shadow-test-remote-temporary-file-directory
- (ignore-errors
- (file-truename shadow-test-remote-temporary-file-directory)))
-
-;; This should happen on hydra only.
-(when (getenv "EMACS_HYDRA_CI")
- (add-to-list 'tramp-remote-path 'tramp-own-remote-path))
+ ert-remote-temporary-file-directory
+ (ignore-errors (file-truename ert-remote-temporary-file-directory)))
(defconst shadow-test-info-file
(expand-file-name "shadows_test" temporary-file-directory)
@@ -100,7 +67,7 @@
"Reset all `shadowfile' internals."
;; Cleanup Tramp.
(tramp-cleanup-connection
- (tramp-dissect-file-name shadow-test-remote-temporary-file-directory) t t)
+ (tramp-dissect-file-name ert-remote-temporary-file-directory) t t)
;; Delete auto-saved files.
(with-current-buffer (find-file-noselect shadow-info-file 'nowarn)
(ignore-errors (delete-file (make-auto-save-file-name)))
@@ -135,7 +102,7 @@ a cluster (or site). This is not tested here; it must be
guaranteed by the originator of a cluster definition."
:tags '(:expensive-test)
(skip-unless (not (memq system-type '(windows-nt ms-dos))))
- (skip-unless (file-remote-p shadow-test-remote-temporary-file-directory))
+ (skip-unless (file-remote-p ert-remote-temporary-file-directory))
(let ((text-quoting-style 'grave) ;; We inspect the *Messages* buffer!
(inhibit-message t)
@@ -222,8 +189,7 @@ guaranteed by the originator of a cluster definition."
(shadow-cluster-regexp (shadow-get-cluster cluster)) regexp))
;; Redefine the cluster.
- (setq primary
- (file-remote-p shadow-test-remote-temporary-file-directory)
+ (setq primary (file-remote-p ert-remote-temporary-file-directory)
regexp (shadow-regexp-superquote primary)
mocked-input `(,cluster ,primary ,regexp))
(call-interactively #'shadow-define-cluster)
@@ -254,7 +220,7 @@ Per definition, all files are identical on the different hosts of
a cluster (or site). This is not tested here; it must be
guaranteed by the originator of a cluster definition."
(skip-unless (not (memq system-type '(windows-nt ms-dos))))
- (skip-unless (file-remote-p shadow-test-remote-temporary-file-directory))
+ (skip-unless (file-remote-p ert-remote-temporary-file-directory))
(let ((shadow-info-file shadow-test-info-file)
(shadow-todo-file shadow-test-todo-file)
@@ -286,14 +252,14 @@ guaranteed by the originator of a cluster definition."
(should (string-equal (system-name) (shadow-site-name primary1)))
(should
(string-equal
- (file-remote-p shadow-test-remote-temporary-file-directory)
+ (file-remote-p ert-remote-temporary-file-directory)
(shadow-name-site
- (file-remote-p shadow-test-remote-temporary-file-directory))))
+ (file-remote-p ert-remote-temporary-file-directory))))
(should
(string-equal
- (file-remote-p shadow-test-remote-temporary-file-directory)
+ (file-remote-p ert-remote-temporary-file-directory)
(shadow-site-name
- (file-remote-p shadow-test-remote-temporary-file-directory))))
+ (file-remote-p ert-remote-temporary-file-directory))))
(should (equal (shadow-site-cluster cluster1)
(shadow-get-cluster cluster1)))
@@ -324,8 +290,7 @@ guaranteed by the originator of a cluster definition."
;; Define a second cluster.
(setq cluster2 "cluster2"
- primary2
- (file-remote-p shadow-test-remote-temporary-file-directory)
+ primary2 (file-remote-p ert-remote-temporary-file-directory)
regexp2 (format "^\\(%s\\|%s\\)$" shadow-system-name primary2))
(shadow-set-cluster cluster2 primary2 regexp2)
@@ -356,7 +321,7 @@ guaranteed by the originator of a cluster definition."
(ert-deftest shadow-test02-files ()
"Check file manipulation functions."
(skip-unless (not (memq system-type '(windows-nt ms-dos))))
- (skip-unless (file-remote-p shadow-test-remote-temporary-file-directory))
+ (skip-unless (file-remote-p ert-remote-temporary-file-directory))
(let ((shadow-info-file shadow-test-info-file)
(shadow-todo-file shadow-test-todo-file)
@@ -398,8 +363,7 @@ guaranteed by the originator of a cluster definition."
(string-equal (shadow-local-file (concat primary file)) file))
;; Redefine the cluster.
- (setq primary
- (file-remote-p shadow-test-remote-temporary-file-directory)
+ (setq primary (file-remote-p ert-remote-temporary-file-directory)
regexp (shadow-regexp-superquote primary))
(shadow-set-cluster cluster primary regexp)
@@ -428,7 +392,7 @@ guaranteed by the originator of a cluster definition."
(ert-deftest shadow-test03-expand-cluster-in-file-name ()
"Check canonical file name of a cluster or site."
(skip-unless (not (memq system-type '(windows-nt ms-dos))))
- (skip-unless (file-remote-p shadow-test-remote-temporary-file-directory))
+ (skip-unless (file-remote-p ert-remote-temporary-file-directory))
(let ((shadow-info-file shadow-test-info-file)
(shadow-todo-file shadow-test-todo-file)
@@ -453,8 +417,7 @@ guaranteed by the originator of a cluster definition."
file2
(make-temp-name
(expand-file-name
- "shadowfile-tests"
- shadow-test-remote-temporary-file-directory)))
+ "shadowfile-tests" ert-remote-temporary-file-directory)))
;; A local file name is kept.
(should
@@ -473,8 +436,7 @@ guaranteed by the originator of a cluster definition."
(shadow-expand-cluster-in-file-name (concat primary file1)) file1))
;; Redefine the cluster.
- (setq primary
- (file-remote-p shadow-test-remote-temporary-file-directory)
+ (setq primary (file-remote-p ert-remote-temporary-file-directory)
regexp (shadow-regexp-superquote primary))
(shadow-set-cluster cluster primary regexp)
@@ -495,7 +457,7 @@ guaranteed by the originator of a cluster definition."
(ert-deftest shadow-test04-contract-file-name ()
"Check canonical file name of a cluster or site."
(skip-unless (not (memq system-type '(windows-nt ms-dos))))
- (skip-unless (file-remote-p shadow-test-remote-temporary-file-directory))
+ (skip-unless (file-remote-p ert-remote-temporary-file-directory))
(let ((shadow-info-file shadow-test-info-file)
(shadow-todo-file shadow-test-todo-file)
@@ -533,8 +495,7 @@ guaranteed by the originator of a cluster definition."
(concat "/cluster:" file)))
;; Redefine the cluster.
- (setq primary
- (file-remote-p shadow-test-remote-temporary-file-directory)
+ (setq primary (file-remote-p ert-remote-temporary-file-directory)
regexp (shadow-regexp-superquote primary))
(shadow-set-cluster cluster primary regexp)
@@ -542,8 +503,7 @@ guaranteed by the originator of a cluster definition."
(should
(string-equal
(shadow-contract-file-name
- (concat
- (file-remote-p shadow-test-remote-temporary-file-directory) file))
+ (concat (file-remote-p ert-remote-temporary-file-directory) file))
(concat "/cluster:" file))))
;; Cleanup.
@@ -552,7 +512,7 @@ guaranteed by the originator of a cluster definition."
(ert-deftest shadow-test05-file-match ()
"Check `shadow-same-site' and `shadow-file-match'."
(skip-unless (not (memq system-type '(windows-nt ms-dos))))
- (skip-unless (file-remote-p shadow-test-remote-temporary-file-directory))
+ (skip-unless (file-remote-p ert-remote-temporary-file-directory))
(let ((shadow-info-file shadow-test-info-file)
(shadow-todo-file shadow-test-todo-file)
@@ -588,17 +548,14 @@ guaranteed by the originator of a cluster definition."
(should (shadow-file-match (shadow-parse-name file) file))
;; Redefine the cluster.
- (setq primary
- (file-remote-p shadow-test-remote-temporary-file-directory)
+ (setq primary (file-remote-p ert-remote-temporary-file-directory)
regexp (shadow-regexp-superquote primary))
(shadow-set-cluster cluster primary regexp)
(should
(shadow-file-match
(shadow-parse-name
- (concat
- (file-remote-p shadow-test-remote-temporary-file-directory)
- file))
+ (concat (file-remote-p ert-remote-temporary-file-directory) file))
file)))
;; Cleanup.
@@ -607,7 +564,7 @@ guaranteed by the originator of a cluster definition."
(ert-deftest shadow-test06-literal-groups ()
"Check literal group definitions."
(skip-unless (not (memq system-type '(windows-nt ms-dos))))
- (skip-unless (file-remote-p shadow-test-remote-temporary-file-directory))
+ (skip-unless (file-remote-p ert-remote-temporary-file-directory))
(let ((shadow-info-file shadow-test-info-file)
(shadow-todo-file shadow-test-todo-file)
@@ -632,8 +589,7 @@ guaranteed by the originator of a cluster definition."
(shadow-set-cluster cluster1 primary regexp)
(setq cluster2 "cluster2"
- primary
- (file-remote-p shadow-test-remote-temporary-file-directory)
+ primary (file-remote-p ert-remote-temporary-file-directory)
regexp (format "^\\(%s\\|%s\\)$" shadow-system-name primary))
(shadow-set-cluster cluster2 primary regexp)
@@ -644,8 +600,7 @@ guaranteed by the originator of a cluster definition."
file2
(make-temp-name
(expand-file-name
- "shadowfile-tests"
- shadow-test-remote-temporary-file-directory))
+ "shadowfile-tests" ert-remote-temporary-file-directory))
mocked-input
`(,cluster1 ,file1 ,cluster2 ,file2
,primary ,file1 ,(kbd "RET")))
@@ -694,7 +649,7 @@ guaranteed by the originator of a cluster definition."
(ert-deftest shadow-test07-regexp-groups ()
"Check regexp group definitions."
(skip-unless (not (memq system-type '(windows-nt ms-dos))))
- (skip-unless (file-remote-p shadow-test-remote-temporary-file-directory))
+ (skip-unless (file-remote-p ert-remote-temporary-file-directory))
(let ((shadow-info-file shadow-test-info-file)
(shadow-todo-file shadow-test-todo-file)
@@ -719,8 +674,7 @@ guaranteed by the originator of a cluster definition."
(shadow-set-cluster cluster1 primary regexp)
(setq cluster2 "cluster2"
- primary
- (file-remote-p shadow-test-remote-temporary-file-directory)
+ primary (file-remote-p ert-remote-temporary-file-directory)
regexp (format "^\\(%s\\|%s\\)$" shadow-system-name primary))
(shadow-set-cluster cluster2 primary regexp)
@@ -757,8 +711,8 @@ guaranteed by the originator of a cluster definition."
(ert-deftest shadow-test08-shadow-todo ()
"Check that needed shadows are added to todo."
(skip-unless (not (memq system-type '(windows-nt ms-dos))))
- (skip-unless (file-remote-p shadow-test-remote-temporary-file-directory))
- (skip-unless (file-writable-p shadow-test-remote-temporary-file-directory))
+ (skip-unless (file-remote-p ert-remote-temporary-file-directory))
+ (skip-unless (file-writable-p ert-remote-temporary-file-directory))
(let ((backup-inhibited t)
create-lockfiles
@@ -778,7 +732,7 @@ guaranteed by the originator of a cluster definition."
(message
"%s %s %s %s %s"
temporary-file-directory
- shadow-test-remote-temporary-file-directory
+ ert-remote-temporary-file-directory
shadow-homedir shadow-info-file shadow-todo-file))
;; Define clusters.
@@ -792,8 +746,7 @@ guaranteed by the originator of a cluster definition."
cluster1 primary regexp shadow-clusters))
(setq cluster2 "cluster2"
- primary
- (file-remote-p shadow-test-remote-temporary-file-directory)
+ primary (file-remote-p ert-remote-temporary-file-directory)
regexp (shadow-regexp-superquote primary))
(shadow-set-cluster cluster2 primary regexp)
(when shadow-debug
@@ -903,8 +856,8 @@ guaranteed by the originator of a cluster definition."
"Check that needed shadow files are copied."
:tags '(:expensive-test)
(skip-unless (not (memq system-type '(windows-nt ms-dos))))
- (skip-unless (file-remote-p shadow-test-remote-temporary-file-directory))
- (skip-unless (file-writable-p shadow-test-remote-temporary-file-directory))
+ (skip-unless (file-remote-p ert-remote-temporary-file-directory))
+ (skip-unless (file-writable-p ert-remote-temporary-file-directory))
(let ((backup-inhibited t)
create-lockfiles
@@ -928,8 +881,7 @@ guaranteed by the originator of a cluster definition."
(shadow-set-cluster cluster1 primary regexp)
(setq cluster2 "cluster2"
- primary
- (file-remote-p shadow-test-remote-temporary-file-directory)
+ primary (file-remote-p ert-remote-temporary-file-directory)
regexp (shadow-regexp-superquote primary))
(shadow-set-cluster cluster2 primary regexp)
diff --git a/test/lisp/simple-tests.el b/test/lisp/simple-tests.el
index 6350bebeeea..b4576889dcd 100644
--- a/test/lisp/simple-tests.el
+++ b/test/lisp/simple-tests.el
@@ -966,10 +966,65 @@ See Bug#21722."
(setq buffer-undo-list nil)
(downcase-word 1)
(should (= (length (delq nil (undo-make-selective-list 1 9))) 2))
- (should (= (length (delq nil (undo-make-selective-list 4 9))) 1))
- ;; FIXME this is the off-by-one error case.
+ ;; FIXME: These should give 0, but currently give 1.
+ ;;(should (= (length (delq nil (undo-make-selective-list 4 9))) 0))
;;(should (= (length (delq nil (undo-make-selective-list 5 9))) 0))
(should (= (length (delq nil (undo-make-selective-list 6 9))) 0))))
+(ert-deftest test-yank-in-context ()
+ (should
+ (equal
+ (with-temp-buffer
+ (sh-mode)
+ (insert "echo \"foo\"")
+ (kill-new "\"bar\"")
+ (goto-char 8)
+ (yank-in-context)
+ (buffer-string))
+ "echo \"f\\\"bar\\\"oo\""))
+
+ (should
+ (equal
+ (with-temp-buffer
+ (sh-mode)
+ (insert "echo \"foo\"")
+ (kill-new "'bar'")
+ (goto-char 8)
+ (yank-in-context)
+ (buffer-string))
+ "echo \"f'bar'oo\""))
+
+ (should
+ (equal
+ (with-temp-buffer
+ (sh-mode)
+ (insert "echo 'foo'")
+ (kill-new "'bar'")
+ (goto-char 8)
+ (yank-in-context)
+ (buffer-string))
+ "echo 'f'\\''bar'\\''oo'")))
+
+;;; Tests for `zap-to-char'
+
+(defmacro with-zap-to-char-test (original result &rest body)
+ (declare (indent 2) (debug (stringp stringp body)))
+ `(with-temp-buffer
+ (insert ,original)
+ (goto-char (point-min))
+ ,@body
+ (should (equal (buffer-string) ,result))))
+
+(ert-deftest simple-tests-zap-to-char ()
+ (with-zap-to-char-test "abcde" "de"
+ (zap-to-char 1 ?c))
+ (with-zap-to-char-test "abcde abc123" "123"
+ (zap-to-char 2 ?c))
+ (let ((case-fold-search t))
+ (with-zap-to-char-test "abcdeCXYZ" "deCXYZ"
+ (zap-to-char 1 ?C))
+ (with-zap-to-char-test "abcdeCXYZ" "XYZ"
+ (zap-to-char 1 ?C 'interactive))))
+
(provide 'simple-test)
;;; simple-tests.el ends here
diff --git a/test/lisp/so-long-tests/so-long-tests.el b/test/lisp/so-long-tests/so-long-tests.el
index 670ab52cef6..bf619f453d2 100644
--- a/test/lisp/so-long-tests/so-long-tests.el
+++ b/test/lisp/so-long-tests/so-long-tests.el
@@ -32,7 +32,7 @@
;; Running manually:
;;
;; for test in lisp/so-long-tests/*-tests.el; do make ${test%.el}; done \
-;; 2>&1 | egrep -v '^(Loading|Source file|make|Changed to so-long-mode)'
+;; 2>&1 | grep -E -v '^(Loading|Source file|make|Changed to so-long-mode)'
;;
;; Which is equivalent to:
;;
@@ -41,7 +41,7 @@
;; "../src/emacs" --no-init-file --no-site-file --no-site-lisp \
;; -L ":." -l ert -l "$test" --batch --eval \
;; '(ert-run-tests-batch-and-exit (quote (not (tag :unstable))))'; \
-;; done 2>&1 | egrep -v '^(Loading|Source file|Changed to so-long-mode)'
+;; done 2>&1 | grep -E -v '^(Loading|Source file|Changed to so-long-mode)'
;;
;; See also `ert-run-tests-batch-and-exit'.
diff --git a/test/lisp/so-long-tests/spelling-tests.el b/test/lisp/so-long-tests/spelling-tests.el
index 14136cd4607..7bd06395535 100644
--- a/test/lisp/so-long-tests/spelling-tests.el
+++ b/test/lisp/so-long-tests/spelling-tests.el
@@ -23,6 +23,7 @@
;;; Code:
(require 'ert)
+(require 'ert-x)
(require 'ispell)
(require 'cl-lib)
@@ -35,12 +36,11 @@
;; make lisp/so-long-tests/spelling-tests SELECTOR=t
;; Only define the test if spell-checking is possible.
-(when (and ispell-program-name
- (executable-find ispell-program-name)
- (condition-case ()
- (progn (ispell-check-version) t)
- (error nil))
- (member "british" (ispell-valid-dictionary-list)))
+(when (ignore-errors
+ (and ispell-program-name
+ (executable-find ispell-program-name)
+ (progn (ispell-check-version) t)
+ (member "british" (ispell-valid-dictionary-list))))
(ert-deftest so-long-spelling ()
"Check the spelling in the source code."
:tags '(:unstable) ;; It works for me, but I'm not sure about others.
@@ -50,20 +50,20 @@
;; The Emacs test Makefile's use of HOME=/nonexistent triggers an error
;; when starting the inferior ispell process, so we set HOME to a valid
;; (but empty) temporary directory for this test.
- (let* ((tmpdir (make-temp-file "so-long." :dir ".ispell"))
- (process-environment (cons (format "HOME=%s" tmpdir)
- process-environment))
- (find-spelling-mistake
- (unwind-protect
- (cl-letf (((symbol-function 'ispell-command-loop)
- (lambda (_miss _guess word _start _end)
- (message "Unrecognized word: %s." word)
- (throw 'mistake t))))
- (catch 'mistake
- (find-library "so-long")
- (ispell-buffer)
- nil))
- (delete-directory tmpdir))))
- (should (not find-spelling-mistake)))))
+ (ert-with-temp-directory tmpdir
+ :prefix "so-long."
+ :suffix ".ispell"
+ (let* ((process-environment (cons (format "HOME=%s" tmpdir)
+ process-environment))
+ (find-spelling-mistake
+ (cl-letf (((symbol-function 'ispell-command-loop)
+ (lambda (_miss _guess word _start _end)
+ (message "Unrecognized word: %s." word)
+ (throw 'mistake t))))
+ (catch 'mistake
+ (find-library "so-long")
+ (ispell-buffer)
+ nil))))
+ (should (not find-spelling-mistake))))))
;;; spelling-tests.el ends here
diff --git a/test/lisp/subr-tests.el b/test/lisp/subr-tests.el
index dde501d520c..ced2bc5c4e5 100644
--- a/test/lisp/subr-tests.el
+++ b/test/lisp/subr-tests.el
@@ -84,16 +84,237 @@
;;;; Keymap support.
(ert-deftest subr-test-kbd ()
+ (should (equal (kbd "") ""))
(should (equal (kbd "f") "f"))
+ (should (equal (kbd "X") "X"))
+ (should (equal (kbd "foobar") "foobar")) ; 6 characters
+ (should (equal (kbd "return") "return")) ; 6 characters
+
+ (should (equal (kbd "<F2>") [F2]))
+ (should (equal (kbd "<f1> <f2> TAB") [f1 f2 ?\t]))
+ (should (equal (kbd "<f1> RET") [f1 ?\r]))
+ (should (equal (kbd "<f1> SPC") [f1 ? ]))
(should (equal (kbd "<f1>") [f1]))
- (should (equal (kbd "RET") "\C-m"))
+ (should (equal (kbd "<f1>") [f1]))
+ (should (equal (kbd "[f1]") "[f1]"))
+ (should (equal (kbd "<return>") [return]))
+ (should (equal (kbd "< right >") "<right>")) ; 7 characters
+
+ ;; Modifiers:
+ (should (equal (kbd "C-x") "\C-x"))
(should (equal (kbd "C-x a") "\C-xa"))
- ;; Check that kbd handles both new and old style key descriptions
- ;; (bug#45536).
+ (should (equal (kbd "C-;") [?\C-\;]))
+ (should (equal (kbd "C-a") "\C-a"))
+ (should (equal (kbd "C-c SPC") "\C-c "))
+ (should (equal (kbd "C-c TAB") "\C-c\t"))
+ (should (equal (kbd "C-c c") "\C-cc"))
+ (should (equal (kbd "C-x 4 C-f") "\C-x4\C-f"))
+ (should (equal (kbd "C-x C-f") "\C-x\C-f"))
+ (should (equal (kbd "C-M-<down>") [C-M-down]))
+ (should (equal (kbd "<C-M-down>") [C-M-down]))
+ (should (equal (kbd "C-RET") [?\C-\r]))
+ (should (equal (kbd "C-SPC") [?\C- ]))
+ (should (equal (kbd "C-TAB") [?\C-\t]))
+ (should (equal (kbd "C-<down>") [C-down]))
+ (should (equal (kbd "C-c C-c C-c") "\C-c\C-c\C-c"))
+
+ (should (equal (kbd "M-a") [?\M-a]))
+ (should (equal (kbd "M-<DEL>") [?\M-\d]))
+ (should (equal (kbd "M-C-a") [?\M-\C-a]))
+ (should (equal (kbd "M-ESC") [?\M-\e]))
+ (should (equal (kbd "M-RET") [?\M-\r]))
+ (should (equal (kbd "M-SPC") [?\M- ]))
+ (should (equal (kbd "M-TAB") [?\M-\t]))
+ (should (equal (kbd "M-x a") [?\M-x ?a]))
+ (should (equal (kbd "M-<up>") [M-up]))
+ (should (equal (kbd "M-c M-c M-c") [?\M-c ?\M-c ?\M-c]))
+
+ (should (equal (kbd "s-SPC") [?\s- ]))
+ (should (equal (kbd "s-a") [?\s-a]))
+ (should (equal (kbd "s-x a") [?\s-x ?a]))
+ (should (equal (kbd "s-c s-c s-c") [?\s-c ?\s-c ?\s-c]))
+
+ (should (equal (kbd "S-H-a") [?\S-\H-a]))
+ (should (equal (kbd "S-a") [?\S-a]))
+ (should (equal (kbd "S-x a") [?\S-x ?a]))
+ (should (equal (kbd "S-c S-c S-c") [?\S-c ?\S-c ?\S-c]))
+
+ (should (equal (kbd "H-<RET>") [?\H-\r]))
+ (should (equal (kbd "H-DEL") [?\H-\d]))
+ (should (equal (kbd "H-a") [?\H-a]))
+ (should (equal (kbd "H-x a") [?\H-x ?a]))
+ (should (equal (kbd "H-c H-c H-c") [?\H-c ?\H-c ?\H-c]))
+
+ (should (equal (kbd "A-H-a") [?\A-\H-a]))
+ (should (equal (kbd "A-SPC") [?\A- ]))
+ (should (equal (kbd "A-TAB") [?\A-\t]))
+ (should (equal (kbd "A-a") [?\A-a]))
+ (should (equal (kbd "A-c A-c A-c") [?\A-c ?\A-c ?\A-c]))
+
+ (should (equal (kbd "C-M-a") [?\C-\M-a]))
+ (should (equal (kbd "C-M-<up>") [C-M-up]))
+
+ ;; Special characters.
+ (should (equal (kbd "DEL") "\d"))
+ (should (equal (kbd "ESC C-a") "\e\C-a"))
+ (should (equal (kbd "ESC") "\e"))
+ (should (equal (kbd "LFD") "\n"))
+ (should (equal (kbd "NUL") "\0"))
+ (should (equal (kbd "RET") "\C-m"))
+ (should (equal (kbd "SPC") "\s"))
+ (should (equal (kbd "TAB") "\t"))
+ (should (equal (kbd "\^i") ""))
+ (should (equal (kbd "^M") "\^M"))
+
+ ;; With numbers.
+ (should (equal (kbd "\177") "\^?"))
+ (should (equal (kbd "\000") "\0"))
+ (should (equal (kbd "\\177") "\^?"))
+ (should (equal (kbd "\\000") "\0"))
+ (should (equal (kbd "C-x \\150") "\C-xh"))
+
+ ;; Multibyte
+ (should (equal (kbd "ñ") [?ñ]))
+ (should (equal (kbd "ü") [?ü]))
+ (should (equal (kbd "ö") [?ö]))
+ (should (equal (kbd "ğ") [?ğ]))
+ (should (equal (kbd "ա") [?ա]))
+ (should (equal (kbd "üüöö") [?ü ?ü ?ö ?ö]))
+ (should (equal (kbd "C-ü") [?\C-ü]))
+ (should (equal (kbd "M-ü") [?\M-ü]))
+ (should (equal (kbd "H-ü") [?\H-ü]))
+
+ ;; Handle both new and old style key descriptions (bug#45536).
(should (equal (kbd "s-<return>") [s-return]))
(should (equal (kbd "<s-return>") [s-return]))
(should (equal (kbd "C-M-<return>") [C-M-return]))
- (should (equal (kbd "<C-M-return>") [C-M-return])))
+ (should (equal (kbd "<C-M-return>") [C-M-return]))
+
+ ;; Error.
+ (should-error (kbd "C-xx"))
+ (should-error (kbd "M-xx"))
+ (should-error (kbd "M-x<TAB>"))
+
+ ;; These should be equivalent:
+ (should (equal (kbd "\C-xf") (kbd "C-x f"))))
+
+(ert-deftest subr-test-key-valid-p ()
+ (should (not (key-valid-p "")))
+ (should (key-valid-p "f"))
+ (should (key-valid-p "X"))
+ (should (not (key-valid-p " X")))
+ (should (key-valid-p "X f"))
+ (should (not (key-valid-p "a b")))
+ (should (not (key-valid-p "foobar")))
+ (should (not (key-valid-p "return")))
+
+ (should (key-valid-p "<F2>"))
+ (should (key-valid-p "<f1> <f2> TAB"))
+ (should (key-valid-p "<f1> RET"))
+ (should (key-valid-p "<f1> SPC"))
+ (should (key-valid-p "<f1>"))
+ (should (not (key-valid-p "[f1]")))
+ (should (key-valid-p "<return>"))
+ (should (not (key-valid-p "< right >")))
+
+ ;; Modifiers:
+ (should (key-valid-p "C-x"))
+ (should (key-valid-p "C-x a"))
+ (should (key-valid-p "C-;"))
+ (should (key-valid-p "C-a"))
+ (should (key-valid-p "C-c SPC"))
+ (should (key-valid-p "C-c TAB"))
+ (should (key-valid-p "C-c c"))
+ (should (key-valid-p "C-x 4 C-f"))
+ (should (key-valid-p "C-x C-f"))
+ (should (key-valid-p "C-M-<down>"))
+ (should (not (key-valid-p "<C-M-down>")))
+ (should (key-valid-p "C-RET"))
+ (should (key-valid-p "C-SPC"))
+ (should (key-valid-p "C-TAB"))
+ (should (key-valid-p "C-<down>"))
+ (should (key-valid-p "C-c C-c C-c"))
+
+ (should (key-valid-p "M-a"))
+ (should (key-valid-p "M-<DEL>"))
+ (should (not (key-valid-p "M-C-a")))
+ (should (key-valid-p "C-M-a"))
+ (should (key-valid-p "M-ESC"))
+ (should (key-valid-p "M-RET"))
+ (should (key-valid-p "M-SPC"))
+ (should (key-valid-p "M-TAB"))
+ (should (key-valid-p "M-x a"))
+ (should (key-valid-p "M-<up>"))
+ (should (key-valid-p "M-c M-c M-c"))
+
+ (should (key-valid-p "s-SPC"))
+ (should (key-valid-p "s-a"))
+ (should (key-valid-p "s-x a"))
+ (should (key-valid-p "s-c s-c s-c"))
+
+ (should (not (key-valid-p "S-H-a")))
+ (should (key-valid-p "S-a"))
+ (should (key-valid-p "S-x a"))
+ (should (key-valid-p "S-c S-c S-c"))
+
+ (should (key-valid-p "H-<RET>"))
+ (should (key-valid-p "H-DEL"))
+ (should (key-valid-p "H-a"))
+ (should (key-valid-p "H-x a"))
+ (should (key-valid-p "H-c H-c H-c"))
+
+ (should (key-valid-p "A-H-a"))
+ (should (key-valid-p "A-SPC"))
+ (should (key-valid-p "A-TAB"))
+ (should (key-valid-p "A-a"))
+ (should (key-valid-p "A-c A-c A-c"))
+
+ (should (key-valid-p "C-M-a"))
+ (should (key-valid-p "C-M-<up>"))
+
+ ;; Special characters.
+ (should (key-valid-p "DEL"))
+ (should (key-valid-p "ESC C-a"))
+ (should (key-valid-p "ESC"))
+ (should (key-valid-p "LFD"))
+ (should (key-valid-p "NUL"))
+ (should (key-valid-p "RET"))
+ (should (key-valid-p "SPC"))
+ (should (key-valid-p "TAB"))
+ (should (not (key-valid-p "\^i")))
+ (should (not (key-valid-p "^M")))
+
+ ;; With numbers.
+ (should (not (key-valid-p "\177")))
+ (should (not (key-valid-p "\000")))
+ (should (not (key-valid-p "\\177")))
+ (should (not (key-valid-p "\\000")))
+ (should (not (key-valid-p "C-x \\150")))
+
+ ;; Multibyte
+ (should (key-valid-p "ñ"))
+ (should (key-valid-p "ü"))
+ (should (key-valid-p "ö"))
+ (should (key-valid-p "ğ"))
+ (should (key-valid-p "ա"))
+ (should (not (key-valid-p "üüöö")))
+ (should (key-valid-p "C-ü"))
+ (should (key-valid-p "M-ü"))
+ (should (key-valid-p "H-ü"))
+
+ ;; Handle both new and old style key descriptions (bug#45536).
+ (should (key-valid-p "s-<return>"))
+ (should (not (key-valid-p "<s-return>")))
+ (should (key-valid-p "C-M-<return>"))
+ (should (not (key-valid-p "<C-M-return>")))
+
+ (should (key-valid-p "<mouse-1>"))
+ (should (key-valid-p "<Scroll_Lock>"))
+
+ (should (not (key-valid-p "c-x")))
+ (should (not (key-valid-p "C-xx")))
+ (should (not (key-valid-p "M-xx")))
+ (should (not (key-valid-p "M-x<TAB>"))))
(ert-deftest subr-test-define-prefix-command ()
(define-prefix-command 'foo-prefix-map)
@@ -390,12 +611,13 @@ indirectly `mapbacktrace'."
(ert-deftest subr-tests--dolist--wrong-number-of-args ()
"Test that `dolist' doesn't accept wrong types or length of SPEC,
cf. Bug#25477."
- (should-error (eval '(dolist (a)))
- :type 'wrong-number-of-arguments)
- (should-error (eval '(dolist (a () 'result 'invalid)) t)
- :type 'wrong-number-of-arguments)
- (should-error (eval '(dolist "foo") t)
- :type 'wrong-type-argument))
+ (dolist (lb '(nil t))
+ (should-error (eval '(dolist (a)) lb)
+ :type 'wrong-number-of-arguments)
+ (should-error (eval '(dolist (a () 'result 'invalid)) lb)
+ :type 'wrong-number-of-arguments)
+ (should-error (eval '(dolist "foo") lb)
+ :type 'wrong-type-argument)))
(ert-deftest subr-tests-bug22027 ()
"Test for https://debbugs.gnu.org/22027 ."
@@ -704,6 +926,7 @@ See https://debbugs.gnu.org/cgi/bugreport.cgi?bug=19350."
(should-not (apropos-internal "^next-line$" #'keymapp)))
+(defvar test-global-boundp)
(ert-deftest test-buffer-local-boundp ()
(let ((buf (generate-new-buffer "boundp")))
(with-current-buffer buf
@@ -776,12 +999,96 @@ mode runs the hook ‘foo-bar-baz-very-long-name-indeed-mode-hook’, as the fin
or penultimate step during initialization."))
"In addition to any hooks its parent mode might have run, this mode
runs the hook ‘foo-bar-baz-very-long-name-indeed-mode-hook’, as the
-final or penultimate step during initialization.")))
+final or penultimate step during initialization."))
+ (should-error (internal--format-docstring-line "foo\nbar")))
(ert-deftest test-ensure-list ()
(should (equal (ensure-list nil) nil))
(should (equal (ensure-list :foo) '(:foo)))
(should (equal (ensure-list '(1 2 3)) '(1 2 3))))
+(ert-deftest test-alias-p ()
+ (should-not (function-alias-p 1))
+
+ (defun subr-tests--fun ())
+ (should-not (function-alias-p 'subr-tests--fun))
+
+ (defalias 'subr-tests--a 'subr-tests--b)
+ (defalias 'subr-tests--b 'subr-tests--c)
+ (should (equal (function-alias-p 'subr-tests--a)
+ '(subr-tests--b subr-tests--c)))
+
+ (defalias 'subr-tests--d 'subr-tests--e)
+ (defalias 'subr-tests--e 'subr-tests--d)
+ (should-error (function-alias-p 'subr-tests--d))
+ (should (equal (function-alias-p 'subr-tests--d t)
+ '(subr-tests--e))))
+
+(ert-deftest test-readablep ()
+ (should (readablep "foo"))
+ (should-not (readablep (list (make-marker)))))
+
+(ert-deftest test-string-lines ()
+ (should (equal (string-lines "") '("")))
+ (should (equal (string-lines "" t) '()))
+
+ (should (equal (string-lines "foo") '("foo")))
+ (should (equal (string-lines "foo\n") '("foo")))
+ (should (equal (string-lines "foo\nbar") '("foo" "bar")))
+
+ (should (equal (string-lines "foo" t) '("foo")))
+ (should (equal (string-lines "foo\n" t) '("foo")))
+ (should (equal (string-lines "foo\nbar" t) '("foo" "bar")))
+ (should (equal (string-lines "foo\n\n\nbar" t) '("foo" "bar")))
+
+ (should (equal (string-lines "foo" nil t) '("foo")))
+ (should (equal (string-lines "foo\n" nil t) '("foo\n")))
+ (should (equal (string-lines "foo\nbar" nil t) '("foo\n" "bar")))
+ (should (equal (string-lines "foo\n\n\nbar" nil t)
+ '("foo\n" "\n" "\n" "bar")))
+
+ (should (equal (string-lines "foo" t t) '("foo")))
+ (should (equal (string-lines "foo\n" t t) '("foo\n")))
+ (should (equal (string-lines "foo\nbar" t t) '("foo\n" "bar")))
+ (should (equal (string-lines "foo\n\n\nbar" t t)
+ '("foo\n" "bar"))))
+
+(ert-deftest test-keymap-parse-macros ()
+ (should (equal (key-parse "C-x ( C-d C-x )") [24 40 4 24 41]))
+ (should (equal (kbd "C-x ( C-d C-x )") ""))
+ (should (equal (kbd "C-x ( C-x )") "")))
+
+(defvar subr-test--global)
+(ert-deftest test-local-set-state ()
+ (setq subr-test--global 1)
+ (with-temp-buffer
+ (setq-local subr-test--local 2)
+ (let ((state (buffer-local-set-state subr-test--global 10
+ subr-test--local 20
+ subr-test--unexist 30)))
+ (should (= subr-test--global 10))
+ (should (= subr-test--local 20))
+ (should (= subr-test--unexist 30))
+ (buffer-local-restore-state state)
+ (should (= subr-test--global 1))
+ (should (= subr-test--local 2))
+ (should-not (boundp 'subr-test--unexist)))))
+
+(ert-deftest test-char-uppercase-p ()
+ "Tests for `char-uppercase-p'."
+ (dolist (c (list ?R ?S ?Ω ?Ψ))
+ (should (char-uppercase-p c)))
+ (dolist (c (list ?a ?b ?α ?β))
+ (should-not (char-uppercase-p c))))
+
+(ert-deftest test-plistp ()
+ (should (plistp nil))
+ (should-not (plistp 1))
+ (should (plistp '(1 2)))
+ (should-not (plistp '(1 . 2)))
+ (should (plistp '(1 2 3 4)))
+ (should-not (plistp '(1 2 3)))
+ (should-not (plistp '(1 2 3 . 4))))
+
(provide 'subr-tests)
;;; subr-tests.el ends here
diff --git a/test/lisp/tar-mode-tests.el b/test/lisp/tar-mode-tests.el
index 6dd16d18fd0..47c658eb9ad 100644
--- a/test/lisp/tar-mode-tests.el
+++ b/test/lisp/tar-mode-tests.el
@@ -32,7 +32,8 @@
(cons 1024 "-----S---")
(cons 2048 "--S------"))))
(dolist (x alist)
- (should (equal (cdr x) (tar-grind-file-mode (car x)))))))
+ (with-suppressed-warnings ((obsolete tar-grind-file-mode))
+ (should (equal (cdr x) (tar-grind-file-mode (car x))))))))
(ert-deftest tar-mode-test-tar-extract-gz ()
(skip-unless (executable-find "gzip"))
diff --git a/test/lisp/term-tests.el b/test/lisp/term-tests.el
index 90f682a580c..f60d2ff5747 100644
--- a/test/lisp/term-tests.el
+++ b/test/lisp/term-tests.el
@@ -42,36 +42,50 @@
`( :foreground "unspecified-fg"
:background ,(face-background 'term-color-bright-yellow nil 'default)
:inverse-video nil))
+(defvar custom-color-fg-props
+ `( :foreground "#87FFFF"
+ :background "unspecified-bg" :inverse-video nil))
(defvar ansi-test-strings
`(("\e[33mHello World\e[0m"
- ,(propertize "Hello World" 'font-lock-face yellow-fg-props))
+ ,(propertize "Hello World" 'font-lock-face `(,yellow-fg-props)))
("\e[43mHello World\e[0m"
- ,(propertize "Hello World" 'font-lock-face yellow-bg-props))
+ ,(propertize "Hello World" 'font-lock-face `(,yellow-bg-props)))
("\e[93mHello World\e[0m"
- ,(propertize "Hello World" 'font-lock-face bright-yellow-fg-props))
+ ,(propertize "Hello World" 'font-lock-face `(,bright-yellow-fg-props)))
("\e[103mHello World\e[0m"
- ,(propertize "Hello World" 'font-lock-face bright-yellow-bg-props))
+ ,(propertize "Hello World" 'font-lock-face `(,bright-yellow-bg-props)))
("\e[1;33mHello World\e[0m"
,(propertize "Hello World" 'font-lock-face
- `(,yellow-fg-props :inherit term-bold))
+ `(,yellow-fg-props term-bold))
,(propertize "Hello World" 'font-lock-face
- `(,bright-yellow-fg-props :inherit term-bold)))
+ `(,bright-yellow-fg-props term-bold)))
("\e[33;1mHello World\e[0m"
,(propertize "Hello World" 'font-lock-face
- `(,yellow-fg-props :inherit term-bold))
+ `(,yellow-fg-props term-bold))
,(propertize "Hello World" 'font-lock-face
- `(,bright-yellow-fg-props :inherit term-bold)))
+ `(,bright-yellow-fg-props term-bold)))
("\e[1m\e[33mHello World\e[0m"
,(propertize "Hello World" 'font-lock-face
- `(,yellow-fg-props :inherit term-bold))
+ `(,yellow-fg-props term-bold))
,(propertize "Hello World" 'font-lock-face
- `(,bright-yellow-fg-props :inherit term-bold)))
+ `(,bright-yellow-fg-props term-bold)))
("\e[33m\e[1mHello World\e[0m"
,(propertize "Hello World" 'font-lock-face
- `(,yellow-fg-props :inherit term-bold))
+ `(,yellow-fg-props term-bold))
+ ,(propertize "Hello World" 'font-lock-face
+ `(,bright-yellow-fg-props term-bold)))
+ ("\e[38;5;3;1mHello World\e[0m"
+ ,(propertize "Hello World" 'font-lock-face
+ `(,yellow-fg-props term-bold))
+ ,(propertize "Hello World" 'font-lock-face
+ `(,bright-yellow-fg-props term-bold)))
+ ("\e[38;5;123;1mHello World\e[0m"
+ ,(propertize "Hello World" 'font-lock-face
+ `(,custom-color-fg-props term-bold)))
+ ("\e[38;2;135;255;255;1mHello World\e[0m"
,(propertize "Hello World" 'font-lock-face
- `(,bright-yellow-fg-props :inherit term-bold)))))
+ `(,custom-color-fg-props term-bold)))))
(defun term-test-screen-from-input (width height input &optional return-var)
(with-temp-buffer
diff --git a/test/lisp/textmodes/css-mode-resources/css-selectors.txt b/test/lisp/textmodes/css-mode-resources/css-selectors.txt
new file mode 100644
index 00000000000..5b3d990f279
--- /dev/null
+++ b/test/lisp/textmodes/css-mode-resources/css-selectors.txt
@@ -0,0 +1,56 @@
+#firstname
+*
+p
+p.intro
+div, p
+div p
+div > p
+div + p
+p ~ ul
+[target]
+[target=_blank]
+[title~=flower]
+[lang|=en]
+a[href^="https"]
+a[href$=".pdf"]
+a[href*="w3schools"]
+a:active
+p::after
+p::before
+input:checked
+input:default
+input:disabled
+p:empty
+input:enabled
+p:first-child
+p::first-letter
+p::first-line
+p:first-of-type
+input:focus
+:fullscreen
+a:hover
+input:in-range
+input:indeterminate
+input:invalid
+p:lang(it)
+p:last-child
+p:last-of-type
+a:link
+::marker
+:not(p)
+p:nth-child(2)
+p:nth-last-child(2)
+p:nth-last-of-type(2)
+p:nth-of-type(2)
+p:only-of-type
+p:only-child
+input:optional
+input:out-of-range
+input:read-only
+input:read-write
+input:required
+:root
+::selection
+#news:target
+input:valid
+a:visited
diff --git a/test/lisp/textmodes/css-mode-resources/scss-selectors.txt b/test/lisp/textmodes/css-mode-resources/scss-selectors.txt
new file mode 100644
index 00000000000..3e05191a910
--- /dev/null
+++ b/test/lisp/textmodes/css-mode-resources/scss-selectors.txt
@@ -0,0 +1,10 @@
+p.#{$name} var
+p.#{$name}:active var
+p.#{$name}::after var
+f.#{$bar}::after p::after
+p.#{$name} f.#{$bar} k.var #{$bar} #{$bar}
+p.#{$name}
+&:hover
+> li
++ li
+~ li
diff --git a/test/lisp/textmodes/css-mode-tests.el b/test/lisp/textmodes/css-mode-tests.el
index 0ae1593508d..a746edf8944 100644
--- a/test/lisp/textmodes/css-mode-tests.el
+++ b/test/lisp/textmodes/css-mode-tests.el
@@ -419,5 +419,74 @@
(indent-region (point-min) (point-max))
(should (equal (buffer-string) orig)))))
+(ert-deftest css-mode-test-selectors ()
+ (let ((selectors
+ (with-temp-buffer
+ (insert-file-contents (ert-resource-file "css-selectors.txt"))
+ (string-lines (buffer-string)))))
+ (with-suppressed-warnings ((interactive-only font-lock-debug-fontify))
+ (dolist (selector selectors)
+ (with-temp-buffer
+ (css-mode)
+ (insert selector " {\n}\n")
+ (font-lock-debug-fontify)
+ (goto-char (point-min))
+ (unless (eq (get-text-property (point) 'face)
+ 'css-selector)
+ (should-not (format "Didn't recognize %s as a selector"
+ (buffer-substring-no-properties
+ (point) (line-end-position)))))))
+ ;; Test many selectors.
+ (dolist (selector selectors)
+ (with-temp-buffer
+ (css-mode)
+ (insert selector " ")
+ (dotimes (_ (random 5))
+ (insert (seq-random-elt '(" , " " > " " + "))
+ (seq-random-elt selectors)))
+ (insert "{\n}\n")
+ (font-lock-debug-fontify)
+ (goto-char (point-min))
+ (unless (eq (get-text-property (point) 'face)
+ 'css-selector)
+ (should-not (format "Didn't recognize %s as a selector"
+ (buffer-substring-no-properties
+ (point) (line-end-position)))))))
+ ;; Test wrong separators.
+ (dolist (selector selectors)
+ (with-temp-buffer
+ (css-mode)
+ (insert selector " ")
+ (dotimes (_ (1+ (random 5)))
+ (insert (seq-random-elt '("=" " @ "))
+ (seq-random-elt selectors)))
+ (insert "{\n}\n")
+ (font-lock-debug-fontify)
+ (goto-char (point-min))
+ (when (eq (get-text-property (point) 'face)
+ 'css-selector)
+ (should-not (format "Recognized %s as a selector"
+ (buffer-substring-no-properties
+ (point) (line-end-position))))))))))
+
+(ert-deftest scss-mode-test-selectors ()
+ (let ((selectors
+ (with-temp-buffer
+ (insert-file-contents (ert-resource-file "scss-selectors.txt"))
+ (string-lines (buffer-string)))))
+ (with-suppressed-warnings ((interactive-only font-lock-debug-fontify))
+ (dolist (selector selectors)
+ (with-temp-buffer
+ (scss-mode)
+ (insert selector " {\n}\n")
+ (font-lock-debug-fontify)
+ (goto-char (point-min))
+ (unless (eq (get-text-property (point) 'face)
+ 'css-selector)
+ (should-not (format "Didn't recognize %s as a selector"
+ (buffer-substring-no-properties
+ (point) (line-end-position))))))))))
+
+
(provide 'css-mode-tests)
;;; css-mode-tests.el ends here
diff --git a/test/lisp/textmodes/emacs-news-mode-resources/toggle-tag.erts b/test/lisp/textmodes/emacs-news-mode-resources/toggle-tag.erts
new file mode 100644
index 00000000000..63c3b1b7d8a
--- /dev/null
+++ b/test/lisp/textmodes/emacs-news-mode-resources/toggle-tag.erts
@@ -0,0 +1,131 @@
+Name: tag1
+Point-Char: |
+
+=-=
++++
+*** 'dired-do-relsymlink-regexp' moved from dired-x to dired.
+The corresponding key "% Y" is now bound by default in Dired.
+
+*** 'M-G' is now bound to 'dired-goto-subdir'.
+|Before, that binding was only available with 'dired-x'.
+=-=
++++
+*** 'dired-do-relsymlink-regexp' moved from dired-x to dired.
+The corresponding key "% Y" is now bound by default in Dired.
+
+---
+*** 'M-G' is now bound to 'dired-goto-subdir'.
+|Before, that binding was only available with 'dired-x'.
+=-=-=
+
+Name: tag2
+Point-Char: |
+
+=-=
++++
+*** 'dired-do-relsymlink-regexp' moved from dired-x to dired.
+The corresponding key "% Y" is now bound by default in Dired.
+
+---
+*** 'M-G' is now bound to 'dired-goto-subdir'.
+|Before, that binding was only available if the 'dired-x' package was
+loaded.
+=-=
++++
+*** 'dired-do-relsymlink-regexp' moved from dired-x to dired.
+The corresponding key "% Y" is now bound by default in Dired.
+
++++
+*** 'M-G' is now bound to 'dired-goto-subdir'.
+|Before, that binding was only available if the 'dired-x' package was
+loaded.
+=-=-=
+
+Name: tag3
+Point-Char: |
+
+=-=
++++
+*** 'dired-do-relsymlink-regexp' moved from dired-x to dired.
+The corresponding key "% Y" is now bound by default in Dired.
+
++++
+*** 'M-G' is now bound to 'dired-goto-subdir'.
+|Before, that binding was only available if the 'dired-x' package was
+loaded.
+=-=
++++
+*** 'dired-do-relsymlink-regexp' moved from dired-x to dired.
+The corresponding key "% Y" is now bound by default in Dired.
+
+*** 'M-G' is now bound to 'dired-goto-subdir'.
+|Before, that binding was only available if the 'dired-x' package was
+loaded.
+=-=-=
+
+Name: tag4-point-at-headline
+Point-Char: |
+
+=-=
++++
+*** 'dired-do-relsymlink-regexp' moved from dired-x to dired.
+The corresponding key "% Y" is now bound by default in Dired.
+
+|*** 'M-G' is now bound to 'dired-goto-subdir'.
+Before, that binding was only available if the 'dired-x' package was
+loaded.
+=-=
++++
+*** 'dired-do-relsymlink-regexp' moved from dired-x to dired.
+The corresponding key "% Y" is now bound by default in Dired.
+
+---
+|*** 'M-G' is now bound to 'dired-goto-subdir'.
+Before, that binding was only available if the 'dired-x' package was
+loaded.
+=-=-=
+
+Name: tag5-point-at-tag
+Point-Char: |
+
+=-=
++++
+*** 'dired-do-relsymlink-regexp' moved from dired-x to dired.
+The corresponding key "% Y" is now bound by default in Dired.
+
+|---
+*** 'M-G' is now bound to 'dired-goto-subdir'.
+Before, that binding was only available if the 'dired-x' package was
+loaded.
+=-=
++++
+*** 'dired-do-relsymlink-regexp' moved from dired-x to dired.
+The corresponding key "% Y" is now bound by default in Dired.
+
+|+++
+*** 'M-G' is now bound to 'dired-goto-subdir'.
+Before, that binding was only available if the 'dired-x' package was
+loaded.
+=-=-=
+
+Name: tag6-point-at-tag
+Point-Char: |
+
+=-=
++++
+*** 'dired-do-relsymlink-regexp' moved from dired-x to dired.
+The corresponding key "% Y" is now bound by default in Dired.
+
+|+++
+*** 'M-G' is now bound to 'dired-goto-subdir'.
+Before, that binding was only available if the 'dired-x' package was
+loaded.
+=-=
++++
+*** 'dired-do-relsymlink-regexp' moved from dired-x to dired.
+The corresponding key "% Y" is now bound by default in Dired.
+
+|*** 'M-G' is now bound to 'dired-goto-subdir'.
+Before, that binding was only available if the 'dired-x' package was
+loaded.
+=-=-=
diff --git a/test/lisp/textmodes/emacs-news-mode-tests.el b/test/lisp/textmodes/emacs-news-mode-tests.el
new file mode 100644
index 00000000000..d2da5eda906
--- /dev/null
+++ b/test/lisp/textmodes/emacs-news-mode-tests.el
@@ -0,0 +1,32 @@
+;;; emacs-news-mode-tests.el --- Tests for emacs-news-mode.el -*- lexical-binding: t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'ert)
+(require 'ert-x)
+(require 'emacs-news-mode)
+
+(ert-deftest emacs-news-toggle-tag ()
+ (ert-test-erts-file (ert-resource-file "toggle-tag.erts")
+ (lambda ()
+ (emacs-news-mode)
+ (emacs-news-toggle-tag))))
+
+;;; emacs-news-mode-tests.el ends here
diff --git a/test/lisp/textmodes/fill-tests.el b/test/lisp/textmodes/fill-tests.el
index 8b9f144dfff..b730de5a690 100644
--- a/test/lisp/textmodes/fill-tests.el
+++ b/test/lisp/textmodes/fill-tests.el
@@ -78,6 +78,28 @@
(buffer-string)
"aaa = baaaaaaaa aaaaaaaaaa\n aaaaaaaaaa\n")))))
+(ert-deftest test-fill-end-period ()
+ (should
+ (equal
+ (with-temp-buffer
+ (text-mode)
+ (auto-fill-mode)
+ (insert "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eius.")
+ (self-insert-command 1 ?\s)
+ (buffer-string))
+ "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eius. "))
+ (should
+ (equal
+ (with-temp-buffer
+ (text-mode)
+ (auto-fill-mode)
+ (insert "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eius.Foo")
+ (forward-char -3)
+ (self-insert-command 1 ?\s)
+ (buffer-string))
+ "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do
+eius. Foo")))
+
(ert-deftest test-fill-haskell ()
(should
(equal
diff --git a/test/lisp/textmodes/page-tests.el b/test/lisp/textmodes/page-tests.el
index 596f3a6ceb7..b7217e69f0c 100644
--- a/test/lisp/textmodes/page-tests.el
+++ b/test/lisp/textmodes/page-tests.el
@@ -80,6 +80,17 @@
(narrow-to-page 2)
(should (equal (buffer-string) "baz"))
(narrow-to-page -1)
+ (should (equal (buffer-string) "bar\n"))
+
+ (widen)
+ (goto-char (point-min))
+ (narrow-to-page)
+ (should (equal (buffer-string) "foo\n"))
+ (goto-char (point-max))
+ (narrow-to-page 2)
+ (should (equal (buffer-string) "baz"))
+ (goto-char (point-max))
+ (narrow-to-page -1)
(should (equal (buffer-string) "bar\n"))))
(ert-deftest page-tests-count-lines-page ()
@@ -100,4 +111,5 @@
(forward-page)
(should (equal (page--what-page) '(3 4)))))
+
;;; page-tests.el ends here
diff --git a/test/lisp/textmodes/reftex-tests.el b/test/lisp/textmodes/reftex-tests.el
index 0051bf3fd0c..9ef41088d1e 100644
--- a/test/lisp/textmodes/reftex-tests.el
+++ b/test/lisp/textmodes/reftex-tests.el
@@ -24,6 +24,7 @@
;;; Code:
(require 'ert)
+(require 'ert-x)
;;; reftex
(require 'reftex)
@@ -33,32 +34,31 @@
(ert-deftest reftex-locate-bibliography-files ()
"Test `reftex-locate-bibliography-files'."
- (let ((temp-dir (make-temp-file "reftex-bib" 'dir))
- (files '("ref1.bib" "ref2.bib"))
- (test '(("\\addbibresource{ref1.bib}\n" . ("ref1.bib"))
- ("\\\\addbibresource[label=x]{ref2.bib}\\n" . ("ref2.bib"))
- ("\\begin{document}\n\\bibliographystyle{plain}\n
+ (ert-with-temp-directory temp-dir
+ (let ((files '("ref1.bib" "ref2.bib"))
+ (test '(("\\addbibresource{ref1.bib}\n" . ("ref1.bib"))
+ ("\\\\addbibresource[label=x]{ref2.bib}\\n" . ("ref2.bib"))
+ ("\\begin{document}\n\\bibliographystyle{plain}\n
\\bibliography{ref1,ref2}\n\\end{document}" . ("ref1.bib" "ref2.bib"))))
- (reftex-bibliography-commands
- ;; Default value: See reftex-vars.el `reftex-bibliography-commands'
- '("bibliography" "nobibliography" "setupbibtex\\[.*?database="
- "addbibresource")))
- (with-temp-buffer
- (insert "test\n")
+ (reftex-bibliography-commands
+ ;; Default value: See reftex-vars.el `reftex-bibliography-commands'
+ '("bibliography" "nobibliography" "setupbibtex\\[.*?database="
+ "addbibresource")))
+ (with-temp-buffer
+ (insert "test\n")
+ (mapc
+ (lambda (file)
+ (write-region (point-min) (point-max) (expand-file-name file
+ temp-dir)))
+ files))
(mapc
- (lambda (file)
- (write-region (point-min) (point-max) (expand-file-name file
- temp-dir)))
- files))
- (mapc
- (lambda (data)
- (with-temp-buffer
- (insert (car data))
- (let ((res (mapcar #'file-name-nondirectory
- (reftex-locate-bibliography-files temp-dir))))
- (should (equal res (cdr data))))))
- test)
- (delete-directory temp-dir 'recursive)))
+ (lambda (data)
+ (with-temp-buffer
+ (insert (car data))
+ (let ((res (mapcar #'file-name-nondirectory
+ (reftex-locate-bibliography-files temp-dir))))
+ (should (equal res (cdr data))))))
+ test))))
(ert-deftest reftex-what-environment-test ()
"Test `reftex-what-environment'."
@@ -102,12 +102,12 @@
;; reason. (An alternative solution would be to use file-equal-p,
;; but I'm too lazy to do that, as one of the tests compares a
;; list.)
- (let* ((temp-dir (file-truename (make-temp-file "reftex-parse" 'dir)))
- (tex-file (expand-file-name "test.tex" temp-dir))
- (bib-file (expand-file-name "ref.bib" temp-dir)))
- (with-temp-buffer
- (insert
-"\\begin{document}
+ (ert-with-temp-directory temp-dir
+ (let* ((tex-file (expand-file-name "test.tex" temp-dir))
+ (bib-file (expand-file-name "ref.bib" temp-dir)))
+ (with-temp-buffer
+ (insert
+ "\\begin{document}
\\section{test}\\label{sec:test}
\\subsection{subtest}
@@ -118,27 +118,26 @@
\\bibliographystyle{plain}
\\bibliography{ref}
\\end{document}")
- (write-region (point-min) (point-max) tex-file))
- (with-temp-buffer
- (insert "test\n")
- (write-region (point-min) (point-max) bib-file))
- (reftex-ensure-compiled-variables)
- (let ((parsed (reftex-parse-from-file tex-file nil temp-dir)))
- (should (equal (car parsed) `(eof ,tex-file)))
- (pop parsed)
- (while parsed
- (let ((entry (pop parsed)))
- (cond
- ((eq (car entry) 'bib)
- (should (string= (cadr entry) bib-file)))
- ((eq (car entry) 'toc)) ;; ...
- ((string= (car entry) "eq:foo"))
- ((string= (car entry) "sec:test"))
- ((eq (car entry) 'bof)
- (should (string= (cadr entry) tex-file))
- (should (null parsed)))
- (t (should-not t)))))
- (delete-directory temp-dir 'recursive))))
+ (write-region (point-min) (point-max) tex-file))
+ (with-temp-buffer
+ (insert "test\n")
+ (write-region (point-min) (point-max) bib-file))
+ (reftex-ensure-compiled-variables)
+ (let ((parsed (reftex-parse-from-file tex-file nil temp-dir)))
+ (should (equal (car parsed) `(eof ,tex-file)))
+ (pop parsed)
+ (while parsed
+ (let ((entry (pop parsed)))
+ (cond
+ ((eq (car entry) 'bib)
+ (should (string= (cadr entry) bib-file)))
+ ((eq (car entry) 'toc)) ;; ...
+ ((string= (car entry) "eq:foo"))
+ ((string= (car entry) "sec:test"))
+ ((eq (car entry) 'bof)
+ (should (string= (cadr entry) tex-file))
+ (should (null parsed)))
+ (t (should-not t)))))))))
;;; reftex-cite
(require 'reftex-cite)
diff --git a/test/lisp/textmodes/texinfo-resources/fill.erts b/test/lisp/textmodes/texinfo-resources/fill.erts
new file mode 100644
index 00000000000..95f3b09eba8
--- /dev/null
+++ b/test/lisp/textmodes/texinfo-resources/fill.erts
@@ -0,0 +1,70 @@
+Code:
+ (lambda ()
+ (texinfo-mode)
+ (fill-paragraph))
+
+Name: fill1
+Point-Char: |
+
+=-=
+@noindent Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
+=-=
+@noindent Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+=-=-=
+
+Name: fill2
+Point-Char: |
+
+=-=
+@cindex relative| remapping, faces
+@cindex base remapping, faces
+ The following functions implement a higher-level interface to @code{face-remapping-alist}.
+=-=-=
+
+
+Name: fill3
+Point-Char: |
+
+=-=
+@cindex relative remapping, faces
+@cindex base remapping, faces|
+ The following functions implement a higher-level interface to @code{face-remapping-alist}.
+=-=-=
+
+Name: fill4
+Point-Char: |
+
+=-=
+@cindex relative remapping, faces
+@cindex base remapping, faces
+ The following functions| implement a higher-level interface to @code{face-remapping-alist}.
+=-=
+@cindex relative remapping, faces
+@cindex base remapping, faces
+ The following functions| implement a higher-level interface to
+@code{face-remapping-alist}.
+=-=-=
+
+Name: fill5
+Point-Char: |
+
+=-=
+@defun face-remap-add-relative face &rest specs
+|This function adds the face spec in @var{specs} as relative
+remappings for face @var{face} in the current buffer. The remaining
+arguments, @var{specs}, should form either a list of face names, or a
+property list of attribute/value pairs.
+=-=
+@defun face-remap-add-relative face &rest specs
+This function adds the face spec in @var{specs} as relative remappings
+for face @var{face} in the current buffer. The remaining arguments,
+@var{specs}, should form either a list of face names, or a property
+list of attribute/value pairs.
+=-=-=
+
+Name: fill6
+
+=-=
+@subsection This is a very very very very very very very very very very long subsection name
+=-=-=
diff --git a/test/lisp/textmodes/texinfo-tests.el b/test/lisp/textmodes/texinfo-tests.el
new file mode 100644
index 00000000000..48cc5fece2c
--- /dev/null
+++ b/test/lisp/textmodes/texinfo-tests.el
@@ -0,0 +1,33 @@
+;;; texinfo-tests.el --- Tests for texinfo.el -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021-2022 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'texinfo)
+(require 'ert)
+(require 'ert-x)
+
+(ert-deftest test-filling ()
+ (ert-test-erts-file (ert-resource-file "fill.erts")))
+
+;;; texinfo-tests.el ends here
diff --git a/test/lisp/thingatpt-tests.el b/test/lisp/thingatpt-tests.el
index 8d794f25f43..b6d0b1446a3 100644
--- a/test/lisp/thingatpt-tests.el
+++ b/test/lisp/thingatpt-tests.el
@@ -170,21 +170,13 @@ position to retrieve THING.")
(forward-char -1)
(should (eq (symbol-at-point) 'bar))))
-(ert-deftest test-symbol-thing-2 ()
- (with-temp-buffer
- (insert " bar ")
- (goto-char (point-max))
- (should (eq (symbol-at-point) nil))
- (forward-char -1)
- (should (eq (symbol-at-point) 'bar))))
-
(ert-deftest test-symbol-thing-3 ()
(with-temp-buffer
(insert "bar")
(goto-char 2)
(should (eq (symbol-at-point) 'bar))))
-(ert-deftest test-symbol-thing-3 ()
+(ert-deftest test-symbol-thing-4 ()
(with-temp-buffer
(insert "`[[`(")
(goto-char 2)
diff --git a/test/lisp/thumbs-tests.el b/test/lisp/thumbs-tests.el
index 3c14840c722..a8972394fa5 100644
--- a/test/lisp/thumbs-tests.el
+++ b/test/lisp/thumbs-tests.el
@@ -20,15 +20,13 @@
;;; Code:
(require 'ert)
+(require 'ert-x)
(require 'thumbs)
(ert-deftest thumbs-tests-thumbsdir/create-if-missing ()
- (let ((thumbs-thumbsdir (make-temp-file "thumbs-test" t)))
- (unwind-protect
- (progn
- (delete-directory thumbs-thumbsdir)
- (should (file-directory-p (thumbs-thumbsdir))))
- (delete-directory thumbs-thumbsdir))))
+ (ert-with-temp-directory thumbs-thumbsdir
+ (delete-directory thumbs-thumbsdir)
+ (should (file-directory-p (thumbs-thumbsdir)))))
(provide 'thumbs-tests)
;;; thumbs-tests.el ends here
diff --git a/test/lisp/time-stamp-tests.el b/test/lisp/time-stamp-tests.el
index fca35329b1b..8361d58b558 100644
--- a/test/lisp/time-stamp-tests.el
+++ b/test/lisp/time-stamp-tests.el
@@ -271,7 +271,8 @@
(should (equal (time-stamp-string "%3a" ref-time1) Mon))
(should (equal (time-stamp-string "%#A" ref-time1) MONDAY))
;; documented 1997-2019
- (should (equal (time-stamp-string "%3A" ref-time1) MON))
+ (should (equal (time-stamp-string "%3A" ref-time1)
+ (substring MONDAY 0 3)))
(should (equal (time-stamp-string "%:a" ref-time1) Monday))
;; implemented since 2001, documented since 2019
(should (equal (time-stamp-string "%#a" ref-time1) MON))
@@ -291,10 +292,12 @@
(January (format-time-string "%B" ref-time1 t))
(JANUARY (format-time-string "%^B" ref-time1 t)))
;; implemented and documented since 1997
- (should (equal (time-stamp-string "%3b" ref-time1) Jan))
+ (should (equal (time-stamp-string "%3b" ref-time1)
+ (substring January 0 3)))
(should (equal (time-stamp-string "%#B" ref-time1) JANUARY))
;; documented 1997-2019
- (should (equal (time-stamp-string "%3B" ref-time1) JAN))
+ (should (equal (time-stamp-string "%3B" ref-time1)
+ (substring JANUARY 0 3)))
(should (equal (time-stamp-string "%:b" ref-time1) January))
;; implemented since 2001, documented since 2019
(should (equal (time-stamp-string "%#b" ref-time1) JAN))
@@ -595,8 +598,12 @@
;; incorrectly nested parens do not crash us
(should-not (equal (time-stamp-string "%(stuffB" ref-time3) May))
(should-not (equal (time-stamp-string "%)B" ref-time3) May))
+ ;; unterminated format does not crash us
+ (should-not (equal (time-stamp-string "%" ref-time3) May))
;; not all punctuation is allowed
- (should-not (equal (time-stamp-string "%&B" ref-time3) May)))))
+ (should-not (equal (time-stamp-string "%&B" ref-time3) May))
+ (should-not (equal (time-stamp-string "%/B" ref-time3) May))
+ (should-not (equal (time-stamp-string "%;B" ref-time3) May)))))
(ert-deftest time-stamp-format-non-conversions ()
"Test that without a %, the text is copied literally."
@@ -635,8 +642,8 @@
(concat Mon "." Monday "." Mon)))
(should (equal (time-stamp-string "%5z.%5::z.%5z" ref-time1)
"+0000.+00:00:00.+0000"))
- ;; format letter is independent
- (should (equal (time-stamp-string "%H:%M" ref-time1) "15:04")))))
+ ;; format character is independent
+ (should (equal (time-stamp-string "%H:%M%%%S" ref-time1) "15:04%05")))))
(ert-deftest time-stamp-format-string-width ()
"Test time-stamp string width modifiers."
@@ -648,15 +655,17 @@
(should (equal (time-stamp-string "%0b" ref-time3) ""))
(should (equal (time-stamp-string "%1b" ref-time3) (substring May 0 1)))
(should (equal (time-stamp-string "%2b" ref-time3) (substring May 0 2)))
- (should (equal (time-stamp-string "%3b" ref-time3) May))
+ (should (equal (time-stamp-string "%3b" ref-time3) (substring May 0 3)))
(should (equal (time-stamp-string "%4b" ref-time3) (concat " " May)))
(should (equal (time-stamp-string "%0%" ref-time3) ""))
(should (equal (time-stamp-string "%1%" ref-time3) "%"))
(should (equal (time-stamp-string "%2%" ref-time3) " %"))
(should (equal (time-stamp-string "%9%" ref-time3) " %"))
(should (equal (time-stamp-string "%10%" ref-time3) " %"))
- (should (equal (time-stamp-string "%#3a" ref-time3) SUN))
- (should (equal (time-stamp-string "%#3b" ref-time2) NOV)))))
+ (should (equal (time-stamp-string "%#3a" ref-time3)
+ (substring SUN 0 3)))
+ (should (equal (time-stamp-string "%#3b" ref-time2)
+ (substring NOV 0 3))))))
;;; Tests of helper functions
diff --git a/test/lisp/url/url-tramp-tests.el b/test/lisp/url/url-tramp-tests.el
index 033c17444db..369de0e2457 100644
--- a/test/lisp/url/url-tramp-tests.el
+++ b/test/lisp/url/url-tramp-tests.el
@@ -55,8 +55,12 @@
(password-cache-remove key)
(should-not (password-in-cache-p key)))
- ;; "http" does not belong to `url-tramp-protocols'.
- (should-not (url-tramp-convert-url-to-tramp "http://www.gnu.org")))
+ ;; "http" does not belong to `url-tramp-protocols'. The string
+ ;; isn't changed, therefore.
+ (should
+ (string-equal
+ (url-tramp-convert-url-to-tramp "http://www.gnu.org")
+ "http://www.gnu.org")))
(ert-deftest url-tramp-test-convert-tramp-to-url ()
"Test that Tramp file names are converted into proper URLs."
@@ -75,8 +79,12 @@
(url-tramp-convert-tramp-to-url "/telnet:user@remotehost#42:")
"telnet://user@remotehost:42"))
- ;; "sftp" does not belong to `url-tramp-protocols'.
- (should-not (url-tramp-convert-tramp-to-url "/sftp:user@localhost:")))
+ ;; "sftp" does not belong to `url-tramp-protocols'. The string
+ ;; isn't changed, therefore.
+ (should
+ (string-equal
+ (url-tramp-convert-tramp-to-url "/sftp:user@localhost:")
+ "/sftp:user@localhost:")))
(provide 'url-tramp-tests)
diff --git a/test/lisp/vc/diff-mode-tests.el b/test/lisp/vc/diff-mode-tests.el
index 214c82530a0..19e3dbb42a6 100644
--- a/test/lisp/vc/diff-mode-tests.el
+++ b/test/lisp/vc/diff-mode-tests.el
@@ -173,35 +173,33 @@ wristwatches
wrongheadedly
wrongheadedness
youthfulness
-")
- (temp-dir (make-temp-file "diff-mode-test" 'dir)))
-
- (let ((buf (find-file-noselect (format "%s/%s" temp-dir "fil" )))
- (buf2 (find-file-noselect (format "%s/%s" temp-dir "fil2"))))
- (unwind-protect
- (progn
- (with-current-buffer buf (insert fil_before) (save-buffer))
- (with-current-buffer buf2 (insert fil2_before) (save-buffer))
-
- (with-temp-buffer
- (cd temp-dir)
- (insert patch)
- (goto-char (point-min))
- (diff-apply-hunk)
- (diff-apply-hunk)
- (diff-apply-hunk))
-
- (should (equal (with-current-buffer buf (buffer-string))
- fil_after))
- (should (equal (with-current-buffer buf2 (buffer-string))
- fil2_after)))
-
- (ignore-errors
- (with-current-buffer buf (set-buffer-modified-p nil))
- (kill-buffer buf)
- (with-current-buffer buf2 (set-buffer-modified-p nil))
- (kill-buffer buf2)
- (delete-directory temp-dir 'recursive))))))
+"))
+ (ert-with-temp-directory temp-dir
+ (let ((buf (find-file-noselect (format "%s/%s" temp-dir "fil" )))
+ (buf2 (find-file-noselect (format "%s/%s" temp-dir "fil2"))))
+ (unwind-protect
+ (progn
+ (with-current-buffer buf (insert fil_before) (save-buffer))
+ (with-current-buffer buf2 (insert fil2_before) (save-buffer))
+
+ (with-temp-buffer
+ (cd temp-dir)
+ (insert patch)
+ (goto-char (point-min))
+ (diff-apply-hunk)
+ (diff-apply-hunk)
+ (diff-apply-hunk))
+
+ (should (equal (with-current-buffer buf (buffer-string))
+ fil_after))
+ (should (equal (with-current-buffer buf2 (buffer-string))
+ fil2_after)))
+
+ (ignore-errors
+ (with-current-buffer buf (set-buffer-modified-p nil))
+ (kill-buffer buf)
+ (with-current-buffer buf2 (set-buffer-modified-p nil))
+ (kill-buffer buf2)))))))
(ert-deftest diff-mode-test-hunk-text-no-newline ()
"Check output of `diff-hunk-text' with no newline at end of file."
diff --git a/test/lisp/vc/ediff-ptch-tests.el b/test/lisp/vc/ediff-ptch-tests.el
index 21b9b0cab76..935046198f3 100644
--- a/test/lisp/vc/ediff-ptch-tests.el
+++ b/test/lisp/vc/ediff-ptch-tests.el
@@ -22,6 +22,7 @@
;;; Code:
(require 'ert)
+(require 'ert-x)
(require 'ediff-ptch)
(ert-deftest ediff-ptch-test-bug25010 ()
@@ -45,34 +46,33 @@ index 6a07f80..6e8e947 100644
"Test for https://debbugs.gnu.org/26084 ."
(skip-unless (executable-find "git"))
(skip-unless (executable-find ediff-patch-program))
- (let* ((tmpdir (make-temp-file "ediff-ptch-test" t))
- (default-directory (file-name-as-directory tmpdir))
- (patch (make-temp-file "ediff-ptch-test"))
- (qux (expand-file-name "qux.txt" tmpdir))
- (bar (expand-file-name "bar.txt" tmpdir))
- (git-program (executable-find "git")))
- ;; Create repository.
- (with-temp-buffer
- (insert "qux here\n")
- (write-region nil nil qux nil 'silent)
- (erase-buffer)
- (insert "bar here\n")
- (write-region nil nil bar nil 'silent))
- (call-process git-program nil nil nil "init")
- (call-process git-program nil nil nil "add" ".")
- (call-process git-program nil nil nil "commit" "-m" "Test repository.")
- ;; Update repo., save the diff and reset to initial state.
- (with-temp-buffer
- (insert "foo here\n")
- (write-region nil nil qux nil 'silent)
- (write-region nil nil bar nil 'silent))
- (call-process git-program nil `(:file ,patch) nil "diff")
- (call-process git-program nil nil nil "reset" "--hard" "HEAD")
- ;; Visit the diff file i.e., patch; extract from it the parts
- ;; affecting just each of the files: store in patch-bar the part
- ;; affecting 'bar', and in patch-qux the part affecting 'qux'.
- (find-file patch)
- (unwind-protect
+ (ert-with-temp-directory tmpdir
+ (ert-with-temp-file patch
+ (let* ((default-directory (file-name-as-directory tmpdir))
+ (qux (expand-file-name "qux.txt" tmpdir))
+ (bar (expand-file-name "bar.txt" tmpdir))
+ (git-program (executable-find "git")))
+ ;; Create repository.
+ (with-temp-buffer
+ (insert "qux here\n")
+ (write-region nil nil qux nil 'silent)
+ (erase-buffer)
+ (insert "bar here\n")
+ (write-region nil nil bar nil 'silent))
+ (call-process git-program nil nil nil "init")
+ (call-process git-program nil nil nil "add" ".")
+ (call-process git-program nil nil nil "commit" "-m" "Test repository.")
+ ;; Update repo., save the diff and reset to initial state.
+ (with-temp-buffer
+ (insert "foo here\n")
+ (write-region nil nil qux nil 'silent)
+ (write-region nil nil bar nil 'silent))
+ (call-process git-program nil `(:file ,patch) nil "diff")
+ (call-process git-program nil nil nil "reset" "--hard" "HEAD")
+ ;; Visit the diff file i.e., patch; extract from it the parts
+ ;; affecting just each of the files: store in patch-bar the part
+ ;; affecting 'bar', and in patch-qux the part affecting 'qux'.
+ (find-file patch)
(let* ((info
(progn (ediff-map-patch-buffer (current-buffer)) ediff-patch-map))
(patch-bar
@@ -116,9 +116,7 @@ index 6a07f80..6e8e947 100644
(buffer-string))
(with-temp-buffer
(insert-file-contents backup)
- (buffer-string)))))))
- (delete-directory tmpdir 'recursive)
- (delete-file patch)))))
+ (buffer-string))))))))))))
(provide 'ediff-ptch-tests)
diff --git a/test/lisp/vc/vc-bzr-tests.el b/test/lisp/vc/vc-bzr-tests.el
index 86d497631cb..52f06df5bcd 100644
--- a/test/lisp/vc/vc-bzr-tests.el
+++ b/test/lisp/vc/vc-bzr-tests.el
@@ -25,6 +25,7 @@
;;; Code:
(require 'ert)
+(require 'ert-x)
(require 'vc-bzr)
(require 'vc-dir)
@@ -51,106 +52,97 @@
;; temporary directory.
;; TODO does this means tests should be setting XDG_ variables (not
;; just HOME) to temporary values too?
- (let* ((homedir (make-temp-file "vc-bzr-test" t))
- (bzrdir (expand-file-name "bzr" homedir))
- (ignored-dir (progn
- (make-directory bzrdir)
- (expand-file-name "ignored-dir" bzrdir)))
- (default-directory (file-name-as-directory bzrdir))
- (process-environment (cons (format "HOME=%s" homedir)
- process-environment)))
- (unwind-protect
- (progn
- (make-directory ignored-dir)
- (with-temp-buffer
- (insert (file-name-nondirectory ignored-dir))
- (write-region nil nil (expand-file-name ".bzrignore" bzrdir)
- nil 'silent))
- (skip-unless (eq 0 ; some internal bzr error
- (call-process vc-bzr-program nil nil nil "init")))
- (call-process vc-bzr-program nil nil nil "add")
- (call-process vc-bzr-program nil nil nil "commit" "-m" "Commit 1")
- (with-temp-buffer
- (insert "unregistered file")
- (write-region nil nil (expand-file-name "testfile2" ignored-dir)
- nil 'silent))
- (vc-dir ignored-dir)
- (while (vc-dir-busy)
- (sit-for 0.1))
- ;; FIXME better to explicitly test for error from process sentinel.
- (with-current-buffer "*vc-dir*"
- (goto-char (point-min))
- (should (search-forward "unregistered" nil t))))
- (delete-directory homedir t))))
+ (ert-with-temp-directory homedir
+ (let* ((bzrdir (expand-file-name "bzr" homedir))
+ (ignored-dir (progn
+ (make-directory bzrdir)
+ (expand-file-name "ignored-dir" bzrdir)))
+ (default-directory (file-name-as-directory bzrdir))
+ (process-environment (cons (format "HOME=%s" homedir)
+ process-environment)))
+ (make-directory ignored-dir)
+ (with-temp-buffer
+ (insert (file-name-nondirectory ignored-dir))
+ (write-region nil nil (expand-file-name ".bzrignore" bzrdir)
+ nil 'silent))
+ (skip-unless (eq 0 ; some internal bzr error
+ (call-process vc-bzr-program nil nil nil "init")))
+ (call-process vc-bzr-program nil nil nil "add")
+ (call-process vc-bzr-program nil nil nil "commit" "-m" "Commit 1")
+ (with-temp-buffer
+ (insert "unregistered file")
+ (write-region nil nil (expand-file-name "testfile2" ignored-dir)
+ nil 'silent))
+ (vc-dir ignored-dir)
+ (while (vc-dir-busy)
+ (sit-for 0.1))
+ ;; FIXME better to explicitly test for error from process sentinel.
+ (with-current-buffer "*vc-dir*"
+ (goto-char (point-min))
+ (should (search-forward "unregistered" nil t))))))
;; Not specific to bzr.
(ert-deftest vc-bzr-test-bug9781 ()
"Test for https://debbugs.gnu.org/9781 ."
(skip-unless (executable-find vc-bzr-program))
- (let* ((homedir (make-temp-file "vc-bzr-test" t))
- (bzrdir (expand-file-name "bzr" homedir))
- (subdir (progn
- (make-directory bzrdir)
- (expand-file-name "subdir" bzrdir)))
- (file (expand-file-name "file" bzrdir))
- (default-directory (file-name-as-directory bzrdir))
- (process-environment (cons (format "HOME=%s" homedir)
- process-environment)))
- (unwind-protect
- (progn
- (skip-unless (eq 0 ; some internal bzr error
- (call-process vc-bzr-program nil nil nil "init")))
- (make-directory subdir)
- (with-temp-buffer
- (insert "text")
- (write-region nil nil file nil 'silent)
- (write-region nil nil (expand-file-name "subfile" subdir)
- nil 'silent))
- (call-process vc-bzr-program nil nil nil "add")
- (call-process vc-bzr-program nil nil nil "commit" "-m" "Commit 1")
- (call-process vc-bzr-program nil nil nil "remove" subdir)
- (with-temp-buffer
- (insert "different text")
- (write-region nil nil file nil 'silent))
- (vc-dir bzrdir)
- (while (vc-dir-busy)
- (sit-for 0.1))
- (vc-dir-mark-all-files t)
- (cl-letf (((symbol-function 'y-or-n-p) (lambda (_) t)))
- (vc-next-action nil))
- (should (get-buffer "*vc-log*")))
- (delete-directory homedir t))))
+ (ert-with-temp-directory homedir
+ (let* ((bzrdir (expand-file-name "bzr" homedir))
+ (subdir (progn
+ (make-directory bzrdir)
+ (expand-file-name "subdir" bzrdir)))
+ (file (expand-file-name "file" bzrdir))
+ (default-directory (file-name-as-directory bzrdir))
+ (process-environment (cons (format "HOME=%s" homedir)
+ process-environment)))
+ (skip-unless (eq 0 ; some internal bzr error
+ (call-process vc-bzr-program nil nil nil "init")))
+ (make-directory subdir)
+ (with-temp-buffer
+ (insert "text")
+ (write-region nil nil file nil 'silent)
+ (write-region nil nil (expand-file-name "subfile" subdir)
+ nil 'silent))
+ (call-process vc-bzr-program nil nil nil "add")
+ (call-process vc-bzr-program nil nil nil "commit" "-m" "Commit 1")
+ (call-process vc-bzr-program nil nil nil "remove" subdir)
+ (with-temp-buffer
+ (insert "different text")
+ (write-region nil nil file nil 'silent))
+ (vc-dir bzrdir)
+ (while (vc-dir-busy)
+ (sit-for 0.1))
+ (vc-dir-mark-all-files t)
+ (cl-letf (((symbol-function 'y-or-n-p) (lambda (_) t)))
+ (vc-next-action nil))
+ (should (get-buffer "*vc-log*")))))
;; https://lists.gnu.org/r/help-gnu-emacs/2012-04/msg00145.html
(ert-deftest vc-bzr-test-faulty-bzr-autoloads ()
"Test we can generate autoloads in a bzr directory when bzr is faulty."
(skip-unless (executable-find vc-bzr-program))
- (let* ((homedir (make-temp-file "vc-bzr-test" t))
- (bzrdir (expand-file-name "bzr" homedir))
- (file (progn
- (make-directory bzrdir)
- (expand-file-name "foo.el" bzrdir)))
- (default-directory (file-name-as-directory bzrdir))
- (process-environment (cons (format "HOME=%s" homedir)
- process-environment)))
- (unwind-protect
- (progn
- (call-process vc-bzr-program nil nil nil "init")
- (with-temp-buffer
- (insert ";;;###autoload
+ (ert-with-temp-directory homedir
+ (let* ((bzrdir (expand-file-name "bzr" homedir))
+ (file (progn
+ (make-directory bzrdir)
+ (expand-file-name "foo.el" bzrdir)))
+ (default-directory (file-name-as-directory bzrdir))
+ (process-environment (cons (format "HOME=%s" homedir)
+ process-environment)))
+ (call-process vc-bzr-program nil nil nil "init")
+ (with-temp-buffer
+ (insert ";;;###autoload
\(defun foo () \"foo\" (interactive) (message \"foo!\"))")
- (write-region nil nil file nil 'silent))
- (call-process vc-bzr-program nil nil nil "add")
- (call-process vc-bzr-program nil nil nil "commit" "-m" "Commit 1")
- ;; Deleting dirstate ensures both that vc-bzr's status heuristic
- ;; fails, so it has to call the external bzr status, and
- ;; causes bzr status to fail. This simulates a broken bzr
- ;; installation.
- (delete-file ".bzr/checkout/dirstate")
- (should (progn (make-directory-autoloads
- default-directory
- (expand-file-name "loaddefs.el" bzrdir))
- t)))
- (delete-directory homedir t))))
+ (write-region nil nil file nil 'silent))
+ (call-process vc-bzr-program nil nil nil "add")
+ (call-process vc-bzr-program nil nil nil "commit" "-m" "Commit 1")
+ ;; Deleting dirstate ensures both that vc-bzr's status heuristic
+ ;; fails, so it has to call the external bzr status, and
+ ;; causes bzr status to fail. This simulates a broken bzr
+ ;; installation.
+ (delete-file ".bzr/checkout/dirstate")
+ (should (progn (loaddefs-generate
+ default-directory
+ (expand-file-name "loaddefs.el" bzrdir))
+ t)))))
;;; vc-bzr-tests.el ends here
diff --git a/test/lisp/vc/vc-git-tests.el b/test/lisp/vc/vc-git-tests.el
new file mode 100644
index 00000000000..dc9641ed46b
--- /dev/null
+++ b/test/lisp/vc/vc-git-tests.el
@@ -0,0 +1,67 @@
+;;; vc-git-tests.el --- tests for vc/vc-git.el -*- lexical-binding:t -*-
+
+;; Copyright (C) 2016-2022 Free Software Foundation, Inc.
+
+;; Author: Justin Schell <justinmschell@gmail.com>
+;; Maintainer: emacs-devel@gnu.org
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'vc-git)
+
+(ert-deftest vc-git-test-program-version-general ()
+ (vc-git-test--run-program-version-test
+ "git version 2.30.1.0"
+ "2.30.1.0"))
+
+(ert-deftest vc-git-test-program-version-windows ()
+ (vc-git-test--run-program-version-test
+ "git version 2.30.1.1.windows.1"
+ "2.30.1.1"))
+
+(ert-deftest vc-git-test-program-version-apple ()
+ (vc-git-test--run-program-version-test
+ "git version 2.30.1.2 (Apple Git-130)"
+ "2.30.1.2"))
+
+(ert-deftest vc-git-test-program-version-other ()
+ (vc-git-test--run-program-version-test
+ "git version 2.30.1.3.foo.bar"
+ "2.30.1.3"))
+
+(ert-deftest vc-git-test-program-version-invalid-leading-string ()
+ (vc-git-test--run-program-version-test
+ "git version foo.bar.2.30.1.4"
+ "0"))
+
+(ert-deftest vc-git-test-program-version-invalid-leading-dot ()
+ (vc-git-test--run-program-version-test
+ "git version .2.30.1.5"
+ "0"))
+
+(defun vc-git-test--run-program-version-test
+ (mock-version-string expected-output)
+ (cl-letf* (((symbol-function 'vc-git--run-command-string)
+ (lambda (_file _args) mock-version-string))
+ (vc-git--program-version nil)
+ (actual-output (vc-git--program-version)))
+ (should (equal actual-output expected-output))))
+
+;;; vc-git-tests.el ends here
diff --git a/test/lisp/vc/vc-tests.el b/test/lisp/vc/vc-tests.el
index 5e2a0c555f9..dc4d3af6999 100644
--- a/test/lisp/vc/vc-tests.el
+++ b/test/lisp/vc/vc-tests.el
@@ -109,6 +109,7 @@
;;; Code:
(require 'ert)
+(require 'ert-x)
(require 'vc)
(require 'log-edit)
@@ -152,7 +153,7 @@ For backends which dont support it, it is emulated."
(delete-directory "module" 'recursive)
;; We must cleanup the "remote" CVS repo as well.
(add-hook 'vc-test--cleanup-hook
- `(lambda () (delete-directory ,tmp-dir 'recursive)))))
+ (lambda () (delete-directory tmp-dir 'recursive)))))
((eq backend 'Arch)
(let ((archive-name (format "%s--%s" user-mail-address (random))))
@@ -178,41 +179,39 @@ For backends which dont support it, it is emulated."
(defun vc-test--create-repo (backend)
"Create a test repository in `default-directory', a temporary directory."
-
- (let ((vc-handled-backends `(,backend))
- (default-directory
- (file-name-as-directory
- (expand-file-name
- (make-temp-name "vc-test") temporary-file-directory)))
- (process-environment process-environment)
- tempdir
- vc-test--cleanup-hook)
- (when (eq backend 'Bzr)
- (setq tempdir (make-temp-file "vc-test--create-repo" t)
- process-environment (cons (format "BZR_HOME=%s" tempdir)
- process-environment)))
-
- (unwind-protect
- (progn
- ;; Cleanup.
- (add-hook
- 'vc-test--cleanup-hook
- `(lambda () (delete-directory ,default-directory 'recursive)))
-
- ;; Check the revision granularity.
- (should (memq (vc-test--revision-granularity-function backend)
- '(file repository)))
-
- ;; Create empty repository.
- (make-directory default-directory)
- (should (file-directory-p default-directory))
- (vc-test--create-repo-function backend)
- (should (eq (vc-responsible-backend default-directory) backend)))
-
- ;; Save exit.
- (ignore-errors
- (if tempdir (delete-directory tempdir t))
- (run-hooks 'vc-test--cleanup-hook)))))
+ (ert-with-temp-directory tempdir
+ (let ((vc-handled-backends `(,backend))
+ (default-directory
+ (file-name-as-directory
+ (expand-file-name
+ (make-temp-name "vc-test") temporary-file-directory)))
+ (process-environment process-environment)
+ vc-test--cleanup-hook)
+ (when (eq backend 'Bzr)
+ (setq process-environment (cons (format "BZR_HOME=%s" tempdir)
+ process-environment)))
+
+ (unwind-protect
+ (progn
+ ;; Cleanup.
+ (add-hook
+ 'vc-test--cleanup-hook
+ (let ((dir default-directory))
+ (lambda () (delete-directory dir 'recursive))))
+
+ ;; Check the revision granularity.
+ (should (memq (vc-test--revision-granularity-function backend)
+ '(file repository)))
+
+ ;; Create empty repository.
+ (make-directory default-directory)
+ (should (file-directory-p default-directory))
+ (vc-test--create-repo-function backend)
+ (should (eq (vc-responsible-backend default-directory) backend)))
+
+ ;; Save exit.
+ (ignore-errors
+ (run-hooks 'vc-test--cleanup-hook))))))
;; FIXME: Why isn't there `vc-unregister'?
(defun vc-test--unregister-function (backend file)
@@ -235,447 +234,435 @@ Catch the `vc-not-supported' error."
(defun vc-test--register (backend)
"Register and unregister a file.
This checks also `vc-backend' and `vc-responsible-backend'."
-
- (let ((vc-handled-backends `(,backend))
- (default-directory
- (file-name-as-directory
- (expand-file-name
- (make-temp-name "vc-test") temporary-file-directory)))
- (process-environment process-environment)
- tempdir
- vc-test--cleanup-hook)
- (when (eq backend 'Bzr)
- (setq tempdir (make-temp-file "vc-test--register" t)
- process-environment (cons (format "BZR_HOME=%s" tempdir)
- process-environment)))
- (unwind-protect
- (progn
- ;; Cleanup.
- (add-hook
- 'vc-test--cleanup-hook
- `(lambda () (delete-directory ,default-directory 'recursive)))
-
- ;; Create empty repository.
- (make-directory default-directory)
- (vc-test--create-repo-function backend)
- ;; For file oriented backends CVS, RCS and SVN the backend is
- ;; returned, and the directory is registered already.
- (should (if (vc-backend default-directory)
- (vc-registered default-directory)
- (not (vc-registered default-directory))))
- (should (eq (vc-responsible-backend default-directory) backend))
-
- (let ((tmp-name1 (expand-file-name "foo" default-directory))
- (tmp-name2 "bla"))
- ;; Register files. Check for it.
- (write-region "foo" nil tmp-name1 nil 'nomessage)
- (should (file-exists-p tmp-name1))
- (should-not (vc-backend tmp-name1))
- (should (eq (vc-responsible-backend tmp-name1) backend))
- (should-not (vc-registered tmp-name1))
-
- (write-region "bla" nil tmp-name2 nil 'nomessage)
- (should (file-exists-p tmp-name2))
- (should-not (vc-backend tmp-name2))
- (should (eq (vc-responsible-backend tmp-name2) backend))
- (should-not (vc-registered tmp-name2))
-
- (vc-register (list backend (list tmp-name1 tmp-name2)))
- (should (file-exists-p tmp-name1))
- (should (eq (vc-backend tmp-name1) backend))
- (should (eq (vc-responsible-backend tmp-name1) backend))
- (should (vc-registered tmp-name1))
-
- (should (file-exists-p tmp-name2))
- (should (eq (vc-backend tmp-name2) backend))
- (should (eq (vc-responsible-backend tmp-name2) backend))
- (should (vc-registered tmp-name2))
-
- ;; `vc-backend' accepts also a list of files,
- ;; `vc-responsible-backend' doesn't.
- (should (vc-backend (list tmp-name1 tmp-name2)))
-
- ;; Unregister the files.
- (unless (eq (vc-test--run-maybe-unsupported-function
- 'vc-test--unregister-function backend tmp-name1)
- 'vc-not-supported)
+ (ert-with-temp-directory tempdir
+ (let ((vc-handled-backends `(,backend))
+ (default-directory
+ (file-name-as-directory
+ (expand-file-name
+ (make-temp-name "vc-test") temporary-file-directory)))
+ (process-environment process-environment)
+ vc-test--cleanup-hook)
+ (when (eq backend 'Bzr)
+ (setq process-environment (cons (format "BZR_HOME=%s" tempdir)
+ process-environment)))
+ (unwind-protect
+ (progn
+ ;; Cleanup.
+ (add-hook
+ 'vc-test--cleanup-hook
+ (let ((dir default-directory))
+ (lambda () (delete-directory dir 'recursive))))
+
+ ;; Create empty repository.
+ (make-directory default-directory)
+ (vc-test--create-repo-function backend)
+ ;; For file oriented backends CVS, RCS and SVN the backend is
+ ;; returned, and the directory is registered already.
+ (should (if (vc-backend default-directory)
+ (vc-registered default-directory)
+ (not (vc-registered default-directory))))
+ (should (eq (vc-responsible-backend default-directory) backend))
+
+ (let ((tmp-name1 (expand-file-name "foo" default-directory))
+ (tmp-name2 "bla"))
+ ;; Register files. Check for it.
+ (write-region "foo" nil tmp-name1 nil 'nomessage)
+ (should (file-exists-p tmp-name1))
(should-not (vc-backend tmp-name1))
- (should-not (vc-registered tmp-name1)))
- (unless (eq (vc-test--run-maybe-unsupported-function
- 'vc-test--unregister-function backend tmp-name2)
- 'vc-not-supported)
- (should-not (vc-backend tmp-name2))
- (should-not (vc-registered tmp-name2)))
-
- ;; The files should still exist.
- (should (file-exists-p tmp-name1))
- (should (file-exists-p tmp-name2))))
+ (should (eq (vc-responsible-backend tmp-name1) backend))
+ (should-not (vc-registered tmp-name1))
- ;; Save exit.
- (ignore-errors
- (if tempdir (delete-directory tempdir t))
- (run-hooks 'vc-test--cleanup-hook)))))
+ (write-region "bla" nil tmp-name2 nil 'nomessage)
+ (should (file-exists-p tmp-name2))
+ (should-not (vc-backend tmp-name2))
+ (should (eq (vc-responsible-backend tmp-name2) backend))
+ (should-not (vc-registered tmp-name2))
+
+ (vc-register (list backend (list tmp-name1 tmp-name2)))
+ (should (file-exists-p tmp-name1))
+ (should (eq (vc-backend tmp-name1) backend))
+ (should (eq (vc-responsible-backend tmp-name1) backend))
+ (should (vc-registered tmp-name1))
+
+ (should (file-exists-p tmp-name2))
+ (should (eq (vc-backend tmp-name2) backend))
+ (should (eq (vc-responsible-backend tmp-name2) backend))
+ (should (vc-registered tmp-name2))
+
+ ;; `vc-backend' accepts also a list of files,
+ ;; `vc-responsible-backend' doesn't.
+ (should (vc-backend (list tmp-name1 tmp-name2)))
+
+ ;; Unregister the files.
+ (unless (eq (vc-test--run-maybe-unsupported-function
+ 'vc-test--unregister-function backend tmp-name1)
+ 'vc-not-supported)
+ (should-not (vc-backend tmp-name1))
+ (should-not (vc-registered tmp-name1)))
+ (unless (eq (vc-test--run-maybe-unsupported-function
+ 'vc-test--unregister-function backend tmp-name2)
+ 'vc-not-supported)
+ (should-not (vc-backend tmp-name2))
+ (should-not (vc-registered tmp-name2)))
+
+ ;; The files should still exist.
+ (should (file-exists-p tmp-name1))
+ (should (file-exists-p tmp-name2))))
+
+ ;; Save exit.
+ (ignore-errors
+ (run-hooks 'vc-test--cleanup-hook))))))
(defun vc-test--state (backend)
"Check the different states of a file."
-
- (let ((vc-handled-backends `(,backend))
- (default-directory
- (file-name-as-directory
- (expand-file-name
- (make-temp-name "vc-test") temporary-file-directory)))
- (process-environment process-environment)
- tempdir
- vc-test--cleanup-hook)
- (when (eq backend 'Bzr)
- (setq tempdir (make-temp-file "vc-test--state" t)
- process-environment (cons (format "BZR_HOME=%s" tempdir)
- process-environment)))
- (unwind-protect
- (progn
- ;; Cleanup.
- (add-hook
- 'vc-test--cleanup-hook
- `(lambda () (delete-directory ,default-directory 'recursive)))
-
- ;; Create empty repository.
- (make-directory default-directory)
- (vc-test--create-repo-function backend)
-
- (let ((tmp-name (expand-file-name "foo" default-directory)))
- ;; Check state of a nonexistent file.
-
- (message "vc-state2 %s" (vc-state tmp-name))
- (should (null (vc-state tmp-name)))
-
- ;; Write a new file. Check state.
- (write-region "foo" nil tmp-name nil 'nomessage)
-
- ;; nil: Mtn
- ;; unregistered: Bzr CVS Git Hg SVN RCS
- (message "vc-state3 %s %s" backend (vc-state tmp-name backend))
- (should (memq (vc-state tmp-name backend) '(nil unregistered)))
-
- ;; Register a file. Check state.
- (vc-register
- (list backend (list (file-name-nondirectory tmp-name))))
-
- ;; FIXME: nil is definitely wrong.
- ;; nil: SRC
- ;; added: Bzr CVS Git Hg Mtn SVN
- ;; up-to-date: RCS SCCS
- (message "vc-state4 %s" (vc-state tmp-name))
- (should (memq (vc-state tmp-name) '(nil added up-to-date)))
-
- ;; Unregister the file. Check state.
- (if (eq (vc-test--run-maybe-unsupported-function
- 'vc-test--unregister-function backend tmp-name)
- 'vc-not-supported)
- (message "vc-state5 unsupported")
- ;; unregistered: Bzr Git RCS Hg
- ;; unsupported: CVS Mtn SCCS SRC SVN
- (message "vc-state5 %s %s" backend (vc-state tmp-name backend))
- (should (memq (vc-state tmp-name backend)
- '(nil unregistered))))))
-
- ;; Save exit.
- (ignore-errors
- (if tempdir (delete-directory tempdir t))
- (run-hooks 'vc-test--cleanup-hook)))))
+ (ert-with-temp-directory tempdir
+ (let ((vc-handled-backends `(,backend))
+ (default-directory
+ (file-name-as-directory
+ (expand-file-name
+ (make-temp-name "vc-test") temporary-file-directory)))
+ (process-environment process-environment)
+ vc-test--cleanup-hook)
+ (when (eq backend 'Bzr)
+ (setq process-environment (cons (format "BZR_HOME=%s" tempdir)
+ process-environment)))
+ (unwind-protect
+ (progn
+ ;; Cleanup.
+ (add-hook
+ 'vc-test--cleanup-hook
+ (let ((dir default-directory))
+ (lambda () (delete-directory dir 'recursive))))
+
+ ;; Create empty repository.
+ (make-directory default-directory)
+ (vc-test--create-repo-function backend)
+
+ (let ((tmp-name (expand-file-name "foo" default-directory)))
+ ;; Check state of a nonexistent file.
+
+ (message "vc-state2 %s" (vc-state tmp-name))
+ (should (null (vc-state tmp-name)))
+
+ ;; Write a new file. Check state.
+ (write-region "foo" nil tmp-name nil 'nomessage)
+
+ ;; nil: Mtn
+ ;; unregistered: Bzr CVS Git Hg SVN RCS
+ (message "vc-state3 %s %s" backend (vc-state tmp-name backend))
+ (should (memq (vc-state tmp-name backend) '(nil unregistered)))
+
+ ;; Register a file. Check state.
+ (vc-register
+ (list backend (list (file-name-nondirectory tmp-name))))
+
+ ;; FIXME: nil is definitely wrong.
+ ;; nil: SRC
+ ;; added: Bzr CVS Git Hg Mtn SVN
+ ;; up-to-date: RCS SCCS
+ (message "vc-state4 %s" (vc-state tmp-name))
+ (should (memq (vc-state tmp-name) '(nil added up-to-date)))
+
+ ;; Unregister the file. Check state.
+ (if (eq (vc-test--run-maybe-unsupported-function
+ 'vc-test--unregister-function backend tmp-name)
+ 'vc-not-supported)
+ (message "vc-state5 unsupported")
+ ;; unregistered: Bzr Git RCS Hg
+ ;; unsupported: CVS Mtn SCCS SRC SVN
+ (message "vc-state5 %s %s" backend (vc-state tmp-name backend))
+ (should (memq (vc-state tmp-name backend)
+ '(nil unregistered))))))
+
+ ;; Save exit.
+ (ignore-errors
+ (run-hooks 'vc-test--cleanup-hook))))))
(defun vc-test--working-revision (backend)
"Check the working revision of a repository."
-
- (let ((vc-handled-backends `(,backend))
- (default-directory
- (file-name-as-directory
- (expand-file-name
- (make-temp-name "vc-test") temporary-file-directory)))
- (process-environment process-environment)
- tempdir
- vc-test--cleanup-hook)
- (when (eq backend 'Bzr)
- (setq tempdir (make-temp-file "vc-test--working-revision" t)
- process-environment (cons (format "BZR_HOME=%s" tempdir)
- process-environment)))
-
- (unwind-protect
- (progn
- ;; Cleanup.
- (add-hook
- 'vc-test--cleanup-hook
- `(lambda () (delete-directory ,default-directory 'recursive)))
-
- ;; Create empty repository. Check working revision of
- ;; repository, should be nil.
- (make-directory default-directory)
- (vc-test--create-repo-function backend)
-
- ;; FIXME: Is the value for SVN correct?
- ;; nil: Bzr CVS Git Hg Mtn RCS SCCS SRC
- ;; "0": SVN
- (message
- "vc-working-revision1 %s" (vc-working-revision default-directory))
- (should (member (vc-working-revision default-directory) '(nil "0")))
-
- (let ((tmp-name (expand-file-name "foo" default-directory)))
- ;; Check initial working revision, should be nil until
- ;; it's registered.
-
- (message "vc-working-revision2 %s" (vc-working-revision tmp-name))
- (should-not (vc-working-revision tmp-name))
-
- ;; Write a new file. Check working revision.
- (write-region "foo" nil tmp-name nil 'nomessage)
-
- (message "vc-working-revision3 %s" (vc-working-revision tmp-name))
- (should-not (vc-working-revision tmp-name))
-
- ;; Register a file. Check working revision.
- (vc-register
- (list backend (list (file-name-nondirectory tmp-name))))
-
- ;; XXX: nil is fine, at least in Git's case, because
- ;; `vc-register' only makes the file `added' in this case.
- ;; nil: Git Mtn
- ;; "0": Bzr CVS Hg SRC SVN
- ;; "1.1": RCS SCCS
- ;; "-1": Hg versions before 5 (probably)
- (message "vc-working-revision4 %s" (vc-working-revision tmp-name))
- (should (member (vc-working-revision tmp-name) '(nil "0" "1.1" "-1")))
-
- ;; TODO: Call `vc-checkin', and check the resulting
- ;; working revision. None of the return values should be
- ;; nil then.
-
- ;; Unregister the file. Check working revision.
- (if (eq (vc-test--run-maybe-unsupported-function
- 'vc-test--unregister-function backend tmp-name)
- 'vc-not-supported)
- (message "vc-working-revision5 unsupported")
- ;; nil: Bzr Git Hg RCS
- ;; unsupported: CVS Mtn SCCS SRC SVN
- (message "vc-working-revision5 %s" (vc-working-revision tmp-name))
- (should-not (vc-working-revision tmp-name)))))
-
- ;; Save exit.
- (ignore-errors
- (if tempdir (delete-directory tempdir t))
- (run-hooks 'vc-test--cleanup-hook)))))
+ (ert-with-temp-directory tempdir
+ (let ((vc-handled-backends `(,backend))
+ (default-directory
+ (file-name-as-directory
+ (expand-file-name
+ (make-temp-name "vc-test") temporary-file-directory)))
+ (process-environment process-environment)
+ vc-test--cleanup-hook)
+ (when (eq backend 'Bzr)
+ (setq process-environment (cons (format "BZR_HOME=%s" tempdir)
+ process-environment)))
+
+ (unwind-protect
+ (progn
+ ;; Cleanup.
+ (add-hook
+ 'vc-test--cleanup-hook
+ (let ((dir default-directory))
+ (lambda () (delete-directory dir 'recursive))))
+
+ ;; Create empty repository. Check working revision of
+ ;; repository, should be nil.
+ (make-directory default-directory)
+ (vc-test--create-repo-function backend)
+
+ ;; FIXME: Is the value for SVN correct?
+ ;; nil: Bzr CVS Git Hg Mtn RCS SCCS SRC
+ ;; "0": SVN
+ (message
+ "vc-working-revision1 %s" (vc-working-revision default-directory))
+ (should (member (vc-working-revision default-directory) '(nil "0")))
+
+ (let ((tmp-name (expand-file-name "foo" default-directory)))
+ ;; Check initial working revision, should be nil until
+ ;; it's registered.
+
+ (message "vc-working-revision2 %s" (vc-working-revision tmp-name))
+ (should-not (vc-working-revision tmp-name))
+
+ ;; Write a new file. Check working revision.
+ (write-region "foo" nil tmp-name nil 'nomessage)
+
+ (message "vc-working-revision3 %s" (vc-working-revision tmp-name))
+ (should-not (vc-working-revision tmp-name))
+
+ ;; Register a file. Check working revision.
+ (vc-register
+ (list backend (list (file-name-nondirectory tmp-name))))
+
+ ;; XXX: nil is fine, at least in Git's case, because
+ ;; `vc-register' only makes the file `added' in this case.
+ ;; nil: Git Mtn
+ ;; "0": Bzr CVS Hg SRC SVN
+ ;; "1.1": RCS SCCS
+ ;; "-1": Hg versions before 5 (probably)
+ (message "vc-working-revision4 %s" (vc-working-revision tmp-name))
+ (should (member (vc-working-revision tmp-name) '(nil "0" "1.1" "-1")))
+
+ ;; TODO: Call `vc-checkin', and check the resulting
+ ;; working revision. None of the return values should be
+ ;; nil then.
+
+ ;; Unregister the file. Check working revision.
+ (if (eq (vc-test--run-maybe-unsupported-function
+ 'vc-test--unregister-function backend tmp-name)
+ 'vc-not-supported)
+ (message "vc-working-revision5 unsupported")
+ ;; nil: Bzr Git Hg RCS
+ ;; unsupported: CVS Mtn SCCS SRC SVN
+ (message "vc-working-revision5 %s" (vc-working-revision tmp-name))
+ (should-not (vc-working-revision tmp-name)))))
+
+ ;; Save exit.
+ (ignore-errors
+ (run-hooks 'vc-test--cleanup-hook))))))
(defun vc-test--checkout-model (backend)
"Check the checkout model of a repository."
-
- (let ((vc-handled-backends `(,backend))
- (default-directory
- (file-name-as-directory
- (expand-file-name
- (make-temp-name "vc-test") temporary-file-directory)))
- (process-environment process-environment)
- tempdir
- vc-test--cleanup-hook)
- (when (eq backend 'Bzr)
- (setq tempdir (make-temp-file "vc-test--checkout-model" t)
- process-environment (cons (format "BZR_HOME=%s" tempdir)
- process-environment)))
-
- (unwind-protect
- (progn
- ;; Cleanup.
- (add-hook
- 'vc-test--cleanup-hook
- `(lambda () (delete-directory ,default-directory 'recursive)))
-
- ;; Create empty repository. Check repository checkout model.
- (make-directory default-directory)
- (vc-test--create-repo-function backend)
-
- ;; Surprisingly, none of the backends returns 'announce.
- ;; implicit: Bzr CVS Git Hg Mtn SRC SVN
- ;; locking: RCS SCCS
- (message
- "vc-checkout-model1 %s"
- (vc-checkout-model backend default-directory))
- (should (memq (vc-checkout-model backend default-directory)
- '(announce implicit locking)))
-
- (let ((tmp-name (expand-file-name "foo" default-directory)))
- ;; Check checkout model of a nonexistent file.
-
- ;; implicit: Bzr CVS Git Hg Mtn SRC SVN
- ;; locking: RCS SCCS
+ (ert-with-temp-directory tempdir
+ (let ((vc-handled-backends `(,backend))
+ (default-directory
+ (file-name-as-directory
+ (expand-file-name
+ (make-temp-name "vc-test") temporary-file-directory)))
+ (process-environment process-environment)
+ vc-test--cleanup-hook)
+ (when (eq backend 'Bzr)
+ (setq process-environment (cons (format "BZR_HOME=%s" tempdir)
+ process-environment)))
+
+ (unwind-protect
+ (progn
+ ;; Cleanup.
+ (add-hook
+ 'vc-test--cleanup-hook
+ (let ((dir default-directory))
+ (lambda () (delete-directory dir 'recursive))))
+
+ ;; Create empty repository. Check repository checkout model.
+ (make-directory default-directory)
+ (vc-test--create-repo-function backend)
+
+ ;; Surprisingly, none of the backends returns 'announce.
+ ;; implicit: Bzr CVS Git Hg Mtn SRC SVN
+ ;; locking: RCS SCCS
(message
- "vc-checkout-model2 %s" (vc-checkout-model backend tmp-name))
- (should (memq (vc-checkout-model backend tmp-name)
- '(announce implicit locking)))
+ "vc-checkout-model1 %s"
+ (vc-checkout-model backend default-directory))
+ (should (memq (vc-checkout-model backend default-directory)
+ '(announce implicit locking)))
- ;; Write a new file. Check checkout model.
- (write-region "foo" nil tmp-name nil 'nomessage)
+ (let ((tmp-name (expand-file-name "foo" default-directory)))
+ ;; Check checkout model of a nonexistent file.
- ;; implicit: Bzr CVS Git Hg Mtn SRC SVN
- ;; locking: RCS SCCS
- (message
- "vc-checkout-model3 %s" (vc-checkout-model backend tmp-name))
- (should (memq (vc-checkout-model backend tmp-name)
- '(announce implicit locking)))
+ ;; implicit: Bzr CVS Git Hg Mtn SRC SVN
+ ;; locking: RCS SCCS
+ (message
+ "vc-checkout-model2 %s" (vc-checkout-model backend tmp-name))
+ (should (memq (vc-checkout-model backend tmp-name)
+ '(announce implicit locking)))
- ;; Register a file. Check checkout model.
- (vc-register
- (list backend (list (file-name-nondirectory tmp-name))))
+ ;; Write a new file. Check checkout model.
+ (write-region "foo" nil tmp-name nil 'nomessage)
- ;; implicit: Bzr CVS Git Hg Mtn SRC SVN
- ;; locking: RCS SCCS
- (message
- "vc-checkout-model4 %s" (vc-checkout-model backend tmp-name))
- (should (memq (vc-checkout-model backend tmp-name)
- '(announce implicit locking)))
-
- ;; Unregister the file. Check checkout model.
- (if (eq (vc-test--run-maybe-unsupported-function
- 'vc-test--unregister-function backend tmp-name)
- 'vc-not-supported)
- (message "vc-checkout-model5 unsupported")
- ;; implicit: Bzr Git Hg
- ;; locking: RCS
- ;; unsupported: CVS Mtn SCCS SRC SVN
+ ;; implicit: Bzr CVS Git Hg Mtn SRC SVN
+ ;; locking: RCS SCCS
(message
- "vc-checkout-model5 %s" (vc-checkout-model backend tmp-name))
+ "vc-checkout-model3 %s" (vc-checkout-model backend tmp-name))
(should (memq (vc-checkout-model backend tmp-name)
- '(announce implicit locking))))))
+ '(announce implicit locking)))
+
+ ;; Register a file. Check checkout model.
+ (vc-register
+ (list backend (list (file-name-nondirectory tmp-name))))
- ;; Save exit.
- (ignore-errors
- (if tempdir (delete-directory tempdir t))
- (run-hooks 'vc-test--cleanup-hook)))))
+ ;; implicit: Bzr CVS Git Hg Mtn SRC SVN
+ ;; locking: RCS SCCS
+ (message
+ "vc-checkout-model4 %s" (vc-checkout-model backend tmp-name))
+ (should (memq (vc-checkout-model backend tmp-name)
+ '(announce implicit locking)))
+
+ ;; Unregister the file. Check checkout model.
+ (if (eq (vc-test--run-maybe-unsupported-function
+ 'vc-test--unregister-function backend tmp-name)
+ 'vc-not-supported)
+ (message "vc-checkout-model5 unsupported")
+ ;; implicit: Bzr Git Hg
+ ;; locking: RCS
+ ;; unsupported: CVS Mtn SCCS SRC SVN
+ (message
+ "vc-checkout-model5 %s" (vc-checkout-model backend tmp-name))
+ (should (memq (vc-checkout-model backend tmp-name)
+ '(announce implicit locking))))))
+
+ ;; Save exit.
+ (ignore-errors
+ (run-hooks 'vc-test--cleanup-hook))))))
(defun vc-test--rename-file (backend)
"Check the rename-file action."
-
- (let ((vc-handled-backends `(,backend))
- (default-directory
- (file-name-as-directory
- (expand-file-name
- (make-temp-name "vc-test") temporary-file-directory)))
- (process-environment process-environment)
- tempdir
- vc-test--cleanup-hook)
- (when (eq backend 'Bzr)
- (setq tempdir (make-temp-file "vc-test--rename-file" t)
- process-environment (cons (format "BZR_HOME=%s" tempdir)
- process-environment)))
-
- (unwind-protect
- (progn
- ;; Cleanup.
- (add-hook
- 'vc-test--cleanup-hook
- `(lambda () (delete-directory ,default-directory 'recursive)))
-
- ;; Create empty repository.
- (make-directory default-directory)
- (vc-test--create-repo-function backend)
-
- (let ((tmp-name (expand-file-name "foo" default-directory))
- (new-name (expand-file-name "bar" default-directory)))
- ;; Write a new file.
- (write-region "foo" nil tmp-name nil 'nomessage)
-
- ;; Register it. Renaming can fail otherwise.
- (vc-register
- (list backend (list (file-name-nondirectory tmp-name))))
-
- (vc-rename-file tmp-name new-name)
-
- (should (not (file-exists-p tmp-name)))
- (should (file-exists-p new-name))
-
- (should (equal (vc-state new-name)
- (if (memq backend '(RCS SCCS))
- 'up-to-date
- 'added)))))
-
- ;; Save exit.
- (ignore-errors
- (if tempdir (delete-directory tempdir t))
- (run-hooks 'vc-test--cleanup-hook)))))
+ (ert-with-temp-directory tempdir
+ (let ((vc-handled-backends `(,backend))
+ (default-directory
+ (file-name-as-directory
+ (expand-file-name
+ (make-temp-name "vc-test") temporary-file-directory)))
+ (process-environment process-environment)
+ vc-test--cleanup-hook)
+ (when (eq backend 'Bzr)
+ (setq process-environment (cons (format "BZR_HOME=%s" tempdir)
+ process-environment)))
+
+ (unwind-protect
+ (progn
+ ;; Cleanup.
+ (add-hook
+ 'vc-test--cleanup-hook
+ (let ((dir default-directory))
+ (lambda () (delete-directory dir 'recursive))))
+
+ ;; Create empty repository.
+ (make-directory default-directory)
+ (vc-test--create-repo-function backend)
+
+ (let ((tmp-name (expand-file-name "foo" default-directory))
+ (new-name (expand-file-name "bar" default-directory)))
+ ;; Write a new file.
+ (write-region "foo" nil tmp-name nil 'nomessage)
+
+ ;; Register it. Renaming can fail otherwise.
+ (vc-register
+ (list backend (list (file-name-nondirectory tmp-name))))
+
+ (vc-rename-file tmp-name new-name)
+
+ (should (not (file-exists-p tmp-name)))
+ (should (file-exists-p new-name))
+
+ (should (equal (vc-state new-name)
+ (if (memq backend '(RCS SCCS))
+ 'up-to-date
+ 'added)))))
+
+ ;; Save exit.
+ (ignore-errors
+ (run-hooks 'vc-test--cleanup-hook))))))
(declare-function log-edit-done "vc/log-edit")
(defun vc-test--version-diff (backend)
"Check the diff version of a repository."
-
- (let ((vc-handled-backends `(,backend))
- (default-directory
- (file-name-as-directory
- (expand-file-name
- (make-temp-name "vc-test") temporary-file-directory)))
- (process-environment process-environment)
- tempdir
- vc-test--cleanup-hook)
- (when (eq backend 'Bzr)
- (setq tempdir (make-temp-file "vc-test--version-diff" t)
- process-environment (cons (format "BZR_HOME=%s" tempdir)
- process-environment)))
- ;; git tries various approaches to guess a user name and email,
- ;; which can fail depending on how the system is configured.
- ;; Eg if the user account has no GECOS, git commit can fail with
- ;; status 128 "fatal: empty ident name".
- (when (memq backend '(Bzr Git))
- (setq process-environment (cons "EMAIL=john@doe.ee"
- process-environment)))
- (if (eq backend 'Git)
- (setq process-environment (append '("GIT_AUTHOR_NAME=A"
- "GIT_COMMITTER_NAME=C")
- process-environment)))
- (unwind-protect
- (progn
- ;; Cleanup.
- (add-hook
- 'vc-test--cleanup-hook
- `(lambda () (delete-directory ,default-directory 'recursive)))
-
- ;; Create empty repository. Check repository checkout model.
- (make-directory default-directory)
- (vc-test--create-repo-function backend)
-
- (let* ((tmp-name (expand-file-name "foo" default-directory))
- (files (list (file-name-nondirectory tmp-name))))
- ;; Write and register a new file.
- (write-region "originaltext" nil tmp-name nil 'nomessage)
- (vc-register (list backend files))
-
- (let ((buff (find-file tmp-name)))
- (with-current-buffer buff
+ (ert-with-temp-directory tempdir
+ (let ((vc-handled-backends `(,backend))
+ (default-directory
+ (file-name-as-directory
+ (expand-file-name
+ (make-temp-name "vc-test") temporary-file-directory)))
+ (process-environment process-environment)
+ vc-test--cleanup-hook)
+ (when (eq backend 'Bzr)
+ (setq process-environment (cons (format "BZR_HOME=%s" tempdir)
+ process-environment)))
+ ;; git tries various approaches to guess a user name and email,
+ ;; which can fail depending on how the system is configured.
+ ;; Eg if the user account has no GECOS, git commit can fail with
+ ;; status 128 "fatal: empty ident name".
+ (when (memq backend '(Bzr Git))
+ (setq process-environment (cons "EMAIL=john@doe.ee"
+ process-environment)))
+ (if (eq backend 'Git)
+ (setq process-environment (append '("GIT_AUTHOR_NAME=A"
+ "GIT_COMMITTER_NAME=C")
+ process-environment)))
+ (unwind-protect
+ (progn
+ ;; Cleanup.
+ (add-hook
+ 'vc-test--cleanup-hook
+ (let ((dir default-directory))
+ (lambda () (delete-directory dir 'recursive))))
+
+ ;; Create empty repository. Check repository checkout model.
+ (make-directory default-directory)
+ (vc-test--create-repo-function backend)
+
+ (let* ((tmp-name (expand-file-name "foo" default-directory))
+ (files (list (file-name-nondirectory tmp-name))))
+ ;; Write and register a new file.
+ (write-region "originaltext" nil tmp-name nil 'nomessage)
+ (vc-register (list backend files))
+
+ (let ((buff (find-file tmp-name)))
+ (with-current-buffer buff
+ (progn
+ ;; Optionally checkout file.
+ (when (memq backend '(RCS CVS SCCS))
+ (vc-checkout tmp-name))
+
+ ;; Checkin file.
+ (vc-checkin files backend)
+ (insert "Testing vc-version-diff")
+ (log-edit-done))))
+
+ ;; Modify file content.
+ (when (memq backend '(RCS CVS SCCS))
+ (vc-checkout tmp-name))
+ (write-region "updatedtext" nil tmp-name nil 'nomessage)
+
+ ;; Check version diff.
+ (vc-version-diff files nil nil)
+ (should (bufferp (get-buffer "*vc-diff*")))
+
+ (with-current-buffer "*vc-diff*"
(progn
- ;; Optionally checkout file.
- (when (memq backend '(RCS CVS SCCS))
- (vc-checkout tmp-name))
-
- ;; Checkin file.
- (vc-checkin files backend)
- (insert "Testing vc-version-diff")
- (log-edit-done))))
-
- ;; Modify file content.
- (when (memq backend '(RCS CVS SCCS))
- (vc-checkout tmp-name))
- (write-region "updatedtext" nil tmp-name nil 'nomessage)
-
- ;; Check version diff.
- (vc-version-diff files nil nil)
- (should (bufferp (get-buffer "*vc-diff*")))
-
- (with-current-buffer "*vc-diff*"
- (progn
- (let ((rawtext (buffer-substring-no-properties (point-min)
- (point-max))))
- (should (string-search "-originaltext" rawtext))
- (should (string-search "+updatedtext" rawtext)))))))
-
- ;; Save exit.
- (ignore-errors
- (if tempdir (delete-directory tempdir t))
- (run-hooks 'vc-test--cleanup-hook)))))
+ (let ((rawtext (buffer-substring-no-properties (point-min)
+ (point-max))))
+ (should (string-search "-originaltext" rawtext))
+ (should (string-search "+updatedtext" rawtext)))))))
+
+ ;; Save exit.
+ (ignore-errors
+ (run-hooks 'vc-test--cleanup-hook))))))
;; Create the test cases.
@@ -791,8 +778,9 @@ This checks also `vc-backend' and `vc-responsible-backend'."
',(intern
(format "vc-test-%s01-register" backend-string))))))
;; CVS calls vc-delete-file, which insists on prompting
- ;; "Really want to delete ...?"
- (skip-unless (not (eq 'CVS ',backend)))
+ ;; "Really want to delete ...?", and `vc-mtn.el' does not implement
+ ;; `delete-file' at all.
+ (skip-unless (not (memq ',backend '(CVS Mtn))))
(vc-test--rename-file ',backend))
(ert-deftest
@@ -805,6 +793,9 @@ This checks also `vc-backend' and `vc-responsible-backend'."
(ert-get-test
',(intern
(format "vc-test-%s01-register" backend-string))))))
+ ;; `vc-mtn.el' gives me:
+ ;; "Failed (status 1): mtn commit -m Testing vc-version-diff\n\n foo"
+ (skip-unless (not (memq ',backend '(Mtn))))
(vc-test--version-diff ',backend))
))))
diff --git a/test/lisp/wdired-tests.el b/test/lisp/wdired-tests.el
index 596c9881077..58caa1deda8 100644
--- a/test/lisp/wdired-tests.el
+++ b/test/lisp/wdired-tests.el
@@ -20,7 +20,9 @@
;;; Code:
(require 'ert)
+(require 'ert-x)
(require 'dired)
+(require 'dired-x)
(require 'wdired)
(defvar dired-query) ; Pacify byte compiler.
@@ -28,108 +30,100 @@
(ert-deftest wdired-test-bug32173-01 ()
"Test using non-nil wdired-use-interactive-rename.
Partially modifying a file name should succeed."
- (let* ((test-dir (make-temp-file "test-dir-" t))
- (test-file (concat (file-name-as-directory test-dir) "foo.c"))
- (replace "bar")
- (new-file (string-replace "foo" replace test-file))
- (wdired-use-interactive-rename t))
- (write-region "" nil test-file nil 'silent)
- (advice-add 'dired-query ; Don't ask confirmation to overwrite a file.
- :override
- (lambda (_sym _prompt &rest _args) (setq dired-query t))
- '((name . "advice-dired-query")))
- (let ((buf (find-file-noselect test-dir)))
- (unwind-protect
- (with-current-buffer buf
- (should (equal (dired-file-name-at-point) test-file))
- (dired-toggle-read-only)
- (kill-region (point) (progn (search-forward ".")
- (forward-char -1) (point)))
- (insert replace)
- (wdired-finish-edit)
- (should (equal (dired-file-name-at-point) new-file)))
- (if buf (kill-buffer buf))
- (delete-directory test-dir t)))))
+ (ert-with-temp-directory test-dir
+ (let* ((test-file (concat (file-name-as-directory test-dir) "foo.c"))
+ (replace "bar")
+ (new-file (string-replace "foo" replace test-file))
+ (wdired-use-interactive-rename t))
+ (write-region "" nil test-file nil 'silent)
+ (advice-add 'dired-query ; Don't ask confirmation to overwrite a file.
+ :override
+ (lambda (_sym _prompt &rest _args) (setq dired-query t))
+ '((name . "advice-dired-query")))
+ (let ((buf (find-file-noselect test-dir)))
+ (unwind-protect
+ (with-current-buffer buf
+ (should (equal (dired-file-name-at-point) test-file))
+ (dired-toggle-read-only)
+ (kill-region (point) (progn (search-forward ".")
+ (forward-char -1) (point)))
+ (insert replace)
+ (wdired-finish-edit)
+ (should (equal (dired-file-name-at-point) new-file)))
+ (if buf (kill-buffer buf)))))))
(ert-deftest wdired-test-bug32173-02 ()
"Test using non-nil wdired-use-interactive-rename.
Aborting an edit should leaving original file name unchanged."
- (let* ((test-dir (make-temp-file "test-dir-" t))
- (test-file (concat (file-name-as-directory test-dir) "foo.c"))
- (wdired-use-interactive-rename t))
- (write-region "" nil test-file nil 'silent)
- ;; Make dired-do-create-files-regexp a noop to mimic typing C-g
- ;; at its prompt before wdired-finish-edit returns.
- (advice-add 'dired-do-create-files-regexp
- :override
- (lambda (&rest _) (ignore))
- '((name . "advice-dired-do-create-files-regexp")))
- (let ((buf (find-file-noselect test-dir)))
- (unwind-protect
- (with-current-buffer buf
- (should (equal (dired-file-name-at-point) test-file))
- (dired-toggle-read-only)
- (kill-region (point) (progn (search-forward ".")
- (forward-char -1) (point)))
- (insert "bar")
- (wdired-finish-edit)
- (should (equal (dired-get-filename) test-file)))
- (if buf (kill-buffer buf))
- (delete-directory test-dir t)))))
+ (ert-with-temp-directory test-dir
+ (let* ((test-file (concat (file-name-as-directory test-dir) "foo.c"))
+ (wdired-use-interactive-rename t))
+ (write-region "" nil test-file nil 'silent)
+ ;; Make dired-do-create-files-regexp a noop to mimic typing C-g
+ ;; at its prompt before wdired-finish-edit returns.
+ (advice-add 'dired-do-create-files-regexp
+ :override
+ (lambda (&rest _) (ignore))
+ '((name . "advice-dired-do-create-files-regexp")))
+ (let ((buf (find-file-noselect test-dir)))
+ (unwind-protect
+ (with-current-buffer buf
+ (should (equal (dired-file-name-at-point) test-file))
+ (dired-toggle-read-only)
+ (kill-region (point) (progn (search-forward ".")
+ (forward-char -1) (point)))
+ (insert "bar")
+ (wdired-finish-edit)
+ (should (equal (dired-get-filename) test-file)))
+ (if buf (kill-buffer buf)))))))
(ert-deftest wdired-test-symlink-name ()
"Test the file name of a symbolic link.
The Dired and WDired functions returning the name should include
only the name before the link arrow."
- (let* ((test-dir (make-temp-file "test-dir-" t))
- (link-name "foo"))
- (let ((buf (find-file-noselect test-dir)))
- (unwind-protect
- (with-current-buffer buf
- (skip-unless
- ;; This check is for wdired, not symbolic links, so skip
- ;; it when make-symbolic-link fails for any reason (like
- ;; insufficient privileges).
- (ignore-errors (make-symbolic-link "./bar/baz" link-name) t))
- (revert-buffer)
- (let* ((file-name (dired-get-filename))
- (dir-part (file-name-directory file-name))
- (lf-name (concat dir-part link-name)))
- (should (equal file-name lf-name))
- (dired-toggle-read-only)
- (should (equal (wdired-get-filename) lf-name))
- (dired-toggle-read-only)))
- (if buf (kill-buffer buf))
- (delete-directory test-dir t)))))
+ (ert-with-temp-directory test-dir
+ (let* ((link-name "foo"))
+ (let ((buf (find-file-noselect test-dir)))
+ (unwind-protect
+ (with-current-buffer buf
+ (skip-unless
+ ;; This check is for wdired, not symbolic links, so skip
+ ;; it when make-symbolic-link fails for any reason (like
+ ;; insufficient privileges).
+ (ignore-errors (make-symbolic-link "./bar/baz" link-name) t))
+ (revert-buffer)
+ (let* ((file-name (dired-get-filename))
+ (dir-part (file-name-directory file-name))
+ (lf-name (concat dir-part link-name)))
+ (should (equal file-name lf-name))
+ (dired-toggle-read-only)
+ (should (equal (wdired-get-filename) lf-name))
+ (dired-toggle-read-only)))
+ (if buf (kill-buffer buf)))))))
(ert-deftest wdired-test-unfinished-edit-01 ()
"Test editing a file name without saving the change.
Finding the new name should be possible while still in
wdired-mode."
- (let* ((test-dir (make-temp-file "test-dir-" t))
- (test-file (concat (file-name-as-directory test-dir) "foo.c"))
- (replace "bar")
- (new-file (string-replace "foo" replace test-file)))
- (write-region "" nil test-file nil 'silent)
- (let ((buf (find-file-noselect test-dir)))
- (unwind-protect
- (with-current-buffer buf
- (should (equal (dired-file-name-at-point) test-file))
- (dired-toggle-read-only)
- (kill-region (point) (progn (search-forward ".")
- (forward-char -1) (point)))
- (insert replace)
- (should (equal (dired-get-filename) new-file)))
- (when buf
- (with-current-buffer buf
- ;; Prevent kill-buffer-query-functions from chiming in.
- (set-buffer-modified-p nil)
- (kill-buffer buf)))
- (delete-directory test-dir t)))))
-
-(defvar server-socket-dir)
-(declare-function dired-smart-shell-command "dired-x"
- (command &optional output-buffer error-buffer))
+ (ert-with-temp-directory test-dir
+ (let* ((test-file (concat (file-name-as-directory test-dir) "foo.c"))
+ (replace "bar")
+ (new-file (string-replace "foo" replace test-file)))
+ (write-region "" nil test-file nil 'silent)
+ (let ((buf (find-file-noselect test-dir)))
+ (unwind-protect
+ (with-current-buffer buf
+ (should (equal (dired-file-name-at-point) test-file))
+ (dired-toggle-read-only)
+ (kill-region (point) (progn (search-forward ".")
+ (forward-char -1) (point)))
+ (insert replace)
+ (should (equal (dired-get-filename) new-file)))
+ (when buf
+ (with-current-buffer buf
+ ;; Prevent kill-buffer-query-functions from chiming in.
+ (set-buffer-modified-p nil)
+ (kill-buffer buf))))))))
(ert-deftest wdired-test-bug34915 ()
"Test editing when dired-listing-switches includes -F.
@@ -139,61 +133,61 @@ dired-move-to-end-of-filename handles indicator characters, it
suffices to compare the return values of dired-get-filename and
wdired-get-filename before and after editing."
;; FIXME: Add a test for a door (indicator ">") only under Solaris?
- (let* ((test-dir (make-temp-file "test-dir-" t))
- (server-socket-dir test-dir)
- (dired-listing-switches "-Fl")
- (dired-ls-F-marks-symlinks (eq system-type 'darwin))
- (buf (find-file-noselect test-dir)))
- (unwind-protect
- (progn
- (with-current-buffer buf
- (dired-create-empty-file "foo")
- (set-file-modes "foo" (file-modes-symbolic-to-number "+x"))
- (make-symbolic-link "foo" "bar")
- (make-directory "foodir")
- (require 'dired-x)
- (dired-smart-shell-command "mkfifo foopipe")
- (server-force-delete)
- ;; FIXME? This seems a heavy-handed way of making a socket.
- (server-start) ; Add a socket file.
- (kill-buffer buf))
- (dired test-dir)
- (dired-toggle-read-only)
- (let (names)
- ;; Test that the file names are the same in Dired and WDired.
- (while (not (eobp))
- (should (equal (dired-get-filename 'no-dir t)
- (wdired-get-filename t)))
- (insert "w")
- (push (wdired-get-filename t) names)
- (dired-next-line 1))
- (wdired-finish-edit)
- ;; Test that editing the file names ignores the indicator
- ;; character.
- (let (dir)
- (while (and (dired-previous-line 1)
- (setq dir (dired-get-filename 'no-dir t)))
- (should (equal dir (pop names)))))))
- (kill-buffer (get-buffer test-dir))
- (server-force-delete)
- (delete-directory test-dir t))))
+ (ert-with-temp-directory test-dir
+ (let* ((dired-listing-switches "-Fl")
+ (dired-ls-F-marks-symlinks (eq system-type 'darwin))
+ (buf (find-file-noselect test-dir))
+ proc)
+ (unwind-protect
+ (progn
+ (with-current-buffer buf
+ (dired-create-empty-file "foo")
+ (set-file-modes "foo" (file-modes-symbolic-to-number "+x"))
+ (make-symbolic-link "foo" "bar")
+ (make-directory "foodir")
+ (dired-smart-shell-command "mkfifo foopipe")
+ (when (featurep 'make-network-process '(:family local))
+ (setq proc (make-network-process
+ :name "foo"
+ :family 'local
+ :server t
+ :service (expand-file-name "foosocket" test-dir))))
+ (kill-buffer buf))
+ (dired test-dir)
+ (dired-toggle-read-only)
+ (let (names)
+ ;; Test that the file names are the same in Dired and WDired.
+ (while (not (eobp))
+ (should (equal (dired-get-filename 'no-dir t)
+ (wdired-get-filename t)))
+ (insert "w")
+ (push (wdired-get-filename t) names)
+ (dired-next-line 1))
+ (wdired-finish-edit)
+ ;; Test that editing the file names ignores the indicator
+ ;; character.
+ (let (dir)
+ (while (and (dired-previous-line 1)
+ (setq dir (dired-get-filename 'no-dir t)))
+ (should (equal dir (pop names)))))))
+ (kill-buffer (get-buffer test-dir))
+ (ignore-errors (delete-process proc))))))
(ert-deftest wdired-test-bug39280 ()
"Test for https://debbugs.gnu.org/39280."
- (let* ((test-dir (make-temp-file "test-dir" 'dir))
- (fname "foo")
- (full-fname (expand-file-name fname test-dir)))
- (make-empty-file full-fname)
- (let ((buf (find-file-noselect test-dir)))
- (unwind-protect
- (with-current-buffer buf
- (dired-toggle-read-only)
- (dolist (old '(t nil))
- (should (equal fname (wdired-get-filename 'nodir old)))
- (should (equal full-fname (wdired-get-filename nil old))))
- (wdired-finish-edit))
- (if buf (kill-buffer buf))
- (delete-directory test-dir t)))))
+ (ert-with-temp-directory test-dir
+ (let* ((fname "foo")
+ (full-fname (expand-file-name fname test-dir)))
+ (make-empty-file full-fname)
+ (let ((buf (find-file-noselect test-dir)))
+ (unwind-protect
+ (with-current-buffer buf
+ (dired-toggle-read-only)
+ (dolist (old '(t nil))
+ (should (equal fname (wdired-get-filename 'nodir old)))
+ (should (equal full-fname (wdired-get-filename nil old))))
+ (wdired-finish-edit))
+ (if buf (kill-buffer buf)))))))
(provide 'wdired-tests)
;;; wdired-tests.el ends here
diff --git a/test/lisp/x-dnd-tests.el b/test/lisp/x-dnd-tests.el
new file mode 100644
index 00000000000..8856be79ebc
--- /dev/null
+++ b/test/lisp/x-dnd-tests.el
@@ -0,0 +1,203 @@
+;;; dnd-tests.el --- Tests for X DND support -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Tests for stuff in x-dnd.el that doesn't require a window system.
+
+;;; Code:
+
+(require 'x-dnd)
+(require 'cl-lib)
+
+(when (display-graphic-p)
+ (error "This test cannot be run under X"))
+
+;; Dummy replacements.
+
+(defconst x-dnd-tests-drag-window-xid 3948573
+ "XID of the drag window returned during the test.")
+
+(defvar x-dnd-tests-xds-property-value nil
+ "The value of the `XdndDirectSave0' window property.")
+
+(defconst x-dnd-tests-targets-table
+ (base64-decode-string
+ "bAArAKIBAAAGAB8AAABqAQAANgIAAJMCAAAFAwAABgMAAAEAkMJbAAEAINNbAAUAHwAAAGoBAAA2
+AgAAkwIAANkfAAALAB8AAABqAQAANgIAAJMCAADyAgAA2R8AANwfAADgHwAA4R8AAOIfAADjHwAA
+AQDQMAgCAQBQTggCAQCwe5IAAQDQmZIABgDyAgAA9wIAABcRAADgHwAAvSEAAI3AAAABAHC52AAB
+AGDY2AABAABq3QABAGBw3QAIAB8AAAA2AgAA8gIAANwfAADgHwAA4R8AAOIfAADjHwAAAQBwBOEA
+AQCACuEAAQAwLwUCAQDwPgUCAQBQxoQBAQCQ3YQBAQCQBYoBAQDACYoBAQCgMooBAQCgOIoBAQAf
+AAAAAQDATrcDAQAQ1LcDAQCw/sADAQAgBcEDAQBQt7oDAQAAUsIDAQCAc7wDAQAwerwDAQBAIKUE
+AQAALKUEAQDwfKUEAQDgg6UEAQCgjesEAQAAmusEAQCA7+sEAQCw9usECAAfAAAAagEAADYCAACT
+AgAABQMAAAYDAAATGwAAGhsAAA==")
+ "Predefined Motif targets table used to test the targets table parser.")
+
+(defconst x-dnd-tests-lispy-targets-table [[31 362 566 659 773 774] [6013584] [6017824]
+ [31 362 566 659 8153]
+ [31 362 566 659 754 8153 8156 8160 8161 8162 8163]
+ [34091216] [34098768] [9599920]
+ [9607632] [754 759 4375 8160 8637 49293]
+ [14203248] [14211168] [14510592]
+ [14512224] [31 566 754 8156 8160 8161 8162 8163]
+ [14746736] [14748288] [33894192] [33898224]
+ [25478736] [25484688] [25822608] [25823680]
+ [25834144] [25835680] [31] [62344896] [62379024]
+ [62979760] [62981408] [62568272] [63066624]
+ [62681984] [62683696] [77930560] [77933568]
+ [77954288] [77956064] [82546080] [82549248]
+ [82571136] [82572976] [31 362 566 659 773 774 6931 6938]]
+ "The expected result of parsing that targets table.")
+
+(defalias 'x-window-property
+ (lambda (prop &optional _frame type window-id delete-p _vector-ret-p)
+ (cond
+ ((and (equal prop "_MOTIF_DRAG_WINDOW")
+ (zerop window-id) (equal type "WINDOW"))
+ x-dnd-tests-drag-window-xid)
+ ((and (equal prop "_MOTIF_DRAG_TARGETS")
+ (equal type "_MOTIF_DRAG_TARGETS")
+ (equal window-id x-dnd-tests-drag-window-xid))
+ x-dnd-tests-targets-table)
+ ((and (equal prop "XdndDirectSave0")
+ (or (equal type "text/plain")
+ (equal type "AnyPropertyType")))
+ (prog1 x-dnd-tests-xds-property-value
+ (when delete-p
+ (setq x-dnd-tests-xds-property-value nil)))))))
+
+;; This test also serves to exercise most of the Motif value
+;; extraction code.
+(ert-deftest x-dnd-tests-read-xm-targets-table ()
+ (should (equal (x-dnd-xm-read-targets-table nil)
+ x-dnd-tests-lispy-targets-table)))
+
+;;; XDS tests.
+
+(defvar x-dnd-tests-xds-target-dir nil
+ "The name of the target directory where the file will be saved.")
+
+(defvar x-dnd-tests-xds-name nil
+ "The name that the dragged file should be saved under.")
+
+(defvar x-dnd-tests-xds-include-hostname nil
+ "Whether or not to include the hostname inside the XDS URI.")
+
+(defun x-dnd-tests-call-xds-converter ()
+ "Look up the XDS selection converter and call it.
+Return the result of the selection."
+ (let ((conv (cdr (assq 'XdndDirectSave0
+ selection-converter-alist))))
+ (should (functionp conv))
+ (funcall conv 'XdndDirectSave0 'XdndDirectSave0 nil)))
+
+(defalias 'x-begin-drag
+ (lambda (_targets &optional action frame &rest _)
+ ;; Verify that frame is either nil or a valid frame.
+ (when (and frame (not (frame-live-p frame)))
+ (signal 'wrong-type-argument frame))
+ (prog1 'XdndActionDirectSave
+ ;; Verify that the action is `XdndActionDirectSave'.
+ (should (eq action 'XdndActionDirectSave))
+ ;; Set the property value to the URI of the new file.
+ (should (and (stringp x-dnd-tests-xds-property-value)
+ (not (multibyte-string-p x-dnd-tests-xds-property-value))))
+ (let ((uri (if x-dnd-tests-xds-include-hostname
+ (format "file://%s%s" (system-name)
+ (expand-file-name x-dnd-tests-xds-property-value
+ x-dnd-tests-xds-target-dir))
+ (concat "file:///" (expand-file-name x-dnd-tests-xds-property-value
+ x-dnd-tests-xds-target-dir)))))
+ (setq x-dnd-tests-xds-property-value
+ (encode-coding-string (url-encode-url uri)
+ 'raw-text)))
+ ;; Convert the selection and verify its success.
+ (should (equal (x-dnd-tests-call-xds-converter)
+ '(STRING . "S"))))))
+
+(defalias 'x-change-window-property
+ (lambda (prop value &optional _frame type format outer-p _window-id)
+ ;; Check that the properties are the right type.
+ (should (equal prop "XdndDirectSave0"))
+ (should (equal value (encode-coding-string
+ x-dnd-tests-xds-name
+ (or file-name-coding-system
+ default-file-name-coding-system))))
+ (should (equal type "text/plain"))
+ (should (equal format 8))
+ (should (not outer-p))
+ (setq x-dnd-tests-xds-property-value value)))
+
+(defalias 'x-delete-window-property
+ (lambda (&rest _args)
+ ;; This function shouldn't ever be reached during XDS.
+ (setq x-dnd-tests-xds-property-value nil)))
+
+(defun x-dnd-tests-do-direct-save-internal (include-hostname)
+ "Test the behavior of `x-dnd-do-direct-save'.
+Make it perform a direct save to a randomly generated directory,
+and check that the file exists. If INCLUDE-HOSTNAME, include the
+hostname in the target URI."
+ (let ((x-dnd-tests-xds-include-hostname include-hostname)
+ (x-dnd-tests-xds-target-dir
+ (file-name-as-directory (expand-file-name
+ (make-temp-name "x-dnd-test")
+ temporary-file-directory)))
+ (original-file (expand-file-name
+ (make-temp-name "x-dnd-test")
+ temporary-file-directory))
+ (x-dnd-tests-xds-name (make-temp-name "x-dnd-test-target")))
+ ;; The call to `gui-set-selection' is only used for providing the
+ ;; conventional `text/uri-list' target and can be ignored.
+ (cl-flet ((gui-set-selection #'ignore))
+ (unwind-protect
+ (progn
+ ;; Touch `original-file' if it doesn't exist.
+ (unless (file-exists-p original-file)
+ (write-region "" 0 original-file))
+ ;; Create `x-dnd-tests-xds-target-dir'.
+ (make-directory x-dnd-tests-xds-target-dir)
+ ;; Start the direct save and verify it returns the correct action.
+ (should (eq (x-dnd-do-direct-save original-file
+ x-dnd-tests-xds-name
+ nil nil)
+ 'XdndActionDirectSave))
+ ;; Now verify that the new file exists.
+ (should (file-exists-p
+ (expand-file-name x-dnd-tests-xds-name
+ x-dnd-tests-xds-target-dir)))
+ ;; The XDS protocol makes very clear that the window
+ ;; property must be deleted after the drag-and-drop
+ ;; operation completes.
+ (should (not x-dnd-tests-xds-property-value)))
+ ;; Clean up after ourselves.
+ (ignore-errors
+ (delete-file original-file))
+ (ignore-errors
+ (delete-directory x-dnd-tests-xds-target-dir t))))))
+
+(ert-deftest x-dnd-tests-do-direct-save ()
+ ;; TODO: add tests for application/octet-stream transfer.
+ (x-dnd-tests-do-direct-save-internal nil)
+ ;; Test with both kinds of file: URIs, since different programs
+ ;; generate different kinds.
+ (x-dnd-tests-do-direct-save-internal t))
+
+(provide 'x-dnd-tests)
+;;; x-dnd-tests.el ends here
diff --git a/test/lisp/xml-tests.el b/test/lisp/xml-tests.el
index eecf6406fb8..748f1e39446 100644
--- a/test/lisp/xml-tests.el
+++ b/test/lisp/xml-tests.el
@@ -97,7 +97,7 @@
((("FOOBAR:" . "something") nil "hi there"))
((FOOBAR:something nil "hi there"))))
"List of strings which are parsed using namespace expansion.
-Parser is called with and without 'symbol-qnames argument.")
+Parser is called with and without `symbol-qnames' argument.")
(ert-deftest xml-parse-tests ()
"Test XML parsing."
diff --git a/test/lisp/yank-media-tests.el b/test/lisp/yank-media-tests.el
new file mode 100644
index 00000000000..4487ae150da
--- /dev/null
+++ b/test/lisp/yank-media-tests.el
@@ -0,0 +1,38 @@
+;;; yank-media-tests.el --- Tests for yank-media.el -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'yank-media)
+(require 'ert)
+(require 'ert-x)
+
+(ert-deftest test-utf-16 ()
+ (should-not (yank-media--utf-16-p "f"))
+ (should-not (yank-media--utf-16-p "fo"))
+ (should-not (yank-media--utf-16-p "\000ofo"))
+ (should (eq (yank-media--utf-16-p "\000o\000o") 'utf-16-be))
+ (should (eq (yank-media--utf-16-p "o\000o\000") 'utf-16-le))
+ (should-not (yank-media--utf-16-p "o\000\000o")))
+
+;;; yank-media-tests.el ends here