diff --git a/.hgignore b/.hgignore
index a152158c3b479f42ba0afe941983380df9164082_LmhnaWdub3Jl..9eace7214a4cb5e74113ecb7be7d1f1e1bba0169_LmhnaWdub3Jl 100644
--- a/.hgignore
+++ b/.hgignore
@@ -20,3 +20,5 @@
 .*.log\..*
 .*/\.pytest_cache/
 ^\.vscode/sftp\.json
+^build/
+^secrules.egg-info/
diff --git a/securityrules.py b/securityrules.py
deleted file mode 100644
index a152158c3b479f42ba0afe941983380df9164082_c2VjdXJpdHlydWxlcy5weQ==..0000000000000000000000000000000000000000
--- a/securityrules.py
+++ /dev/null
@@ -1,164 +0,0 @@
-# -*- coding: iso-8859-1 -*-
-
-import sys
-import os
-import re
-import argparse
-import importlib
-
-DEBUG = False
-if DEBUG:
-    import debugpy
-
-    # 5678 is the default attach port in the VS Code debug configurations.
-    # Unless a host and port are specified, host defaults to 127.0.0.1
-    debugpy.configure(subProcess=False)
-
-    debugpy.listen(('0.0.0.0', 5678), in_process_debug_adapter=True)
-    print('Waiting for debugger attach')
-    debugpy.wait_for_client()
-    debugpy.breakpoint()
-    print('break on this line')
-
-
-all_rules = {}
-args = None
-
-
-def rules_exec(seclass, numrule=None, info=False, fo=None, export=None):
-    global all_rules, args
-    rules = all_rules[seclass][1]
-    m = all_rules[seclass][0]
-    if numrule is None:
-        for r in rules:
-            if info:
-                print(getattr(m, r).__name__)
-                print(getattr(m, r).__doc__)
-                print()
-            else:
-                getattr(m, r)(fo, export)
-    else:
-        for n in numrule:
-            rname = 'rule%s%02d' % (seclass[-2:], n)
-            if rname in rules:
-                if info:
-                    print(getattr(m, rname).__name__)
-                    print(getattr(m, rname).__doc__)
-                    print()
-                else:
-                    getattr(m, rname)(fo, export)
-
-
-class InflateRange(argparse.Action):
-    def __call__(self, parser, namespace, values, option_string=None):
-        lst = []
-        for string in values:   # type: ignore
-            string = string.replace('(', '')
-            string = string.replace(')', '')
-            if '-' in string or ':' in string:
-                string = string.replace(':', '-')
-                m = re.match(r'(\d+)(?:-(\d+))?$', string)
-                # ^ (or use .split('-'). anyway you like.)
-                if not m:
-                    raise argparse.ArgumentTypeError(
-                        "'"
-                        + string
-                        + "' is not a range of number. Expected forms like '0-5' or '2'."
-                    )
-                start = m.group(1)
-                end = m.group(2) or start
-                lst.extend(list(range(int(start, 10), int(end, 10) + 1)))
-            else:
-                string = string.replace(',', ' ')
-                for string in string.split(' '):
-                    if string:
-                        lst.append(int(string))
-            setattr(namespace, self.dest, lst)
-
-
-def load_rules(levels):
-    global all_rules
-    mods = [
-        fn[:-3]
-        for fn in os.listdir('./secrules')
-        if fn.startswith('rule') and fn[-1:].lower() == 'y'
-    ]
-    all_rules = {}
-    for modn in mods:
-        m = importlib.import_module('.' + modn, 'secrules')
-        # m = __import__('secrules.' + modn, globals(), locals(), ['*'], -1)
-        lst = [m, []]
-        for r in dir(m):
-            if r.startswith('rule'):
-                if (
-                    levels is None
-                    or not hasattr(getattr(m, r), 'rule_level')
-                    or getattr(m, r).rule_level in levels
-                ):
-                    lst[1].append(r)
-        all_rules[modn] = lst
-        # all_rules[modn] = (m, [r for r in dir(m) if r.startswith('rule')])
-
-
-def main():
-    global args
-    parser = argparse.ArgumentParser(description='security checker')
-    parser.add_argument(
-        '--output',
-        type=argparse.FileType('w'),
-        dest='fo',
-        metavar='out-file',
-        help='output file',
-        default=sys.stdout,
-    )
-    parser.add_argument(
-        '--class', type=int, dest='seclass', help='security class'
-    )
-    parser.add_argument(
-        '--rule',
-        action=InflateRange,
-        nargs='*',
-        dest='numrule',
-        help='rule number',
-    )
-    parser.add_argument(
-        '--export',
-        action='store_true',
-        dest='export',
-        default=False,
-        help='export format',
-    )
-    parser.add_argument(
-        '--info',
-        action='store_true',
-        dest='info',
-        default=False,
-        help='Rules info',
-    )
-    parser.add_argument(
-        '--level',
-        action=InflateRange,
-        nargs='*',
-        dest='levels',
-        help='rule levels',
-    )
-
-    args = parser.parse_args()
-
-    load_rules(args.levels)
-
-    if args.seclass is None:
-        if args.numrule is not None:
-            raise argparse.ArgumentTypeError('missing seclass argument')
-        lst = list(all_rules.keys())
-        lst.sort()
-        for seclass in lst:
-            #            seclass = 'rules%02d' % args.seclass
-            rules_exec(seclass, args.numrule, args.info, args.fo, args.export)
-    else:
-        seclass = 'rules%02d' % args.seclass
-        rules_exec(seclass, args.numrule, args.info, args.fo, args.export)
-
-
-if __name__ == '__main__':
-    main()