Repository: 8400TheHealthNetwork/HebSafeHarbor (language: python)

Issue:
only identifies the first name in a given paragraph
for a given free text paragraph:
 שרון הגיעה לבית החולים הדסה עם כאבים בחזה. לשרון נמדד לחץ דם נמוך בהדסה
 I get this result:
 <שם_> PERS הגיעה <ארגון_> ORG עם כאבים בחזה. לשרון נמדד לחץ דם נמוך <ארגון_> ORG
 it does recognize repeated organization's name but not a person's name


Discussion / hints:

Fix patch:
diff --git a/Dockerfile b/Dockerfile
index bda4623..33c46fd 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -10,12 +10,13 @@ RUN python3 -m venv /opt/venv
 ENV PATH="/opt/venv/bin:$PATH"
 
 COPY requirements.txt ./
-COPY requirements_server.txt ./
+COPY requirements-server.txt ./
 COPY setup.py ./
+COPY README.md ./
 COPY hebsafeharbor ./hebsafeharbor
 RUN python3 -m pip install --upgrade pip
 RUN python3 -m pip install -r requirements.txt --no-cache-dir
-RUN python3 -m pip install -r requirements_server.txt --no-cache-dir
+RUN python3 -m pip install -r requirements-server.txt --no-cache-dir
 RUN python3 setup.py install
 
 
@@ -27,5 +28,5 @@ COPY --from=compile-image /opt/venv /opt/venv
 # Make sure we use the virtualenv:
 ENV PATH="/opt/venv/bin:$PATH"
 #run server and expose port 8000 for listening
-EXPOSE 8080
+EXPOSE 8000
 ENTRYPOINT ["python","server.py"]
diff --git a/README.md b/README.md
index 20080e3..aae3ad8 100644
--- a/README.md
+++ b/README.md
@@ -4,9 +4,37 @@ A de-identification toolkit for clinical text in Hebrew.
 
 [![MIT license](https://img.shields.io/badge/license-MIT-brightgreen.svg)](http://opensource.org/licenses/MIT) ![Release](https://img.shields.io/github/v/release/8400TheHealthNetwork/HebSafeHarbor.svg) [![PyPI version](https://badge.fury.io/py/hebsafeharbor.svg)](https://badge.fury.io/py/hebsafeharbor) [![Pypi Downloads](https://img.shields.io/pypi/dm/hebsafeharbor.svg)](https://img.shields.io/pypi/dm/hebsafeharbor.svg) 
 
+HebSafeHarbor was developed according to the requirements described in הצעה למתווה התממה של טקסט רפואי - נמל מבטחים (read more [here](docs/))
+
+The toolkit integrates and uses open source libraries and assets, including [HebSpacy](https://github.com/8400TheHealthNetwork/HebSpacy) (that runs NER model based on [AlephBERT](https://arxiv.org/pdf/2104.04052.pdf), [Nemo](https://github.com/OnlpLab/NEMO-Corpus) and [BMC](https://www.cs.bgu.ac.il/~elhadad/nlpproj/naama/)), [Presidio](https://microsoft.github.io/presidio/), Wikipedia and public lexicons.
+
+📝 Demo website is available [here](https://hebsafeharbor-demo.azurewebsites.net/)
+
+## Contents
+ - [Installation](#installation) 
+ - [Getting started](#getting-started) 
+ - [Docker Compose](#docker-compose)
+ - [Server](#server)
+ - [Demo Application](#demo-application)
+ - [FAQ](#faq)
+
+
 ## Installation
 
-To install the package, clone the repo and install all dependencies, preferably in a virtual environment:
+To install the package, run the following commands - preferably in a virtual environment
+``` sh
+# Create conda env (optional)
+conda create --name hebsafeharbor python=3.8
+conda activate hebsafeharbor
+
+# Install HebSafeHarbor
+pip install hebsafeharbor
+
+# Download the he_ner_news_trf model used by hebsafeharbor
+pip install https://github.com/8400TheHealthNetwork/HebSpacy/releases/download/he_ner_news_trf-3.2.1/he_ner_news_trf-3.2.1-py3-none-any.whl
+```
+
+Alternatively, you may clone the repo and install all dependencies:
 
 ``` sh
 # Create conda env (optional)
@@ -40,13 +68,160 @@ output = hsh([doc])
 print(output)
 ```
 
-### Docker
-
-1. Run the following command to install and run the server and demo services:
+## Docker Compose
+The easiest way to consume HebSafeHarbor as a [service with a REST API](#server)  and [demo application](#demo-application) is through `docker-compose` setup.
 
+Run the `docker-compose` command against the `docker-compose.yml` file in the root directory to get the latest containers from Docker Hub
 ```sh
 docker-compose up -d --build
 ```
+Navigate in the browser to <http://server.localhost/docs> to access the service swagger.
+Navigate in the browser to <http://demo.localhost> to test the demo application.
+
+
+#### Development mode
+To run the containers against the repo's code, run the following command:
+```sh
+docker-compose -f docker-compose-development.yml up -d --build
+```
+
+
+## Server
+### Local REST endpoint
+HebSafeHarbor can be consumed as a REST endpoint for the service powered by the [FastAPI](https://fastapi.tiangolo.com/) library.
+To run the service locally, you will need to first install the environment requirements as follows:  
+``` sh
+# Create conda env (optional)
+conda create --name hebsafeharbor-server python=3.8
+conda activate hebsafeharbor-server
+
+# Install dependencies
+pip install -r requirements.txt
+
+# Install server dependencies
+pip install -r requirements-server.txt
+```
+Once installation is done, run the following command to initiate the service:
+``` sh
+uvicorn server:app --reload
+```
+The service should be running at http://127.0.0.1:8000. Navigate to this URL and make sure you see the following message:
+```
+{"message":"Welcome to the Hebrew Safe Harbor!"}
+```
+Now go to http://127.0.0.1:8000/docs to see interactive API documentation (Swagger). 
+
+Alternatively, you can query the service directly by send POST requests to http://127.0.0.1:8000/query with the payload as described in the API documentation.
+
+### Server Docker
+To download and run the official release as a Docker container, run the following commands:
+```bash
+# Download image 
+docker pull hebsafeharbor/hebsafeharbor
+
+# Run container
+docker run --name hsh_server -d -p 8000:8000 hebsafeharbor/hebsafeharbor:latest
+```
+
+Alternatively, you can build and run the Docker container:
+```bash
+# Build image 
+docker build ./ --tag hebsafeharbor_server
+
+# Run container
+docker run --name hsh_server -d -p 8000:8000 hebsafeharbor_server
+```
+Navigate to http://localhost:8000 to validate the service is up and running. Similarly, you can go to http://localhost:8000/docs and http://localhost:8000/query.
+
+## Demo Application
+For experimentation and testing purposes, we provide a [Streamlit](https://streamlit.io/) demo application.
+![](images/demo_application.png)
+Note that the demo application functions as a (semi-)web client in the sense that it queries the remote REST endpoint and visualizes the results.
+
+In order for the demo to work and interact with the server application, you will need to set [`HSH_SERVER`](#what-is-the-server-docker-container-ip-address) environment variable to the REST point URL. 
+
+For example, assuming you are running the server as docker container:
+```
+[For Windows]
+$env:HSH_SERVER="http://localhost:8000"
+
+[For Linux]
+export HSH_SERVER=http://localhost:8000
+```
+
+### Run locally
+To run the demo locally, first install the requirements as follows:
+``` sh
+# Create conda env (optional)
+conda create --name hebsafeharbor_demo python=3.8
+conda activate hebsafeharbor_demo
+
+# Install dependencies
+pip install -r demo/requirements-streamlit.txt
+```
+Once installation is done, run the following command:
+``` sh
+streamlit run demo/demo_app.py
+```
+Now go to http://localhost:8501 to access the application
+
+### Demo Docker
+To download the official Docker container, run the following commands:
+```sh
+# Download image
+docker pull hebsafeharbor/demo_application
+
+# Run container - replace <SERVICE URL> with server url (e.g.,docker run -d -e HSH_SERVER=http://172.17.0.2:8000 -p 8501:8501 hebsafeharbor/demo_application:latest)
+docker run --name hsh_demo -d -e "HSH_SERVER=<SERVICE URL>" -p 8501:8501 hebsafeharbor/demo_application:latest
+```
+Alternatively, you can build and run the Docker container:
+```bash
+# Build image 
+docker build --name hsh_demo demo/. --tag hebsafeharbor_demo
+
+# Run container - replace <SERVICE URL> with server url (e.g.,docker run -d -e HSH_SERVER=http://172.17.0.2:8000 -p 8501:8501 hebsafeharbor_demo)
+docker run -d -e "HSH_SERVER=<SERVICE URL>" -p 8501:8501 hebsafeharbor_demo 
+```
+
+Navigate to http://localhost:8501 to access the demo application.
+
+## FAQ
+
+#### Why does the server contatiner exits with 137 error code?
+Note that the server container includes a trsnssformer model that consume more than 2gb of memory, increase Docker memory allocation to 6gb 
+
+Read more [here](https://forums.docker.com/t/how-to-increase-memory-size-that-is-available-for-a-docker-container/78483).
+
+#### What is the server (Docker container) IP address?
+Run the `network inspect bridge` command to get networking information regarding running dockers
+
+```sh
+docker network inspect bridge
+```
+Your response should look like the following:
+```sh
+[
+    {
+        "Name": "bridge",
+        ...
+        "Containers": {
+            "9611cad28701cfe0877c2bfed9ad2710202492de6d574d42a6714f439cf4f2d2": {
+                "Name": "hsh_server",
+                ...
+                "IPv4Address": "172.17.0.2/16",
+                ...
+            }
+        },
+      ...
+    }
+]
+```
+The IP address is under `IPv4Address` associated with `"Name": "hsh_server"` container under `Containers`. 
+In our case, **HSH_SERVER = 172.17.0.2**
+
+
+Read more [here](https://docs.docker.com/network/network-tutorial-standalone/)
+
+-----
 
-2. Navigate in the browser <http://localhost:8080/docs> to test the Server swagger
-3. Navigate in the browser <http://localhost:8501> to test the Demo app
+HebSafeHarbor is an open-source project developed by [8400 The Health Network](https://www.8400thn.org/).
diff --git a/demo/Dockerfile b/demo/Dockerfile
index 9435edc..4535a79 100644
--- a/demo/Dockerfile
+++ b/demo/Dockerfile
@@ -9,14 +9,14 @@ RUN python3 -m venv /opt/venv
 # Make sure we use the virtualenv:
 ENV PATH="/opt/venv/bin:$PATH"
 
-COPY requirements_streamlit.txt ./
+COPY requirements-streamlit.txt ./
 RUN python3 -m pip install --upgrade pip
-RUN python3 -m pip install -r requirements_streamlit.txt
+RUN python3 -m pip install -r requirements-streamlit.txt
 
 
 FROM python:3.9-slim AS build-image
 WORKDIR /usr/src/app
-COPY main_app.py ./
+COPY demo_app.py ./
 COPY utils.py ./
 COPY visualizer.py ./
 COPY --from=compile-image /opt/venv /opt/venv
@@ -24,4 +24,4 @@ COPY --from=compile-image /opt/venv /opt/venv
 ENV PATH="/opt/venv/bin:$PATH"
 #run app and expose port 8501 for listening
 EXPOSE 8501
-ENTRYPOINT ["streamlit","run", "main_app.py"]
+ENTRYPOINT ["streamlit","run", "demo_app.py"]
diff --git a/demo/main_app.py b/demo/demo_app.py
similarity index 92%
rename from demo/main_app.py
rename to demo/demo_app.py
index 9362058..da98a95 100644
--- a/demo/main_app.py
+++ b/demo/demo_app.py
@@ -1,5 +1,5 @@
 import json
-
+import os
 import requests
 import streamlit as st
 
@@ -8,9 +8,7 @@
 from visualizer import visualize_response
 
 DEFAULT_TEXT = "גדעון לבנה הגיע היום לבית החולים שערי צדק עם תלונות על כאבים בחזה"
-PATH = r"../resources_old"
-URL = "http://server:8080"
-URL = "http://localhost:8080"
+URL = os.getenv("HSH_SERVER", "http://localhost:8000")
 
 def run():
     st.title("Hebrew Safe Harbor demo application")
@@ -30,6 +28,7 @@ def run():
         submitted = st.form_submit_button("Analyze")
 
         if submitted:
+            print(URL)
             if text is not None and len(text) > 0:
                 response = requests.post(f"{URL}/query", json=req_data)
                 content = json.loads(response.content)
@@ -42,7 +41,7 @@ def run():
                 if len(docs) == 1:
                     doc = docs[0]
                     visualize_response(text, doc)
-                else: # TODO handle server connectivity issues better...
+                else:
                     if response.status_code == 20:  # response consists of more than one doc
                         st.error("Expected a single text to process and visualize, but received more than one")
                     else:
diff --git a/demo/requirements_streamlit.txt b/demo/requirements-streamlit.txt
similarity index 100%
rename from demo/requirements_streamlit.txt
rename to demo/requirements-streamlit.txt
diff --git a/docker-compose-development.yml b/docker-compose-development.yml
new file mode 100644
index 0000000..86cee5b
--- /dev/null
+++ b/docker-compose-development.yml
@@ -0,0 +1,31 @@
+version: '3'
+
+services:
+  reverse-proxy:
+    image: traefik:v2.6
+    command: --api.insecure=true --providers.docker
+    ports:
+      - "80:80"
+      - "8080:8080"
+    volumes:
+      - /var/run/docker.sock:/var/run/docker.sock
+
+  server:
+    build: .
+    container_name: "hsh_server"
+    ports:
+      - "8000:8000"
+    labels:
+      - "traefik.enable=true"
+      - "traefik.http.routers.server.rule=Host(`server.localhost`)"
+
+  demo:
+    build: demo
+    container_name: "hsh_demo"
+    labels:
+      - "traefik.enable=true"
+      - "traefik.http.routers.demo.rule=Host(`demo.localhost`)"
+    environment:
+      - HSH_SERVER=http://server:8000
+    depends_on:
+      - server
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
index 95905c8..0e307cc 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,14 +1,31 @@
 version: '3'
 
 services:
-  demo:
-    build: demo
+  reverse-proxy:
+    image: traefik:v2.6
+    command: --api.insecure=true --providers.docker
     ports:
-      - 8501:8501
-    depends_on:
-      - server
+      - "80:80"
+      - "8080:8080"
+    volumes:
+      - /var/run/docker.sock:/var/run/docker.sock
 
   server:
-    build: .
+    image: hebsafeharbor/hebsafeharbor:latest
+    container_name: "hsh_server"
     ports:
-      - 8080:8080
+      - "8000:8000"
+    labels:
+      - "traefik.enable=true"
+      - "traefik.http.routers.server.rule=Host(`server.localhost`)"
+
+  demo:
+    image: hebsafeharbor/demo_application:latest
+    container_name: "hsh_demo"
+    labels:
+      - "traefik.enable=true"
+      - "traefik.http.routers.demo.rule=Host(`demo.localhost`)"
+    environment:
+      - HSH_SERVER=http://server:8000
+    depends_on:
+      - server
diff --git "a/\327\224\327\246\327\242\327\224 \327\234\327\236\327\252\327\225\327\225\327\224 \327\224\327\252\327\236\327\236\327\224 \327\251\327\234 \327\230\327\247\327\241\327\230 \327\250\327\244\327\225\327\220\327\231 - \327\240\327\236\327\234 \327\236\327\221\327\230\327\227\327\231\327\235.docx" "b/docs/\327\224\327\246\327\242\327\224 \327\234\327\236\327\252\327\225\327\225\327\224 \327\224\327\252\327\236\327\236\327\224 \327\251\327\234 \327\230\327\247\327\241\327\230 \327\250\327\244\327\225\327\220\327\231 - \327\240\327\236\327\234 \327\236\327\221\327\230\327\227\327\231\327\235.docx"
similarity index 100%
rename from "\327\224\327\246\327\242\327\224 \327\234\327\236\327\252\327\225\327\225\327\224 \327\224\327\252\327\236\327\236\327\224 \327\251\327\234 \327\230\327\247\327\241\327\230 \327\250\327\244\327\225\327\220\327\231 - \327\240\327\236\327\234 \327\236\327\221\327\230\327\227\327\231\327\235.docx"
rename to "docs/\327\224\327\246\327\242\327\224 \327\234\327\236\327\252\327\225\327\225\327\224 \327\224\327\252\327\236\327\236\327\224 \327\251\327\234 \327\230\327\247\327\241\327\230 \327\250\327\244\327\225\327\220\327\231 - \327\240\327\236\327\234 \327\236\327\221\327\230\327\227\327\231\327\235.docx"
diff --git a/hebsafeharbor/anonymizer/custom_operators/israeli_city_anonymizer_operator.py b/hebsafeharbor/anonymizer/custom_operators/israeli_city_anonymizer_operator.py
index 2fa713b..dabd12a 100644
--- a/hebsafeharbor/anonymizer/custom_operators/israeli_city_anonymizer_operator.py
+++ b/hebsafeharbor/anonymizer/custom_operators/israeli_city_anonymizer_operator.py
@@ -2,7 +2,9 @@
 
 from presidio_anonymizer.operators import OperatorType, Operator
 
-from hebsafeharbor.common.city_utils import ABOVE_THRESHOLD_CITIES_LIST, BELOW_THRESHOLD_CITIES_LIST
+from hebsafeharbor.common.city_utils import ABOVE_THRESHOLD_CITIES_LIST, BELOW_THRESHOLD_CITIES_LIST, \
+    ABBREVIATIONS_LIST, AMBIGOUS_ABOVE_THRESHOLD_CITIES_LIST
+
 
 class IsraeliCityAnonymizerOperator(Operator):
     """
@@ -21,6 +23,10 @@ def operate(self, text: str, params: Dict = None) -> str:
 
         if text in ABOVE_THRESHOLD_CITIES_LIST:
             return text
+        elif text in AMBIGOUS_ABOVE_THRESHOLD_CITIES_LIST:
+            return text
+        elif text in ABBREVIATIONS_LIST:
+            return text
         elif text in BELOW_THRESHOLD_CITIES_LIST:
             return "<מיקום_>"
         else:
diff --git a/hebsafeharbor/common/city_utils.py b/hebsafeharbor/common/city_utils.py
index 1e4f358..23f4405 100644
--- a/hebsafeharbor/common/city_utils.py
+++ b/hebsafeharbor/common/city_utils.py
@@ -1,1483 +1,1441 @@
-ABOVE_THRESHOLD_CITIES_LIST = [
-	"גבע בנימין",
-	"ג'לג'וליה",
-	"קרני שומרון",
-	"סאג'ור",
-	"לפיד",
-	"כפר האורנים",
-	"מעלות-תרשיחא",
-	"רמת ישי",
-	"אבו קורינאת",
-	"נווה דניאל",
-	"מוקייבלה",
-	"קרית ים",
-	"ברקת",
-	"אום אל-פחם",
-	"חולון",
-	"שבלי",
-	"אריאל",
-	"בת ים",
-	"גבעת אלה",
-	"יקיר",
-	"קרית מלאכי",
-	"רעננה",
-	"קודייראת א",
-	"נצרת",
-	"אל סייד",
-	"מעיליא",
-	"הרצליה",
-	"עכו",
-	"אטרש שבט",
-	"שגב-שלום",
-	"ג'דיידה-מכר",
-	"תפרח",
-	"בוקעאתא",
-	"ג'סר א-זרקא",
-	"חשמונאים",
-	"פסוטה",
-	"שגב",
-	"סעוה",
-	"כעביה",
-	"שלום",
-	"בית חשמונאי",
-	"גרביה",
-	"זרזיר",
-	"כפר יאסיף",
-	"ג'ת",
-	"אחוזת ברק",
-	"ניין",
-	"גבעת עדה",
-	"מסעדה",
-	"ביר אל",
-	"כעביה-טבאש-חג'אג'רה",
-	"הושעיה",
-	"בית שאן",
-	"דאלית אל-כרמל",
-	"כפר אדומים",
-	"הר אדר",
-	"הוואשלה שבט",
-	"אילת",
-	"נס ציונה",
-	"אעבלין",
-	"כפר סבא",
-	"קדומים",
-	"כפר ורדים",
-	"אעצם",
-	"רבבה",
-	"ירכא",
-	"דייר אל",
-	"באר יעקב",
-	"אבני חפץ",
-	"מסעודין אל",
-	"באקה אל-גרביה",
-	"מצפה רמון",
-	"בועיינה",
-	"תל שבע",
-	"קרית עקרון",
-	"כפר קרע",
-	"שתולים",
-	"אבו גוש",
-	"גדרה",
-	"אבו ג'ווייעד שבט",
-	"ג'ולס",
-	"ראש פינה",
-	"נאעורה",
-	"גבעת זאב",
-	"בוקייעה",
-	"קרית ביאליק",
-	"כרום",
-	"חג'אג'רה",
-	"רעות",
-	"עספיא",
-	"כסיפה",
-	"שער חפר",
-	"פרדס חנה-כרכור",
-	"כפר תבור",
-	"צור הדסה",
-	"בענה",
-	"ראשון לציון",
-	"כוכב יעקב",
-	"ברוכין",
-	"גבעת ברנר",
-	"כוכב יאיר",
-	"מבשרת ציון",
-	"מרכז שפירא",
-	"ביר אל-מכסור",
-	"עתלית",
-	"חורה",
-	"עפולה",
-	"בנימינה-גבעת עדה",
-	"גבעתיים",
-	"רמלה",
-	"פרדס חנה",
-	"יהוד",
-	"עילוט",
-	"בית יצחק-שער חפר",
-	"דימונה",
-	"נוקדים",
-	"גבעת שמואל",
-	"כרכור",
-	"אפרת",
-	"הוואשלה",
-	"יפיע",
-	"באקה אל",
-	"סייד",
-	"ג'דיידה",
-	"תקוע",
-	"עוזייר",
-	"פקיעין",
-	"היג'א",
-	"קרית שמונה",
-	"כפר כנא",
-	"מעגן מיכאל",
-	"מסעודין אל-עזאזמה",
-	"תל אביב",
-	"עץ אפרים",
-	"ג'סר א",
-	"כפר יונה",
-	"עמנואל",
-	"פחם",
-	"זמר",
-	"אור יהודה",
-	"עין מאהל",
-	"טייבה",
-	"יהוד-מונוסון",
-	"שייח' דנון",
-	"אלון שבות",
-	"אבו רובייעה",
-	"עלי זהב",
-	"ירוחם",
-	"מייסר",
-	"פרדסיה",
-	"דייר אל-אסד",
-	"שלומי",
-	"שערי תקווה",
-	"ערערה",
-	"קצר א",
-	"חצור הגלילית",
-	"מכסור",
-	"סייד שבט",
-	"סח'נין",
-	"נתיבות",
-	"ירושלים",
-	"עדי",
-	"מגדל העמק",
-	"כפר חב\"ד",
-	"קרית מוצקין",
-	"חורפיש",
-	"פתח תקווה",
-	"מג'דל שמס",
-	"יד בנימין",
-	"כאוכב אבו אל-היג'א",
-	"בנגב",
-	"נוף הגליל",
-	"קרית טבעון",
-	"מעלה עירון",
-	"מג'ד אל-כרום",
-	"טמרה",
-	"קלנסווה",
-	"נהריה",
-	"צופים",
-	"רהט",
-	"קרית ארבע",
-	"אורנית",
-	"אבו תלול",
-	"ראש העין",
-	"צאנע",
-	"נוג'ידאת",
-	"חריש",
-	"כפר כמא",
-	"סר",
-	"מעלות",
-	"בית ג'ן",
-	"כסרא",
-	"סולם",
-	"שבלי - אום אל-גנם",
-	"עין נקובא",
-	"נעלה",
-	"זנגריה",
-	"באר גנים",
-	"יבנאל",
-	"באר שבע",
-	"כרמל",
-	"טלמון",
-	"קיסריה",
-	"עיילבון",
-	"גוש חלב",
-	"צפת",
-	"ערד",
-	"עלי",
-	"אכסאל",
-	"מג'ד אל",
-	"אשקלון",
-	"כוכב השחר",
-	"ג'ש",
-	"אום בטין",
-	"קודייראת א-צאנעשבט",
-	"קרית אתא",
-	"מודיעין עילית",
-	"רמת גן",
-	"בנימינה",
-	"כאוכב אבו אל",
-	"צורן",
-	"מודיעין",
-	"מגאר",
-	"בועיינה-נוג'ידאת",
-	"אסד",
-	"גנם",
-	"עין קנייא",
-	"אבו רוקייק",
-	"עופרה",
-	"בסמת טבעון",
-	"אזור",
-	"נופית",
-	"בית אל",
-	"תל מונד",
-	"אבטין",
-	"טבאש",
-	"מיתר",
-	"זרקא",
-	"יצהר",
-	"אור עקיבא",
-	"רכסים",
-	"הוזייל",
-	"נשר",
-	"שפרעם",
-	"אבו רוקייק שבט",
-	"כפר קאסם",
-	"ע'ג'ר",
-	"ברכה",
-	"צור יצחק",
-	"קדימה-צורן",
-	"עראבה",
-	"מזרעה",
-	"אעצם שבט",
-	"דייר חנא",
-	"גבעת אבני",
-	"אבו קורינאת שבט",
-	"טייבה בעמק",
-	"בית דגן",
-	"טובא",
-	"לקיה",
-	"בת חפר",
-	"ביתר עילית",
-	"כסרא-סמיע",
-	"רחובות",
-	"שדרות",
-	"כפר מנדא",
-	"טובא-זנגריה",
-	"ביר הדאג'",
-	"אבו רובייעה שבט",
-	"בני עי\"ש",
-	"גני מודיעין",
-	"קדימה",
-	"אום אל",
-	"כאבול",
-	"פקיעין בוקייעה",
-	"פסגות",
-	"טירת כרמל",
-	"יאנוח",
-	"קרית אונו",
-	"זכרון יעקב",
-	"ברקן",
-	"שעב",
-	"שמשית",
-	"ג'ש גוש חלב",
-	"כפר שמריהו",
-	"אבו ג'ווייעד",
-	"סלמה",
-	"רמת השרון",
-	"אלעד",
-	"עזאזמה",
-	"בני ברק",
-	"טורעאן",
-	"קרית גת",
-	"חדרה",
-	"גן יבנה",
-	"אשדוד",
-	"גן נר",
-	"בסמ\"ה",
-	"אלקנה",
-	"אלעזר",
-	"צור משה",
-	"דאלית אל",
-	"קציר",
-	"מצפה יריחו",
-	"אליכין",
-	"יפו",
-	"כרמיאל",
-	"אופקים",
-	"תל אביב - יפו",
-	"חיפה",
-	"שילה",
-	"ערערה-בנגב",
-	"נתניה",
-	"קצר א-סר",
-	"שוהם",
-	"בית יצחק",
-	"בעמק",
-	"מזכרת בתיה",
-	"מגדל",
-	"מתן",
-	"דבוריה",
-	"מכר",
-	"גני תקווה",
-	"אלפי מנשה",
-	"קצרין",
-	"מודיעין-מכבים-רעות",
-	"טירה",
-	"יבנה",
-	"אבן יהודה",
-	"מונוסון",
-	"מכבים",
-	"יקנעם עילית",
-	"עומר",
-	"בית אריה",
-	"משהד",
-	"פדואל",
-	"מבוא חורון",
-	"פוריידיס",
-	"ראמה",
-	"כפר מצר",
-	"שבט",
-	"לוד",
-	"קרית יערים",
-	"מעלה אדומים",
-	"בית שמש",
-	"כפר ברא",
-	"יאנוח-ג'ת",
-	"תרשיחא",
-	"הוד השרון",
-	"הוזייל שבט",
-	"סביון",
-	"אבו סנאן",
-	"נחף",
-	"נוף איילון",
-	"ריינה",
-	"סמיע",
-	"להבים",
-	"רומת הייב",
-	"ניצן",
-	"אטרש",
-	"טבריה",
-]
-BELOW_THRESHOLD_CITIES_LIST = [
-	"ספיר",
-	"כפר אחים",
-	"מבוא דותן",
-	"ורד יריחו",
-	"בית העמק",
-	"באר טוביה",
-	"כפר חיטים",
-	"תראבין א-צאנעישוב",
-	"ורדון",
-	"בני נצרים",
-	"גן השומרון",
-	"שחרות",
-	"כפר חיים",
-	"דפנה",
-	"גרופית",
-	"לפידות",
-	"גבולות",
-	"בית שקמה",
-	"עין הבשור",
-	"מסלול",
-	"נערן",
-	"עין אל-אסד",
-	"מורן",
-	"רמת צבי",
-	"בית עובד",
-	"קורנית",
-	"מסד",
-	"רמת רזיאל",
-	"מולדת",
-	"און",
-	"עין זיוון",
-	"דלתון",
-	"כפר נוער",
-	"יפעת",
-	"מעלה החמישה",
-	"גשר",
-	"עין יעקב",
-	"חמרה",
-	"זוהר",
-	"גאליה",
-	"רינתיה",
-	"שלווה במדבר",
-	"חגי",
-	"לכיש",
-	"גבעת שמש",
-	"משמר איילון",
-	"כפר ברוך",
-	"תימורים",
-	"חרב לאת",
-	"בית זית",
-	"בני עטרות",
-	"עין",
-	"נגבה",
-	"עין דור",
-	"קוממיות",
-	"ברקאי",
-	"נווה ימין",
-	"תל יוסף",
-	"נצר חזני",
-	"נגוהות",
-	"אבו עמרה שבט",
-	"נווה עובד",
-	"אל-עזי",
-	"עין הוד",
-	"עזריה",
-	"מאיר שפיה",
-	"ריחן",
-	"שרונה",
-	"יהל",
-	"ניר ח\"ן",
-	"עוקבי בנו עוקבה",
-	"מצפה שלם",
-	"גבעת חיים מאוחד",
-	"הגושרים",
-	"כפר סאלד",
-	"כפר בלום",
-	"גנות",
-	"סגולה",
-	"זמרת",
-	"משמר הירדן",
-	"פוריה",
-	"מתת",
-	"תושיה",
-	"רוויה",
-	"בארותיים",
-	"צורית",
-	"אבו עמאר",
-	"אליפלט",
-	"נאות הכיכר",
-	"גלעד",
-	"שדמה",
-	"שורש",
-	"רבדים",
-	"בית חנניה",
-	"כפר גלעדי",
-	"נחליאל",
-	"עמיחי",
-	"חספין",
-	"נירית",
-	"נחשונים",
-	"קבועה שבט",
-	"בית הלל",
-	"כפר הנגיד",
-	"מדרשת בן גוריון",
-	"פוריה עילית",
-	"ניר ישראל",
-	"אבו עמאר שבט",
-	"חפצי-בה",
-	"חמרייה",
-	"מרחב עם",
-	"כפר חרוב",
-	"גבע כרמל",
-	"לבנים",
-	"אורנים",
-	"אדמית",
-	"אורים",
-	"צוקי ים",
-	"סנסנה",
-	"חוקוק",
-	"גבעת כ\"ח",
-	"עין המפרץ",
-	"שפיר",
-	"אחווה",
-	"נווה ים",
-	"איתנים",
-	"צפריה",
-	"הראל",
-	"טל-אל",
-	"טירת צבי",
-	"נירים",
-	"מצדות יהודה",
-	"מחנה יהודית",
-	"מעלה גמלא",
-	"כפר רופין",
-	"כפר מנחם",
-	"גדות",
-	"נתיב הגדוד",
-	"שומרה",
-	"עוצם",
-	"כפר הס",
-	"יפית",
-	"שובה",
-	"גן שמואל",
-	"שקף",
-	"אום אל-קוטוף",
-	"משמר דוד",
-	"קדר",
-	"זכריה",
-	"תלמי אלעזר",
-	"בית יהושע",
-	"אחיסמך",
-	"געש",
-	"כנות",
-	"ניר בנים",
-	"גיתית",
-	"אושה",
-	"לוזית",
-	"פקיעין חדשה",
-	"אורה",
-	"מי עמי",
-	"רמת מגשימים",
-	"מכמורת",
-	"עראמשה",
-	"משמר הנגב",
-	"דייר ראפאת",
-	"מחנה טלי",
-	"אמנון",
-	"שבי דרום",
-	"נחלים",
-	"גן שורק",
-	"נעורים",
-	"גיבתון",
-	"גינתון",
-	"דברת",
-	"ניר צבי",
-	"אחיטוב",
-	"אייל",
-	"כפר דניאל",
-	"כפר יהושע",
-	"סואעד חמרייה",
-	"לי",
-	"אלון הגליל",
-	"חרשים",
-	"אבנת",
-	"כפר בן נון",
-	"כפר גליקסון",
-	"רמות מנשה",
-	"ניצני סיני",
-	"יובלים",
-	"גן יאשיה",
-	"עין השופט",
-	"אשדות יעקב",
-	"נטור",
-	"שדה אליהו",
-	"ציפורי",
-	"עין גדי",
-	"אבשלום",
-	"מרחביה מושב",
-	"כרם יבנה",
-	"יסודות",
-	"בת עין",
-	"קוואעין שבט",
-	"בן עמי",
-	"נווה אילן",
-	"תלם",
-	"בית אלפא",
-	"רשפים",
-	"אשרת",
-	"מעלה עמוס",
-	"אדירים",
-	"מנרה",
-	"אלישיב",
-	"שדה עוזיהו",
-	"רמת דוד",
-	"נחלה",
-	"לוטן",
-	"כפר עציון",
-	"תאשור",
-	"ארגמן",
-	"אדורה",
-	"איתמר",
-	"חד-נס",
-	"שדה אילן",
-	"הדר עם",
-	"יפתח",
-	"בית יוסף",
-	"יושיביה",
-	"נווה ירק",
-	"רביד",
-	"נחושה",
-	"עזריקם",
-	"נהורה",
-	"תלמי יפה",
-	"שדמות דבורה",
-	"בארות יצחק",
-	"קדרון",
-	"אומן",
-	"קרית יעריםמוסד",
-	"שדה דוד",
-	"בית גמליאל",
-	"הבונים",
-	"הרדוף",
-	"ניר יפה",
-	"בניה",
-	"כרם בן שמן",
-	"ח'ואלד שבט",
-	"סלעית",
-	"ברעם",
-	"אשכולות",
-	"יודפת",
-	"מחנה מרים",
-	"תל עדשים",
-	"כפר עבודה",
-	"מדרך עוז",
-	"הילה",
-	"כפר המכבי",
-	"יציץ",
-	"פתחיה",
-	"חד",
-	"כחלה",
-	"יקום",
-	"עינת",
-	"יעד",
-	"בית ינאי",
-	"אבן יצחק",
-	"גבעולים",
-	"חופית",
-	"שני",
-	"בני דרור",
-	"גילון",
-	"צרעה",
-	"גאולי תימן",
-	"אבו עבדון",
-	"איתן",
-	"ניר יצחק",
-	"מפלסים",
-	"כפר קיש",
-	"נחם",
-	"ניצני עוז",
-	"רומאנה",
-	"נחשולים",
-	"יד מרדכי",
-	"טמרה יזרעאל",
-	"קדרים",
-	"אביחיל",
-	"ניצנה קהילת חינוך",
-	"מבטחים",
-	"אביאל",
-	"אומץ",
-	"חוג'ייראת ד'הרה",
-	"מחנה יוכבד",
-	"תדהר",
-	"נועם",
-	"שדה בוקר",
-	"כנרת",
-	"עזוז",
-	"חבצלת השרון",
-	"רוחמה",
-	"אילניה",
-	"נתיב העשרה",
-	"מחנה הילה",
-	"משואה",
-	"עולש",
-	"כפר מרדכי",
-	"שער הגולן",
-	"שריד",
-	"באר אורה",
-	"עין כרם-בי\"ס חקלאי",
-	"חלוץ",
-	"שואבה",
-	"ראס אל",
-	"כנרת קבוצה",
-	"שיזף",
-	"חניאל",
-	"אתגר",
-	"כפר זיתים",
-	"דבורה",
-	"חוג'ייראת",
-	"מעלה לבונה",
-	"חולתה",
-	"גבת",
-	"קרית ענבים",
-	"ברק",
-	"צופית",
-	"גת קיבוץ",
-	"חמאם",
-	"אשל הנשיא",
-	"כמהין",
-	"דוב\"ב",
-	"ענב",
-	"יתד",
-	"ניר עציון",
-	"מירב",
-	"ביריה",
-	"גבעת שפירא",
-	"רמות השבים",
-	"שלווה",
-	"משמרות",
-	"גלאון",
-	"רגבים",
-	"לוחמי הגיטאות",
-	"החותרים",
-	"פרי גן",
-	"מצפה אילן",
-	"נטף",
-	"עין חצבה",
-	"אביטל",
-	"שבי שומרון",
-	"בר יוחאי",
-	"מירון",
-	"רתמים",
-	"בני דקלים",
-	"אשלים",
-	"כפר חנניה",
-	"אמירים",
-	"הזורעים",
-	"עין העמק",
-	"גדעונה",
-	"צופר",
-	"משמר השרון",
-	"עין ראפה",
-	"שפיים",
-	"בית אורן",
-	"כרכום",
-	"מבוא חמה",
-	"צוריאל",
-	"שדה ניצן",
-	"גברעם",
-	"שומריה",
-	"עין החורש",
-	"יזרעאל",
-	"רמת הכובש",
-	"עטרת",
-	"חירות",
-	"נאות סמדר",
-	"נווה",
-	"עטאוונה שבט",
-	"הזורע",
-	"עין גב",
-	"אחיהוד",
-	"כפר נטר",
-	"רעים",
-	"תומר",
-	"קלחים",
-	"גלעד אבן יצחק",
-	"מגשימים",
-	"תלמי אליהו",
-	"שדה יואב",
-	"אלמוג",
-	"גפן",
-	"עין ורד",
-	"רמות נפתלי",
-	"רגבה",
-	"אספר",
-	"כרי דשא",
-	"גת",
-	"ישרש",
-	"ישעי",
-	"יסעור",
-	"ג'נאביב שבט",
-	"שאר ישוב",
-	"בני ציון",
-	"עזר",
-	"בית הלוי",
-	"עין כרמל",
-	"תראבין א-צאנע שבט",
-	"בית נחמיה",
-	"יסוד המעלה",
-	"עופר",
-	"כפר עזה",
-	"זיתן",
-	"מבואות ים",
-	"פורת",
-	"שריגים לי-און",
-	"ניל\"י",
-	"בטחה",
-	"מנוף",
-	"ארבל",
-	"ניצנים",
-	"חוסן",
-	"כוכב מיכאל",
-	"בית חורון",
-	"צביה",
-	"נווה חריף",
-	"מגדלים",
-	"רמות מאיר",
-	"בן שמן מושב",
-	"בוסתן הגליל",
-	"מגדים",
-	"קבועה",
-	"עזריאל",
-	"אל-עריאן",
-	"מאוחד",
-	"כפר חושן",
-	"בקעות",
-	"תלמים",
-	"פצאל",
-	"מבואות יריחו",
-	"אמציה",
-	"גמזו",
-	"משמר העמק",
-	"אשבול",
-	"מרום גולן",
-	"ינון",
-	"אשדות יעקב מאוחד",
-	"קדמת צבי",
-	"כרמי יוסף",
-	"גבעת חיים",
-	"כפר מונש",
-	"עלמון",
-	"מכמנים",
-	"ייט\"ב",
-	"נופים",
-	"נווה אטי\"ב",
-	"בת הדר",
-	"שמרת",
-	"מעברות",
-	"עין חוד",
-	"זרחיה",
-	"כפר רוזנואלד זרעית",
-	"בני יהודה",
-	"מנשית זבדה",
-	"מגדל עוז",
-	"מלכיה",
-	"דבירה",
-	"כפר ביאליק",
-	"ביצרון",
-	"מאור",
-	"הר עמשא",
-	"מעונה",
-	"עמיעוז",
-	"רמת רחל",
-	"חורשים",
-	"ניר גלים",
-	"חרמש",
-	"תנובות",
-	"יבול",
-	"יד השמונה",
-	"דן",
-	"גדיש",
-	"שער העמקים",
-	"צנדלה",
-	"אפיניש",
-	"כמון",
-	"ביתן אהרן",
-	"טמרה",
-	"כפר רוזנואלד",
-	"משכיות",
-	"נס הרים",
-	"דליה",
-	"מעין צבי",
-	"דגניה א'",
-	"קהילת חינוך",
-	"מורשת",
-	"מוצא עילית",
-	"שמיר",
-	"בארי",
-	"דורות",
-	"חצבה",
-	"צור נתן",
-	"הר גילה",
-	"משאבי שדה",
-	"יגור",
-	"בית רבן",
-	"בית הערבה",
-	"אפיניש שבט",
-	"חוסנייה",
-	"זרעית",
-	"שפר",
-	"האון",
-	"בה",
-	"חנתון",
-	"אבני איתן",
-	"קלע",
-	"עוקבי",
-	"צאנע",
-	"גונן",
-	"סופה",
-	"קרית נטפים",
-	"איילת השחר",
-	"אלוני יצחק",
-	"שחר",
-	"בית השיטה",
-	"מעגן",
-	"יראון",
-	"גזר",
-	"כפר אביב",
-	"כפר הנוער הדתי",
-	"רם",
-	"לביא",
-	"יד נתן",
-	"אוהד",
-	"להבות הבשן",
-	"בית שערים",
-	"נווה זוהר",
-	"מבקיעים",
-	"נווה אור",
-	"נעמ\"ה",
-	"גיאה",
-	"לוטם",
-	"כרמי צור",
-	"סואעד",
-	"משואות יצחק",
-	"שדי חמד",
-	"אשתאול",
-	"להב",
-	"גבעת יערים",
-	"גורנות הגליל",
-	"כדורי",
-	"כפר ידידיה",
-	"תעוז",
-	"משגב עם",
-	"אבו קרינאת יישוב",
-	"גבעת ח\"ן",
-	"מחסיה",
-	"מעוז חיים",
-	"בן שמן",
-	"גילת",
-	"שבי ציון",
-	"חצב",
-	"אשדות יעקב איחוד",
-	"אלומה",
-	"מעין ברוך",
-	"נצאצרה",
-	"רותם",
-	"נווה מיכאל",
-	"שוקדה",
-	"קוטוף",
-	"גורן",
-	"כפר תפוח",
-	"שיטים",
-	"גבעות בר",
-	"רימונים",
-	"מושב",
-	"נורדיה",
-	"סער",
-	"עלומים",
-	"מסילות",
-	"מסילת ציון",
-	"רום",
-	"אבו סריחאן",
-	"הסוללים",
-	"אבו סריחאן שבט",
-	"דמיידה",
-	"רשפון",
-	"גשר הזיו",
-	"מחניים",
-	"יכיני",
-	"קוואעין",
-	"ג'נאביב",
-	"כרמל",
-	"עתניאל",
-	"חמדיה",
-	"תירוש",
-	"שניר",
-	"יד רמב\"ם",
-	"חגור",
-	"מחנה יתיר",
-	"נמרוד",
-	"חלץ",
-	"גבעתי",
-	"לבון",
-	"מתתיהו",
-	"כרם בן זמרה",
-	"מצפה נטופה",
-	"כפר ראש הנקרה",
-	"סתריה",
-	"גיזו",
-	"נטעים",
-	"שעלבים",
-	"תראבין א",
-	"דחי",
-	"מחנה יפה",
-	"מלילות",
-	"אבטליון",
-	"כפר הרי\"ף",
-	"גבעת ישעיהו",
-	"אבו עבדון שבט",
-	"בית עזרא",
-	"חיננית",
-	"רווחה",
-	"עין אל",
-	"שעל",
-	"מעון",
-	"ד'הרה",
-	"אביבים",
-	"בית צבי",
-	"ישע",
-	"עין חרוד",
-	"אלקוש",
-	"בית זרע",
-	"שושנת העמקים",
-	"עמיר",
-	"נבטים",
-	"קטורה",
-	"צוחר",
-	"נווה זיו",
-	"בית חלקיה",
-	"דריג'את",
-	"אלון מורה",
-	"גבעת ניל\"י",
-	"צרופה",
-	"עמיקם",
-	"נחשון",
-	"כנף",
-	"מישר",
-	"שקד",
-	"עלמה",
-	"עוזה",
-	"בן זכאי",
-	"גיניגר",
-	"כפר ורבורג",
-	"עדנים",
-	"סמר",
-	"בית לחם הגלילית",
-	"פעמי תש\"ז",
-	"גן שלמה",
-	"מכחול",
-	"חצור-אשדוד",
-	"תל יצחק",
-	"אודים",
-	"חברון",
-	"אבירים",
-	"מחולה",
-	"אסד",
-	"אור הנר",
-	"יטבתה",
-	"מענית",
-	"קרית שלמה",
-	"זבארגה",
-	"חרוצים",
-	"אחיעזר",
-	"גבעת עוז",
-	"איבים",
-	"כפר גלים",
-	"צפרירים",
-	"שלוחות",
-	"קדמה",
-	"שרשרת",
-	"פרזון",
-	"ניר דוד תל עמל",
-	"זנוח",
-	"נווה שלום",
-	"מעלה אפרים",
-	"מסדה",
-	"איחוד",
-	"שילת",
-	"מצפה אבי\"ב",
-	"גבעת יואב",
-	"בית אלעזרי",
-	"היוגב",
-	"תרום",
-	"כישור",
-	"ירחיב",
-	"בית זיד",
-	"צוקים",
-	"תלמי יחיאל",
-	"גני יוחנן",
-	"קשת",
-	"נופך",
-	"מחנה תל נוף",
-	"רנן",
-	"שדות ים",
-	"שדה נחמיה",
-	"נהלל",
-	"עיר אובות",
-	"שדה צבי",
-	"אירוס",
-	"מכורה",
-	"חגלה",
-	"חמד",
-	"שורשים",
-	"פדויים",
-	"כסלון",
-	"אשחר",
-	"כיסופים",
-	"כמאנה",
-	"ראס עלי",
-	"אלומות",
-	"שער מנשה",
-	"כפר רות",
-	"מבוא מודיעים",
-	"טפחות",
-	"גנות הדר",
-	"כפר ביל\"ו",
-	"יקנעם מושבה",
-	"מגידו",
-	"פדיה",
-	"פני חבר",
-	"ארסוף",
-	"כפר פינס",
-	"אביעזר",
-	"רקפת",
-	"ערוגות",
-	"שדמות מחולה",
-	"נחל עוז",
-	"אסד שבט",
-	"כפר גדעון",
-	"מנות",
-	"להבות חביבה",
-	"מרחביה",
-	"עצמון שגב",
-	"עין איילה",
-	"ניצנה",
-	"אלונים",
-	"עין שריד",
-	"גני טל",
-	"טנא",
-	"עריאן",
-	"גת רימון",
-	"אור הגנוז",
-	"ישוב",
-	"עין שמר",
-	"ירקונה",
-	"פלמחים",
-	"מגן",
-	"עגור",
-	"יחיעם",
-	"בקוע",
-	"אפיקים",
-	"שובל",
-	"ניר משה",
-	"עין צורים",
-	"יד חנה",
-	"דולב",
-	"נטע",
-	"קליה",
-	"דור",
-	"בצרה",
-	"חולית",
-	"כרם יבנה ישיבה",
-	"אליאב",
-	"חניתה",
-	"מעלה גלבוע",
-	"גינוסר",
-	"אלמגור",
-	"אלי-עד",
-	"גיתה",
-	"עיינות",
-	"פארן",
-	"רחוב",
-	"צובה",
-	"חבר",
-	"צאלים",
-	"ניצן ב'",
-	"געתון",
-	"עשרת",
-	"נתיב הל\"ה",
-	"נטועה",
-	"מרחביה קיבוץ",
-	"שדה משה",
-	"משען",
-	"כפר סילבר",
-	"עד",
-	"אניעם",
-	"מצובה",
-	"מוסד",
-	"בית חירות",
-	"שדות מיכה",
-	"ערב אל נעים",
-	"מבועים",
-	"אלי",
-	"מזרע",
-	"פוריה - כפר עבודה",
-	"אום אל",
-	"יונתן",
-	"כלנית",
-	"משמרת",
-	"יעל",
-	"תלמי יוסף",
-	"טל שחר",
-	"בנו עוקבה",
-	"בני ראם",
-	"אפיק",
-	"מקווה ישראל",
-	"בר גיורא",
-	"גבעון החדשה",
-	"ירדנה",
-	"חמדת",
-	"כנרת מושבה",
-	"חצור",
-	"מעגלים",
-	"נוב",
-	"מנוחה",
-	"יעף",
-	"רם-און",
-	"מטולה",
-	"תל קציר",
-	"לימן",
-	"עין חרוד מאוחד",
-	"כפר חסידים א'",
-	"אילות",
-	"אל-רום",
-	"אבן ספיר",
-	"אפק",
-	"יערה",
-	"עין חרוד איחוד",
-	"המעפיל",
-	"העוגן",
-	"תל עמל",
-	"טללים",
-	"חצרים",
-	"אביגדור",
-	"זרועה",
-	"בית חנן",
-	"כפר החורש",
-	"אלוני אבא",
-	"שדה ורבורג",
-	"שלומית",
-	"מדרשת רופין",
-	"קיבוץ",
-	"עין עירון",
-	"בית נקופה",
-	"ראס אל-עין",
-	"חיבת ציון",
-	"עברון",
-	"צלפון",
-	"יגל",
-	"גני הדר",
-	"תובל",
-	"רמות",
-	"פרוד",
-	"עבדון",
-	"כרם שלום",
-	"ניר עם",
-	"כרמי קטיף",
-	"ברכיה",
-	"מיטב",
-	"מזור",
-	"מטע",
-	"אלישמע",
-	"ניר דוד",
-	"מבוא ביתר",
-	"שדי אברהם",
-	"חפצי",
-	"ח'ואלד",
-	"אבן מנחם",
-	"בית רימון",
-	"ברוש",
-	"בלפוריה",
-	"נווה מבטח",
-	"עין יהב",
-	"דקל",
-	"אמונים",
-	"אבו קרינאת",
-	"אשדוד",
-	"ינוב",
-	"סעד",
-	"אל",
-	"כפר מסריק",
-	"כפר שמואל",
-	"שדי תרומות",
-	"זבארגה שבט",
-	"אדרת",
-	"בני דרום",
-	"תלמי ביל\"ו",
-	"בורגתה",
-	"הודיות",
-	"גן הדרום",
-	"משמר השבעה",
-	"שמעה",
-	"נאות גולן",
-	"בית מאיר",
-	"מרגליות",
-	"יקנעם",
-	"טל",
-	"שריגים",
-	"תמרת",
-	"נאות מרדכי",
-	"נוגה",
-	"כדיתה",
-	"בית ברל",
-	"נען",
-	"רמת השופט",
-	"שדה יצחק",
-	"עטאוונה",
-	"בית קמה",
-	"גבעת חיים איחוד",
-	"עין השלושה",
-	"שדה אליעזר",
-	"גן חיים",
-	"גבים",
-	"ראש צורים",
-	"שער אפרים",
-	"מעש",
-	"אחוזם",
-	"עידן",
-	"ריחאניה",
-	"כפר שמאי",
-	"חפץ חיים",
-	"ניר עקיבא",
-	"בצת",
-	"כפר זוהרים",
-	"פטיש",
-	"כפר מימון",
-	"הררית",
-	"דישון",
-	"שכניה",
-	"נס",
-	"כליל",
-	"אליקים",
-	"כפר הנשיא",
-	"נוה צוף",
-	"אילון",
-	"בת שלמה",
-	"ניר עוז",
-	"כפר יחזקאל",
-	"כפר סירקין",
-	"בת חן",
-	"קבוצה",
-	"כפר הרא\"ה",
-	"רביבים",
-	"אבו עמרה",
-	"עמוקה",
-	"הודיה",
-	"אלוני הבשן",
-	"ישיבה",
-	"אליפז",
-	"כברי",
-	"שתולה",
-	"סוסיה",
-	"מצר",
-	"פלך",
-	"רמת יוחנן",
-	"נווה איתן",
-	"גבע",
-	"גני עם",
-	"כפר מל\"ל",
-	"בי\"ס חקלאי",
-	"צבעון",
-	"באר מילכה",
-	"כפר חסידים ב'",
-	"מצפה",
-	"כרמיה",
-	"נורית",
-	"גבעת השלושה",
-	"זיקים",
-	"כפר אוריה",
-	"סאסא",
-	"מנחמיה",
-	"נצאצרה שבט",
-	"נצר סרני",
-	"קבוצת יבנה",
-	"נס עמים",
-	"שדה נחום",
-	"ניר אליהו",
-	"תקומה",
-	"גאולים",
-	"תל תאומים",
-	"גזית",
-	"מגל",
-	"כחל",
-	"שבט",
-	"גליל ים",
-	"מגן שאול",
-	"בית קשת",
-	"אבן שמואל",
-	"חולדה",
-	"כפר יעבץ",
-	"חדיד",
-	"עין הנצי\"ב",
-	"עמינדב",
-	"דגניה ב'",
-	"קרית יערים",
-	"כפר ויתקין",
-	"מצליח",
-	"אשבל",
-	"אורטל",
-	"גלגל",
-	"יישוב",
-	"טירת יהודה",
-	"שיבולים",
-	"עין כרם",
-	"אודם",
-	"בית ניר",
-	"בן שמן כפר נוער",
-	"מלכישוע",
-	"בחן",
-	"שזור",
-	"מעלה מכמש",
-	"ברור חיל",
-	"עמיעד",
-	"בית עוזיאל",
-	"נתיב השיירה",
-	"בית גוברין",
-	"עזי",
-	"רועי",
-	"בית הגדי",
-	"שדה יעקב",
-	"כורזים",
-	"מיצר",
-	"אורות",
-	"כרם מהר\"ל",
-	"עמקה",
-	"סואעד כמאנה שבט",
-	"בית עריף",
-	"משגב דב",
-	"גשור",
-	"מושבה",
-	"מלאה",
-	"עין תמר",
-	"זבדיאל",
-	"כפר טרומן",
-	"נווה אבות",
-	"חזון",
-	"פוריה - נווה עובד",
-	"יובל",
-	"ארז",
-	"כרמים",
-	"רחלים",
-]
-ABBREVIATIONS_LIST = ['‘עפ',
-'‘אר',
-'‘אשד',
-'‘אש',
-'ב”י',
-'ב”ש',
-'נתב”ג',
-'ב”ל',
-'ביש”א',
-'בי”ש',
-'ב”ב',
-'ע”ד',
-'יה”מ',
-'‘די',
-'‘אי',
-'אי”ש',
-'גלה”ע',
-'גלה”ת',
-'ג”ק',
-'‘חד',
-'‘חי',
-'‘הר',
-'הוד”ש',
-'‘חו',
-'חוב”ת',
-'י-מ',
-'יו”ש',
-'יש”ע',
-'‘קצ',
-'כפ”ס',
-'כ”ס',
-'ק”ג',
-'קמ”צ',
-'ק”א',
-'ק”ש',
-'לור”ם',
-'‘מס',
-'‘נה',
-'‘נצ',
-'נעמ”ה',
-'נ”ס',
-'‘נת',
-'נו”ש',
-'נוו”צ',
-'פ”ח',
-'פ”ת',
-'רכ”ס',
-'רמת”א',
-'רמא”ג',
-'רמב”ש',
-'ר”ג',
-'רמ”ג',
-'רג”ב',
-'רה”ג',
-'רמה”ג',
-'רמה”ש',
-'י”ס',
-'‘רח',
-'ראל”צ',
-'ראשל”צ',
-'רה”נ',
-'ר”פ',
-'ש”י',
-'שו”ש',
-'ת”א',
-'תה”ש',
-'‘טב',
-'ז”י',]
\ No newline at end of file
+ABOVE_THRESHOLD_CITIES_LIST = ["אבו ג'ווייעד",
+ "אבו ג'ווייעד שבט",
+ 'אבו גוש',
+ 'אבו סנאן',
+ 'אבו קורינאת',
+ 'אבו קורינאת שבט',
+ 'אבו רובייעה',
+ 'אבו רובייעה שבט',
+ 'אבו רוקייק',
+ 'אבו רוקייק שבט',
+ 'אבו תלול',
+ 'אבטין',
+ 'אבן יהודה',
+ 'אבני חפץ',
+ 'אום אל',
+ 'אום אל-פחם',
+ 'אום בטין',
+ 'אופקים',
+ 'אור יהודה',
+ 'אור עקיבא',
+ 'אורנית',
+ 'אחוזת ברק',
+ 'אטרש',
+ 'אטרש שבט',
+ 'אילת',
+ 'אכסאל',
+ 'אל סייד',
+ 'אלון שבות',
+ 'אליכין',
+ 'אלעד',
+ 'אלעזר',
+ 'אלפי מנשה',
+ 'אלקנה',
+ 'אסד',
+ 'אעבלין',
+ 'אעצם',
+ 'אעצם שבט',
+ 'אשדוד',
+ 'אשקלון',
+ 'באקה אל',
+ 'באקה אל-גרביה',
+ 'באר גנים',
+ 'באר יעקב',
+ 'באר שבע',
+ 'בועיינה',
+ "בועיינה-נוג'ידאת",
+ 'בוקייעה',
+ 'בוקעאתא',
+ 'ביר אל',
+ 'ביר אל-מכסור',
+ "ביר הדאג'",
+ 'בית אל',
+ 'בית אריה',
+ "בית ג'ן",
+ 'בית דגן',
+ 'בית חשמונאי',
+ 'בית יצחק',
+ 'בית יצחק-שער חפר',
+ 'בית שאן',
+ 'בית שמש',
+ 'ביתר עילית',
+ 'בנגב',
+ 'בני ברק',
+ 'בני עי"ש',
+ 'בנימינה',
+ 'בנימינה-גבעת עדה',
+ 'בסמ"ה',
+ 'בסמת טבעון',
+ 'בעמק',
+ 'בענה',
+ 'ברוכין',
+ 'ברקן',
+ 'בת חפר',
+ 'בת ים',
+ "ג'דיידה",
+ "ג'דיידה-מכר",
+ "ג'לג'וליה",
+ "ג'סר א",
+ "ג'סר א-זרקא",
+ "ג'ש",
+ "ג'ש גוש חלב",
+ "ג'ת",
+ 'גבע בנימין',
+ 'גבעת אבני',
+ 'גבעת אלה',
+ 'גבעת ברנר',
+ 'גבעת זאב',
+ 'גבעת עדה',
+ 'גבעת שמואל',
+ 'גבעתיים',
+ 'גדרה',
+ 'גן יבנה',
+ 'גן נר',
+ 'גני מודיעין',
+ 'גני תקווה',
+ 'גנם',
+ 'גרביה',
+ 'דאלית אל',
+ 'דאלית אל-כרמל',
+ 'דבוריה',
+ 'דייר אל',
+ 'דייר אל-אסד',
+ 'דייר חנא',
+ 'דימונה',
+ 'הוד השרון',
+ 'הוואשלה',
+ 'הוואשלה שבט',
+ 'הוזייל',
+ 'הוזייל שבט',
+ 'הושעיה',
+ "היג'א",
+ 'הר אדר',
+ 'הרצליה',
+ 'זכרון יעקב',
+ 'זמר',
+ 'זנגריה',
+ 'זרזיר',
+ 'זרקא',
+ "חג'אג'רה",
+ 'חדרה',
+ 'חולון',
+ 'חורה',
+ 'חורפיש',
+ 'חיפה',
+ 'חצור הגלילית',
+ 'חריש',
+ 'חשמונאים',
+ 'טבאש',
+ 'טבריה',
+ 'טובא',
+ 'טובא-זנגריה',
+ 'טורעאן',
+ 'טייבה',
+ 'טייבה בעמק',
+ 'טירה',
+ 'טירת כרמל',
+ 'טלמון',
+ 'טמרה',
+ 'יאנוח',
+ "יאנוח-ג'ת",
+ 'יבנאל',
+ 'יבנה',
+ 'יד בנימין',
+ 'יהוד',
+ 'יהוד-מונוסון',
+ 'יפו',
+ 'יפיע',
+ 'יצהר',
+ 'יקנעם עילית',
+ 'ירוחם',
+ 'ירושלים',
+ 'ירכא',
+ 'כאבול',
+ 'כאוכב אבו אל',
+ "כאוכב אבו אל-היג'א",
+ 'כוכב השחר',
+ 'כוכב יאיר',
+ 'כוכב יעקב',
+ 'כסיפה',
+ 'כסרא',
+ 'כסרא-סמיע',
+ 'כעביה',
+ "כעביה-טבאש-חג'אג'רה",
+ 'כפר אדומים',
+ 'כפר ברא',
+ 'כפר האורנים',
+ 'כפר ורדים',
+ 'כפר חב"ד',
+ 'כפר יאסיף',
+ 'כפר יונה',
+ 'כפר כמא',
+ 'כפר כנא',
+ 'כפר מנדא',
+ 'כפר מצר',
+ 'כפר סבא',
+ 'כפר קאסם',
+ 'כפר קרע',
+ 'כפר שמריהו',
+ 'כפר תבור',
+ 'כרום',
+ 'כרכור',
+ 'כרמיאל',
+ 'להבים',
+ 'לוד',
+ 'לקיה',
+ 'מבוא חורון',
+ 'מבשרת ציון',
+ "מג'ד אל",
+ "מג'ד אל-כרום",
+ "מג'דל שמס",
+ 'מגאר',
+ 'מגדל',
+ 'מגדל העמק',
+ 'מודיעין',
+ 'מודיעין עילית',
+ 'מודיעין-מכבים-רעות',
+ 'מונוסון',
+ 'מוקייבלה',
+ 'מזכרת בתיה',
+ 'מזרעה',
+ 'מכסור',
+ 'מסעודין אל',
+ 'מסעודין אל-עזאזמה',
+ 'מעגן מיכאל',
+ 'מעיליא',
+ 'מעלה אדומים',
+ 'מעלה עירון',
+ 'מעלות',
+ 'מעלות-תרשיחא',
+ 'מצפה יריחו',
+ 'מצפה רמון',
+ 'מרכז שפירא',
+ 'משהד',
+ 'נאעורה',
+ 'נהריה',
+ "נוג'ידאת",
+ 'נווה דניאל',
+ 'נוף איילון',
+ 'נוף הגליל',
+ 'נופית',
+ 'נוקדים',
+ 'נחף',
+ 'נס ציונה',
+ 'נעלה',
+ 'נצרת',
+ 'נתיבות',
+ 'נתניה',
+ "סאג'ור",
+ 'סביון',
+ 'סולם',
+ "סח'נין",
+ 'סייד',
+ 'סייד שבט',
+ 'סלמה',
+ 'סמיע',
+ 'סעוה',
+ "ע'ג'ר",
+ 'עוזייר',
+ 'עזאזמה',
+ 'עיילבון',
+ 'עילוט',
+ 'עין מאהל',
+ 'עין נקובא',
+ 'עין קנייא',
+ 'עכו',
+ 'עלי זהב',
+ 'עספיא',
+ 'עפולה',
+ 'עץ אפרים',
+ 'עראבה',
+ 'ערד',
+ 'ערערה',
+ 'ערערה-בנגב',
+ 'עתלית',
+ 'פדואל',
+ 'פוריידיס',
+ 'פחם',
+ 'פסוטה',
+ 'פקיעין',
+ 'פקיעין בוקייעה',
+ 'פרדס חנה',
+ 'פרדס חנה-כרכור',
+ 'פרדסיה',
+ 'פתח תקווה',
+ 'צאנע',
+ 'צופים',
+ 'צור הדסה',
+ 'צור יצחק',
+ 'צור משה',
+ 'צורן',
+ 'צפת',
+ 'קדימה-צורן',
+ 'קודייראת א',
+ 'קודייראת א-צאנעשבט',
+ 'קיסריה',
+ 'קלנסווה',
+ 'קציר',
+ 'קצר א-סר',
+ 'קצרין',
+ 'קרית אונו',
+ 'קרית ארבע',
+ 'קרית אתא',
+ 'קרית ביאליק',
+ 'קרית גת',
+ 'קרית טבעון',
+ 'קרית ים',
+ 'קרית יערים',
+ 'קרית מוצקין',
+ 'קרית מלאכי',
+ 'קרית עקרון',
+ 'קרית שמונה',
+ 'קרני שומרון',
+ 'ראמה',
+ 'ראש העין',
+ 'ראש פינה',
+ 'ראשון לציון',
+ 'רבבה',
+ 'רהט',
+ 'רומת הייב',
+ 'רחובות',
+ 'ריינה',
+ 'רכסים',
+ 'רמלה',
+ 'רמת גן',
+ 'רמת השרון',
+ 'רמת ישי',
+ 'רעננה',
+ 'שבלי',
+ 'שבלי - אום אל-גנם',
+ 'שגב-שלום',
+ 'שדרות',
+ 'שוהם',
+ "שייח' דנון",
+ 'שמשית',
+ 'שעב',
+ 'שער חפר',
+ 'שערי תקווה',
+ 'שפרעם',
+ 'שתולים',
+ 'תל אביב',
+ 'תל אביב - יפו',
+ 'תל מונד',
+ 'תל שבע',
+ 'תרשיחא']
+
+BELOW_THRESHOLD_CITIES_LIST = ['אבו סריחאן',
+ 'אבו סריחאן שבט',
+ 'אבו עבדון',
+ 'אבו עבדון שבט',
+ 'אבו עמאר',
+ 'אבו עמאר שבט',
+ 'אבו עמרה',
+ 'אבו עמרה שבט',
+ 'אבו קרינאת',
+ 'אבו קרינאת יישוב',
+ 'אבטליון',
+ 'אביבים',
+ 'אביגדור',
+ 'אביחיל',
+ 'אביטל',
+ 'אביעזר',
+ 'אבירים',
+ 'אבן יצחק',
+ 'אבן מנחם',
+ 'אבן ספיר',
+ 'אבן שמואל',
+ 'אבני איתן',
+ 'אבנת',
+ 'אדורה',
+ 'אדמית',
+ 'אודים',
+ 'אום אל',
+ 'אום אל-קוטוף',
+ 'אור הגנוז',
+ 'אור הנר',
+ 'אורים',
+ 'אורנים',
+ 'אושה',
+ 'אחווה',
+ 'אחוזם',
+ 'אחיהוד',
+ 'אחיטוב',
+ 'אחיסמך',
+ 'אחיעזר',
+ 'איבים',
+ 'איחוד',
+ 'איילת השחר',
+ 'אילות',
+ 'אירוס',
+ 'אל-עזי',
+ 'אל-עריאן',
+ 'אל-רום',
+ 'אלומה',
+ 'אלומות',
+ 'אלון הגליל',
+ 'אלון מורה',
+ 'אלוני אבא',
+ 'אלוני הבשן',
+ 'אלוני יצחק',
+ 'אלונים',
+ 'אלי-עד',
+ 'אליאב',
+ 'אליפז',
+ 'אליפלט',
+ 'אליקים',
+ 'אלישיב',
+ 'אלמגור',
+ 'אלקוש',
+ 'אמונים',
+ 'אמירים',
+ 'אניעם',
+ 'אסד',
+ 'אסד שבט',
+ 'אפיניש',
+ 'אפיניש שבט',
+ 'אפיקים',
+ 'אפק',
+ 'ארבל',
+ 'ארסוף',
+ 'אשבול',
+ 'אשבל',
+ 'אשדוד',
+ 'אשדות יעקב',
+ 'אשדות יעקב איחוד',
+ 'אשדות יעקב מאוחד',
+ 'אשחר',
+ 'אשכולות',
+ 'אשל הנשיא',
+ 'אשלים',
+ 'אשתאול',
+ 'באר אורה',
+ 'באר טוביה',
+ 'באר מילכה',
+ 'בארות יצחק',
+ 'בארותיים',
+ 'בוסתן הגליל',
+ 'בורגתה',
+ 'בטחה',
+ 'בי"ס חקלאי',
+ 'ביצרון',
+ 'ביריה',
+ 'בית אורן',
+ 'בית אלעזרי',
+ 'בית אלפא',
+ 'בית ברל',
+ 'בית גוברין',
+ 'בית גמליאל',
+ 'בית הגדי',
+ 'בית הלוי',
+ 'בית הלל',
+ 'בית העמק',
+ 'בית הערבה',
+ 'בית השיטה',
+ 'בית זיד',
+ 'בית זית',
+ 'בית זרע',
+ 'בית חורון',
+ 'בית חירות',
+ 'בית חלקיה',
+ 'בית חנן',
+ 'בית חנניה',
+ 'בית יהושע',
+ 'בית יוסף',
+ 'בית ינאי',
+ 'בית לחם הגלילית',
+ 'בית מאיר',
+ 'בית נחמיה',
+ 'בית ניר',
+ 'בית נקופה',
+ 'בית עובד',
+ 'בית עוזיאל',
+ 'בית עזרא',
+ 'בית עריף',
+ 'בית צבי',
+ 'בית קמה',
+ 'בית קשת',
+ 'בית רבן',
+ 'בית רימון',
+ 'בית שערים',
+ 'בית שקמה',
+ 'ביתן אהרן',
+ 'בלפוריה',
+ 'בן זכאי',
+ 'בן עמי',
+ 'בן שמן',
+ 'בן שמן כפר נוער',
+ 'בן שמן מושב',
+ 'בנו עוקבה',
+ 'בני דקלים',
+ 'בני דרום',
+ 'בני דרור',
+ 'בני יהודה',
+ 'בני נצרים',
+ 'בני עטרות',
+ 'בני ציון',
+ 'בני ראם',
+ 'בצת',
+ 'בקוע',
+ 'בר גיורא',
+ 'בר יוחאי',
+ 'ברור חיל',
+ 'ברוש',
+ 'ברעם',
+ 'ברקאי',
+ 'בת הדר',
+ 'בת עין',
+ 'בת שלמה',
+ "ג'נאביב",
+ "ג'נאביב שבט",
+ 'גאולי תימן',
+ 'גאולים',
+ 'גבולות',
+ 'גבים',
+ 'גבע',
+ 'גבע כרמל',
+ 'גבעון החדשה',
+ 'גבעות בר',
+ 'גבעת השלושה',
+ 'גבעת ח"ן',
+ 'גבעת חיים',
+ 'גבעת חיים איחוד',
+ 'גבעת חיים מאוחד',
+ 'גבעת יואב',
+ 'גבעת יערים',
+ 'גבעת ישעיהו',
+ 'גבעת כ"ח',
+ 'גבעת ניל"י',
+ 'גבעת עוז',
+ 'גבעת שמש',
+ 'גבעת שפירא',
+ 'גבעתי',
+ 'גברעם',
+ 'גבת',
+ 'גדות',
+ 'גדיש',
+ 'גדעונה',
+ 'גורנות הגליל',
+ 'גזית',
+ 'גיאה',
+ 'גיבתון',
+ 'גיזו',
+ 'גילון',
+ 'גינוסר',
+ 'גיניגר',
+ 'גינתון',
+ 'גלאון',
+ 'גליל ים',
+ 'גלעד אבן יצחק',
+ 'גן הדרום',
+ 'גן השומרון',
+ 'גן חיים',
+ 'גן יאשיה',
+ 'גן שורק',
+ 'גן שלמה',
+ 'גן שמואל',
+ 'גנות',
+ 'גנות הדר',
+ 'גני הדר',
+ 'גני טל',
+ 'גני יוחנן',
+ 'גני עם',
+ 'געש',
+ 'געתון',
+ 'גרופית',
+ 'גשור',
+ 'גשר הזיו',
+ 'גת',
+ 'גת קיבוץ',
+ 'גת רימון',
+ "ד'הרה",
+ 'דבורה',
+ 'דבירה',
+ 'דברת',
+ "דגניה א'",
+ "דגניה ב'",
+ 'דוב"ב',
+ 'דורות',
+ 'דחי',
+ 'דייר ראפאת',
+ 'דישון',
+ 'דלתון',
+ 'דמיידה',
+ "דריג'את",
+ 'האון',
+ 'הבונים',
+ 'הגושרים',
+ 'הדר עם',
+ 'הודיה',
+ 'הודיות',
+ 'הזורע',
+ 'הזורעים',
+ 'החותרים',
+ 'היוגב',
+ 'המעפיל',
+ 'הסוללים',
+ 'העוגן',
+ 'הר גילה',
+ 'הר עמשא',
+ 'הראל',
+ 'הרדוף',
+ 'הררית',
+ 'ורד יריחו',
+ 'ורדון',
+ 'זבארגה',
+ 'זבארגה שבט',
+ 'זבדיאל',
+ 'זיקים',
+ 'זיתן',
+ 'זרועה',
+ 'זרחיה',
+ "ח'ואלד",
+ "ח'ואלד שבט",
+ 'חבצלת השרון',
+ 'חברון',
+ 'חגלה',
+ 'חד-נס',
+ 'חדיד',
+ "חוג'ייראת",
+ "חוג'ייראת ד'הרה",
+ 'חולתה',
+ 'חוסנייה',
+ 'חופית',
+ 'חוקוק',
+ 'חורשים',
+ 'חיבת ציון',
+ 'חמאם',
+ 'חמדיה',
+ 'חמדת',
+ 'חמרה',
+ 'חמרייה',
+ 'חניאל',
+ 'חניתה',
+ 'חנתון',
+ 'חספין',
+ 'חפץ חיים',
+ 'חפצי',
+ 'חפצי-בה',
+ 'חצבה',
+ 'חצור',
+ 'חצור-אשדוד',
+ 'חצרים',
+ 'חרב לאת',
+ 'חרוצים',
+ 'חרשים',
+ 'טירת יהודה',
+ 'טירת צבי',
+ 'טל שחר',
+ 'טל-אל',
+ 'טללים',
+ 'טמרה',
+ 'טמרה יזרעאל',
+ 'טפחות',
+ 'יבול',
+ 'יגור',
+ 'יגל',
+ 'יד השמונה',
+ 'יד חנה',
+ 'יד מרדכי',
+ 'יד נתן',
+ 'יד רמב"ם',
+ 'יהל',
+ 'יובלים',
+ 'יודפת',
+ 'יושיביה',
+ 'יזרעאל',
+ 'יחיעם',
+ 'יטבתה',
+ 'ייט"ב',
+ 'יכיני',
+ 'ינוב',
+ 'יסוד המעלה',
+ 'יסעור',
+ 'יעף',
+ 'יקנעם',
+ 'יקנעם מושבה',
+ 'יראון',
+ 'ירחיב',
+ 'ירקונה',
+ 'ישעי',
+ 'ישרש',
+ 'יתד',
+ 'כברי',
+ 'כדורי',
+ 'כדיתה',
+ 'כוכב מיכאל',
+ 'כורזים',
+ 'כחל',
+ 'כחלה',
+ 'כיסופים',
+ 'כישור',
+ 'כליל',
+ 'כלנית',
+ 'כמאנה',
+ 'כמהין',
+ 'כנות',
+ 'כנרת מושבה',
+ 'כנרת קבוצה',
+ 'כסלון',
+ 'כפר אביב',
+ 'כפר אוריה',
+ 'כפר אחים',
+ 'כפר ביאליק',
+ 'כפר ביל"ו',
+ 'כפר בלום',
+ 'כפר בן נון',
+ 'כפר ברוך',
+ 'כפר גדעון',
+ 'כפר גלים',
+ 'כפר גליקסון',
+ 'כפר גלעדי',
+ 'כפר דניאל',
+ 'כפר החורש',
+ 'כפר המכבי',
+ 'כפר הנגיד',
+ 'כפר הנוער הדתי',
+ 'כפר הנשיא',
+ 'כפר הס',
+ 'כפר הרא"ה',
+ 'כפר הרי"ף',
+ 'כפר ויתקין',
+ 'כפר ורבורג',
+ 'כפר זוהרים',
+ 'כפר זיתים',
+ 'כפר חושן',
+ 'כפר חיטים',
+ 'כפר חיים',
+ 'כפר חנניה',
+ "כפר חסידים א'",
+ "כפר חסידים ב'",
+ 'כפר חרוב',
+ 'כפר טרומן',
+ 'כפר ידידיה',
+ 'כפר יהושע',
+ 'כפר יחזקאל',
+ 'כפר יעבץ',
+ 'כפר מונש',
+ 'כפר מימון',
+ 'כפר מל"ל',
+ 'כפר מנחם',
+ 'כפר מסריק',
+ 'כפר מרדכי',
+ 'כפר נוער',
+ 'כפר נטר',
+ 'כפר סאלד',
+ 'כפר סילבר',
+ 'כפר סירקין',
+ 'כפר עבודה',
+ 'כפר עזה',
+ 'כפר עציון',
+ 'כפר פינס',
+ 'כפר קיש',
+ 'כפר ראש הנקרה',
+ 'כפר רוזנואלד',
+ 'כפר רוזנואלד זרעית',
+ 'כפר רופין',
+ 'כפר רות',
+ 'כפר שמאי',
+ 'כפר שמואל',
+ 'כפר תפוח',
+ 'כרי דשא',
+ 'כרכום',
+ 'כרם בן זמרה',
+ 'כרם בן שמן',
+ 'כרם יבנה',
+ 'כרם יבנה ישיבה',
+ 'כרם מהר"ל',
+ 'כרם שלום',
+ 'כרמי יוסף',
+ 'כרמי צור',
+ 'כרמי קטיף',
+ 'כרמיה',
+ 'כרמים',
+ 'לבון',
+ 'לביא',
+ 'להבות הבשן',
+ 'להבות חביבה',
+ 'לוזית',
+ 'לוחמי הגיטאות',
+ 'לוטם',
+ 'לוטן',
+ 'לימן',
+ 'לכיש',
+ 'לפידות',
+ 'מאיר שפיה',
+ 'מבוא ביתר',
+ 'מבוא דותן',
+ 'מבוא חמה',
+ 'מבוא מודיעים',
+ 'מבואות ים',
+ 'מבואות יריחו',
+ 'מבועים',
+ 'מבטחים',
+ 'מבקיעים',
+ 'מגדים',
+ 'מגדל עוז',
+ 'מגדלים',
+ 'מגל',
+ 'מגן שאול',
+ 'מגשימים',
+ 'מדרך עוז',
+ 'מדרשת בן גוריון',
+ 'מדרשת רופין',
+ 'מוסד',
+ 'מוצא עילית',
+ 'מורשת',
+ 'מזור',
+ 'מזרע',
+ 'מחנה הילה',
+ 'מחנה טלי',
+ 'מחנה יהודית',
+ 'מחנה יוכבד',
+ 'מחנה יפה',
+ 'מחנה יתיר',
+ 'מחנה מרים',
+ 'מחנה תל נוף',
+ 'מחניים',
+ 'מחסיה',
+ 'מטולה',
+ 'מי עמי',
+ 'מיצר',
+ 'מירב',
+ 'מישר',
+ 'מכורה',
+ 'מכחול',
+ 'מכמורת',
+ 'מכמנים',
+ 'מלכיה',
+ 'מלכישוע',
+ 'מנוף',
+ 'מנחמיה',
+ 'מנרה',
+ 'מנשית זבדה',
+ 'מסד',
+ 'מסדה',
+ 'מסילות',
+ 'מסילת ציון',
+ 'מעברות',
+ 'מעגן',
+ 'מעוז חיים',
+ 'מעון',
+ 'מעונה',
+ 'מעין ברוך',
+ 'מעין צבי',
+ 'מעלה אפרים',
+ 'מעלה גלבוע',
+ 'מעלה גמלא',
+ 'מעלה החמישה',
+ 'מעלה לבונה',
+ 'מעלה מכמש',
+ 'מעלה עמוס',
+ 'מענית',
+ 'מעש',
+ 'מפלסים',
+ 'מצדות יהודה',
+ 'מצובה',
+ 'מצפה אבי"ב',
+ 'מצפה אילן',
+ 'מצפה נטופה',
+ 'מצפה שלם',
+ 'מקווה ישראל',
+ 'מרגליות',
+ 'מרום גולן',
+ 'מרחב עם',
+ 'מרחביה',
+ 'מרחביה מושב',
+ 'מרחביה קיבוץ',
+ 'משאבי שדה',
+ 'משגב דב',
+ 'משגב עם',
+ 'משואה',
+ 'משואות יצחק',
+ 'משכיות',
+ 'משמר איילון',
+ 'משמר דוד',
+ 'משמר הירדן',
+ 'משמר הנגב',
+ 'משמר העמק',
+ 'משמר השבעה',
+ 'משמר השרון',
+ 'משמרות',
+ 'משמרת',
+ 'מתת',
+ 'מתתיהו',
+ 'נאות גולן',
+ 'נאות הכיכר',
+ 'נאות מרדכי',
+ 'נאות סמדר',
+ 'נבטים',
+ 'נגוהות',
+ 'נהורה',
+ 'נהלל',
+ 'נוב',
+ 'נוגה',
+ 'נוה צוף',
+ 'נווה',
+ 'נווה אבות',
+ 'נווה אור',
+ 'נווה אטי"ב',
+ 'נווה אילן',
+ 'נווה איתן',
+ 'נווה זוהר',
+ 'נווה זיו',
+ 'נווה חריף',
+ 'נווה ים',
+ 'נווה ימין',
+ 'נווה ירק',
+ 'נווה מבטח',
+ 'נווה מיכאל',
+ 'נווה עובד',
+ 'נווה שלום',
+ 'נופים',
+ 'נופך',
+ 'נורדיה',
+ 'נורית',
+ 'נחושה',
+ 'נחל עוז',
+ 'נחליאל',
+ 'נחשולים',
+ 'נחשון',
+ 'נחשונים',
+ 'נטועה',
+ 'נטור',
+ 'נטעים',
+ 'נטף',
+ 'ניל"י',
+ "ניצן ב'",
+ 'ניצנה קהילת חינוך',
+ 'ניצני סיני',
+ 'ניצני עוז',
+ 'ניצנים',
+ 'ניר אליהו',
+ 'ניר בנים',
+ 'ניר גלים',
+ 'ניר דוד',
+ 'ניר דוד תל עמל',
+ 'ניר ח"ן',
+ 'ניר יפה',
+ 'ניר יצחק',
+ 'ניר ישראל',
+ 'ניר משה',
+ 'ניר עוז',
+ 'ניר עם',
+ 'ניר עציון',
+ 'ניר עקיבא',
+ 'ניר צבי',
+ 'נירים',
+ 'נס הרים',
+ 'נס עמים',
+ 'נעורים',
+ 'נעמ"ה',
+ 'נען',
+ 'נערן',
+ 'נצאצרה',
+ 'נצאצרה שבט',
+ 'נצר חזני',
+ 'נצר סרני',
+ 'נתיב הגדוד',
+ 'נתיב הל"ה',
+ 'נתיב העשרה',
+ 'נתיב השיירה',
+ 'סאסא',
+ 'סואעד',
+ 'סואעד חמרייה',
+ 'סואעד כמאנה שבט',
+ 'סוסיה',
+ 'סמר',
+ 'סנסנה',
+ 'סתריה',
+ 'עבדון',
+ 'עברון',
+ 'עגור',
+ 'עדנים',
+ 'עולש',
+ 'עוצם',
+ 'עוקבי',
+ 'עוקבי בנו עוקבה',
+ 'עזי',
+ 'עזריאל',
+ 'עזריה',
+ 'עטאוונה',
+ 'עטאוונה שבט',
+ 'עיינות',
+ 'עין איילה',
+ 'עין אל',
+ 'עין אל-אסד',
+ 'עין גב',
+ 'עין גדי',
+ 'עין דור',
+ 'עין הבשור',
+ 'עין הוד',
+ 'עין החורש',
+ 'עין המפרץ',
+ 'עין הנצי"ב',
+ 'עין העמק',
+ 'עין השופט',
+ 'עין השלושה',
+ 'עין ורד',
+ 'עין זיוון',
+ 'עין חוד',
+ 'עין חצבה',
+ 'עין חרוד',
+ 'עין חרוד איחוד',
+ 'עין חרוד מאוחד',
+ 'עין יהב',
+ 'עין יעקב',
+ 'עין כרם',
+ 'עין כרם-בי"ס חקלאי',
+ 'עין כרמל',
+ 'עין עירון',
+ 'עין צורים',
+ 'עין ראפה',
+ 'עין שמר',
+ 'עין שריד',
+ 'עין תמר',
+ 'עיר אובות',
+ 'עלומים',
+ 'עלמון',
+ 'עמוקה',
+ 'עמינדב',
+ 'עמיעד',
+ 'עמיעוז',
+ 'עמיקם',
+ 'עמיר',
+ 'עמקה',
+ 'ענב',
+ 'עצמון שגב',
+ 'עראמשה',
+ 'ערב אל נעים',
+ 'ערוגות',
+ 'עריאן',
+ 'עשרת',
+ 'עתניאל',
+ 'פארן',
+ 'פדויים',
+ 'פדיה',
+ 'פוריה',
+ 'פוריה - כפר עבודה',
+ 'פוריה - נווה עובד',
+ 'פוריה עילית',
+ 'פורת',
+ 'פלמחים',
+ 'פני חבר',
+ 'פעמי תש"ז',
+ 'פצאל',
+ 'פקיעין חדשה',
+ 'פרוד',
+ 'פרזון',
+ 'פרי גן',
+ 'פתחיה',
+ 'צאלים',
+ 'צאנע',
+ 'צביה',
+ 'צבעון',
+ 'צובה',
+ 'צוחר',
+ 'צוקי ים',
+ 'צוקים',
+ 'צור נתן',
+ 'צוריאל',
+ 'צורית',
+ 'ציפורי',
+ 'צלפון',
+ 'צנדלה',
+ 'צפריה',
+ 'צפרירים',
+ 'צרעה',
+ 'קבועה שבט',
+ 'קבוצת יבנה',
+ 'קדמה',
+ 'קדמת צבי',
+ 'קדר',
+ 'קדרון',
+ 'קדרים',
+ 'קהילת חינוך',
+ 'קוואעין',
+ 'קוואעין שבט',
+ 'קוטוף',
+ 'קוממיות',
+ 'קורנית',
+ 'קטורה',
+ 'קיבוץ',
+ 'קלחים',
+ 'קליה',
+ 'קרית יערים',
+ 'קרית יעריםמוסד',
+ 'קרית נטפים',
+ 'קרית ענבים',
+ 'קרית שלמה',
+ 'ראס אל',
+ 'ראס אל-עין',
+ 'ראס עלי',
+ 'ראש צורים',
+ 'רבדים',
+ 'רביבים',
+ 'רגבה',
+ 'רגבים',
+ 'רווחה',
+ 'רומאנה',
+ 'רחלים',
+ 'ריחאניה',
+ 'ריחן',
+ 'רימונים',
+ 'רינתיה',
+ 'רם-און',
+ 'רמות השבים',
+ 'רמות מאיר',
+ 'רמות מנשה',
+ 'רמות נפתלי',
+ 'רמת דוד',
+ 'רמת הכובש',
+ 'רמת השופט',
+ 'רמת יוחנן',
+ 'רמת מגשימים',
+ 'רמת צבי',
+ 'רמת רזיאל',
+ 'רמת רחל',
+ 'רנן',
+ 'רעים',
+ 'רשפון',
+ 'רשפים',
+ 'רתמים',
+ 'שאר ישוב',
+ 'שבי דרום',
+ 'שבי ציון',
+ 'שבי שומרון',
+ 'שדה אילן',
+ 'שדה אליהו',
+ 'שדה אליעזר',
+ 'שדה בוקר',
+ 'שדה דוד',
+ 'שדה ורבורג',
+ 'שדה יואב',
+ 'שדה יעקב',
+ 'שדה יצחק',
+ 'שדה משה',
+ 'שדה נחום',
+ 'שדה נחמיה',
+ 'שדה ניצן',
+ 'שדה עוזיהו',
+ 'שדה צבי',
+ 'שדות ים',
+ 'שדות מיכה',
+ 'שדי אברהם',
+ 'שדי חמד',
+ 'שדי תרומות',
+ 'שדמות דבורה',
+ 'שדמות מחולה',
+ 'שואבה',
+ 'שובה',
+ 'שובל',
+ 'שומרה',
+ 'שומריה',
+ 'שוקדה',
+ 'שורשים',
+ 'שושנת העמקים',
+ 'שזור',
+ 'שחרות',
+ 'שיבולים',
+ 'שיזף',
+ 'שיטים',
+ 'שילת',
+ 'שכניה',
+ 'שלווה',
+ 'שלווה במדבר',
+ 'שלוחות',
+ 'שמעה',
+ 'שמרת',
+ 'שעלבים',
+ 'שער אפרים',
+ 'שער הגולן',
+ 'שער העמקים',
+ 'שער מנשה',
+ 'שפיים',
+ 'שריגים',
+ 'שריגים לי-און',
+ 'שרשרת',
+ 'תאשור',
+ 'תדהר',
+ 'תובל',
+ 'תושיה',
+ 'תימורים',
+ 'תל יוסף',
+ 'תל יצחק',
+ 'תל עדשים',
+ 'תל עמל',
+ 'תל קציר',
+ 'תל תאומים',
+ 'תלמי אליהו',
+ 'תלמי אלעזר',
+ 'תלמי ביל"ו',
+ 'תלמי יוסף',
+ 'תלמי יחיאל',
+ 'תלמי יפה',
+ 'תלמים',
+ 'תמרת',
+ 'תנובות',
+ 'תעוז',
+ 'תראבין א',
+ 'תראבין א-צאנע שבט',
+ 'תראבין א-צאנעישוב',
+ 'תרום']
+
+ABBREVIATIONS_LIST_RAW = ['ב”ש',
+ 'הוד”ש',
+ 'י-מ',
+ 'יו”ש',
+ 'יש”ע',
+ 'כפ”ס',
+ 'כ”ס',
+ 'ראשל”צ',
+ 'רמה”ש',
+ 'רמ”ג',
+ 'ר”ג',
+ 'ר”ג',
+ 'תה”ש',
+ 'ת”א']
+
+ABBREVIATIONS_LIST_EXTENDED = [city.replace("”", "\"") for city in ABBREVIATIONS_LIST_RAW]
+
+ABBREVIATIONS_LIST = list(set(ABBREVIATIONS_LIST_RAW).union(set(ABBREVIATIONS_LIST_EXTENDED)))
+
+AMBIGOUS_ABOVE_THRESHOLD_CITIES_LIST = ['אזור',
+ 'אפרת',
+ 'אריאל',
+ 'ברכה',
+ 'ברקת',
+ "ג'ולס",
+ 'גוש חלב',
+ 'יקיר',
+ 'כרמל',
+ 'לפיד',
+ 'מייסר',
+ 'מיתר',
+ 'מכבים',
+ 'מכר',
+ 'מתן',
+ 'ניין',
+ 'ניצן',
+ 'נשר',
+ 'סר',
+ 'עדי',
+ 'עומר',
+ 'עופרה',
+ 'עלי',
+ 'עמנואל',
+ 'פסגות',
+ 'קדומים',
+ 'קדימה',
+ 'קצר א',
+ 'רעות',
+ 'שבט',
+ 'שגב',
+ 'שילה',
+ 'שלום',
+ 'שלומי',
+ 'תפרח',
+ 'תקוע']
+
+AMBIGOUS_BELOW_THRESHOLD_CITIES_LIST = ['אביאל',
+ 'אבשלום',
+ 'אדירים',
+ 'אדרת',
+ 'אודם',
+ 'אוהד',
+ 'אומן',
+ 'אומץ',
+ 'און',
+ 'אורה',
+ 'אורות',
+ 'אורטל',
+ 'אייל',
+ 'אילון',
+ 'אילניה',
+ 'איתמר',
+ 'איתן',
+ 'איתנים',
+ 'אל',
+ 'אלי',
+ 'אלישמע',
+ 'אלמוג',
+ 'אמנון',
+ 'אמציה',
+ 'אספר',
+ 'אפיק',
+ 'ארגמן',
+ 'ארז',
+ 'אשרת',
+ 'אתגר',
+ 'בארי',
+ 'בה',
+ 'בחן',
+ 'בניה',
+ 'בצרה',
+ 'בקעות',
+ 'ברכיה',
+ 'ברק',
+ 'בת חן',
+ 'גאליה',
+ 'גבעולים',
+ 'גונן',
+ 'גורן',
+ 'גזר',
+ 'גילת',
+ 'גיתה',
+ 'גיתית',
+ 'גלגל',
+ 'גלעד',
+ 'גמזו',
+ 'גפן',
+ 'גשר',
+ 'דולב',
+ 'דור',
+ 'דליה',
+ 'דן',
+ 'דפנה',
+ 'דקל',
+ 'הילה',
+ 'זוהר',
+ 'זכריה',
+ 'זמרת',
+ 'זנוח',
+ 'זרעית',
+ 'חבר',
+ 'חגור',
+ 'חגי',
+ 'חד',
+ 'חולדה',
+ 'חולית',
+ 'חוסן',
+ 'חזון',
+ 'חיננית',
+ 'חירות',
+ 'חלוץ',
+ 'חלץ',
+ 'חמד',
+ 'חצב',
+ 'חרמש',
+ 'טל',
+ 'טנא',
+ 'יובל',
+ 'יונתן',
+ 'ינון',
+ 'יסודות',
+ 'יעד',
+ 'יעל',
+ 'יערה',
+ 'יפית',
+ 'יפעת',
+ 'יפתח',
+ 'יציץ',
+ 'יקום',
+ 'ירדנה',
+ 'ישע',
+ 'כמון',
+ 'כנף',
+ 'כנרת',
+ 'כרמל',
+ 'לבנים',
+ 'להב',
+ 'לי',
+ 'מאוחד',
+ 'מאור',
+ 'מגידו',
+ 'מגן',
+ 'מולדת',
+ 'מורן',
+ 'מחולה',
+ 'מטע',
+ 'מיטב',
+ 'מירון',
+ 'מלאה',
+ 'מלילות',
+ 'מנוחה',
+ 'מנות',
+ 'מסלול',
+ 'מעגלים',
+ 'מצליח',
+ 'מצר',
+ 'משען',
+ 'נגבה',
+ 'נועם',
+ 'נחלה',
+ 'נחלים',
+ 'נחם',
+ 'נטע',
+ 'ניצנה',
+ 'נירית',
+ 'נמרוד',
+ 'נס',
+ 'סגולה',
+ 'סופה',
+ 'סלעית',
+ 'סעד',
+ 'סער',
+ 'ספיר',
+ 'עד',
+ 'עוזה',
+ 'עופר',
+ 'עזוז',
+ 'עזר',
+ 'עזריקם',
+ 'עטרת',
+ 'עידן',
+ 'עין',
+ 'עינת',
+ 'עלמה',
+ 'עמיחי',
+ 'פטיש',
+ 'פלך',
+ 'צופית',
+ 'צופר',
+ 'צרופה',
+ 'קבועה',
+ 'קלע',
+ 'קשת',
+ 'רביד',
+ 'רוויה',
+ 'רוחמה',
+ 'רום',
+ 'רועי',
+ 'רותם',
+ 'רם',
+ 'רמות',
+ 'רקפת',
+ 'שבט',
+ 'שדמה',
+ 'שורש',
+ 'שחר',
+ 'שלומית',
+ 'שמיר',
+ 'שני',
+ 'שניר',
+ 'שעל',
+ 'שפיר',
+ 'שפר',
+ 'שקד',
+ 'שקף',
+ 'שרונה',
+ 'שריד',
+ 'שתולה',
+ 'תומר',
+ 'תירוש',
+ 'תלם',
+ 'תקומה']
+
+AMBIGUOUS_CITIES_CONTEXT = ["תושב", "תושבת",
+                           "מבקר", "ביקר", "מבקרת","ביקרה", "ביקרו", "לבקר",
+                           "גר", "גרה", "גרו","לגור",
+                           "מגיע", "מגיעה", "הגיע" "להגיע",
+                           "היה", "הייתה", "היתה",
+                           "נכנס", "נכנסה",
+                           "זז", "זזה", "זזו", "לזוז",
+                           "חוזר", "חזר", "חוזרת","חזרה","חזרו",
+                           "טס", "טסה", "טסו", "טס",
+                           "נוסע", "נסע", "נוסעת","נסעת", "לנסוע",
+                           "עובר", "עבר", "עוברת","עברה", "עברו", "לעבור",
+                           "עוזב", "עזב", "עוזבת","עזבה", "עזבו", "לעזוב",
+                           "עוצר", "עצר", "עוצרת","עצרה", "עצרו", "לעצור",
+                           "פוגש", "פגש", "פוגשת","פגשה", "פגשו", "לפגוש",
+                           "עולה", "עלה","עלתה", "עלו", "לעלות",
+                           ]
\ No newline at end of file
diff --git a/hebsafeharbor/common/date_regex.py b/hebsafeharbor/common/date_regex.py
index 48f1c5d..2531d03 100644
--- a/hebsafeharbor/common/date_regex.py
+++ b/hebsafeharbor/common/date_regex.py
@@ -1,10 +1,28 @@
+# Common Expressions
+preposition_re = r"(?:ב|ל|מ|מה|ה)"
+month_preposition_re = r"(?:ב|ל|בחודש|לחודש)"
+
 # Hebrew Dates
 heb_months_re = '|'.join(["אלול","אב","תמוז","סיון","סיוון","אייר","ניסן","אדר","שבט","טבת","כסלו","כיסלו","חשוון","תשרי"])
 heb_days_re = '|'.join(["[א-ל]׳","""י״(?:[א-ד]|[ז-ט])""","""ט״(?:ו|ז)""","""כ״[א-ט]""","""ל״א"""])
 heb_year_re = r"ה?ת[א-ת][א-ת]?״[א-ת]"
-HEB_DATE_REGEX =  rf"\b(?:ב|ל|מ|מה|ה)?({heb_days_re})?(?:\s+)?(?:ב|ל|בחודש|לחודש)?(?:-|\s)?({heb_months_re})(?:\s|,\s)?({heb_year_re})?\b"
+HEB_FULL_DATE_REGEX =  rf"\b{preposition_re}?(?P<day>{heb_days_re})\s+{month_preposition_re}?(?:-|\s)?(?P<month>{heb_months_re})(?:\s+|,\s+)(?P<year>{heb_year_re})\b"
+HEB_MONTH_YEAR_REGEX =  rf"\b{month_preposition_re}?(?:-|\s)?(?P<month>{heb_months_re})(?:\s+|,\s+)(?P<year>{heb_year_re})\b"
+HEB_DAY_MONTH_REGEX =  rf"\b{preposition_re}?(?P<day>{heb_days_re})\s+{month_preposition_re}?(?:-|\s)?(?P<month>{heb_months_re})\b"
 
 # Latin Dates
 latin_months_re =    '|'.join(["ינואר","פברואר","מרץ","אפריל","מאי","יוני","יולי","אוגוסט","ספטמבר","אוקטובר","נובמבר","דצמבר"])
 num_days_re = r"[1-9]|0[1-9]|[1-2][0-9]|3[0-1]"
-LATIN_DATE_REGEX =  rf"\b(?:ב|ל|מ|מה|ה)?({num_days_re})?(?:\s+)?(?:ב|ל|בחודש|לחודש)?(?:-|\s)?({latin_months_re})(?:\s|,\s)?(\d\d|\d\d\d\d)?\b"
\ No newline at end of file
+LATIN_DATE_REGEX =  rf"\b{preposition_re}?(?P<day>{num_days_re})?(?:\s+)?{month_preposition_re}?(?:-|\s)?(?P<month>{latin_months_re})(?:\s|,\s)?(?P<year>\d\d|\d\d\d\d)?\b"
+
+# Dates in English
+en_abbrv_months_list = ['jan','feb','mar','apr','may','jun','jul','aug','sep','oct','nov','dec',]
+en_full_months_list = ['january','february','march','april','may','june','july','august','september','octber','november','december']
+en_month_re = '|'.join(en_abbrv_months_list+en_full_months_list)
+EN_DATE_REGEX = rf"\b(?P<month>(?i){en_month_re})(?:\s|,\s)(?P<day>{num_days_re})(?:st|th|rd|nd)?(?:\s|,\s)?(?P<year>\d\d|\d\d\d\d)?\b"
+
+# Dates with no punctuations (ddmmyyyy,mmddyyyy...)
+EN_DMY_REGEX = rf"\b{preposition_re}?(?:-|:)?(?P<day>[0-2][1-9]|[3[0-1]])(?P<month>1[1-2]|0[1-9])(?P<year>\d\d\d\d)\b"
+EN_MDY_REGEX = rf"\b{preposition_re}?(?:-|:)?(?P<month>0[1-9]|1[0-2])(?P<day>0[1-9]|[1-2][0-9]|3[0-1])(?P<year>\d\d\d\d)\b"
+EN_YMD_REGEX = rf"\b{preposition_re}?(?:-|:)?(?P<year>\d\d\d\d)(?P<month>0[1-9]|[1-2][0-9]|3[0-1])(0[1-9]|1[0-2])\b"
+
diff --git a/hebsafeharbor/common/date_utils.py b/hebsafeharbor/common/date_utils.py
index f7f1743..8c093ee 100644
--- a/hebsafeharbor/common/date_utils.py
+++ b/hebsafeharbor/common/date_utils.py
@@ -1,6 +1,14 @@
 import re
-from typing import List
-from hebsafeharbor.common.date_regex import HEB_DATE_REGEX, LATIN_DATE_REGEX
+from typing import List,Tuple,Optional,Union
+from hebsafeharbor.common.date_regex import (HEB_FULL_DATE_REGEX,
+                                             HEB_MONTH_YEAR_REGEX,
+                                             HEB_DAY_MONTH_REGEX,
+                                             LATIN_DATE_REGEX,
+                                             EN_DMY_REGEX,
+                                             EN_MDY_REGEX,
+                                             EN_YMD_REGEX,
+                                             EN_DATE_REGEX)
+
 MIN_DATE_LENGTH = 6
 
 class DateMentionComponent:
@@ -60,30 +68,32 @@ def reconstruct_date_string(self) -> str:
         return masked_text
  
 
-def set_date_mention_component(matched:re.Match,ind:int) -> DateMentionComponent:
+def set_date_mention_component(matched:re.Match,ind:Union[int,str]) -> Optional[DateMentionComponent]:
     '''
     Extracts the date and its span from a regular expression and sets a DateMentionComponent 
     instance accordingly.
     :param matched: a re.Match instance containing the groups of a regular expression
-    :param ind: the index of the group we would like to retrieve
+    :param ind: the index (or group name) of the group we would like to retrieve. if ind<1 (or group name not in the matched groups), return None
     :return: a DateMentionComponent instance
     '''
-    return DateMentionComponent(matched.group(ind),matched.span(ind)[0],matched.span(ind)[1])
+    if type(ind) == int:
+        date_instance = DateMentionComponent(matched.group(ind),matched.span(ind)[0],matched.span(ind)[1]) if ind>0 else None
+        
+    else:
+        date_instance = DateMentionComponent(matched.group(ind),matched.span(ind)[0],matched.span(ind)[1]) if ind in matched.groupdict() else None
+        
+    return date_instance
 
-def set_date_mention(matched:re.Match,group_order:List[int]) -> DateMention:
+def set_date_mention_from_pattern_group_names(matched:re.Match) -> DateMention:
     '''
-    Extracts the date and its span from a regular expression and sets a DateMention
+    Extracts the date and its span from a regular expression by group names and sets a DateMention
     instance accordingly.
     :param matched: a re.Match instance containing the groups of a regular expression
-    :param group_order: the order of the group indexes to extract from the matched regular expression
     :return: a list of DateMentionComponent instances
     '''
-    day,month,year = [set_date_mention_component(matched,ind) for ind in group_order]
+    day,month,year = [set_date_mention_component(matched,ind) for ind in ['day','month','year'] ]
     return DateMention(day=day,month=month, year=year,text=matched.string)
 
-
-
-
 def extract_date_components(text: str) -> DateMention:
     """
     Extracts the different date components out of the give recognized entity text
@@ -98,18 +108,42 @@ def extract_date_components(text: str) -> DateMention:
     if len(text) < MIN_DATE_LENGTH:
         return DateMention()
 
-    #Hebrew dates
-    heb_pattern = HEB_DATE_REGEX
-    matched = re.search(heb_pattern,text)
-    if matched:
-        return set_date_mention(matched,group_order=[1,2,3])
-        
-    #Latin dates
-    latin_pattern = LATIN_DATE_REGEX
-    matched = re.search(latin_pattern,text)
+    # check if it's a numerical date (dd.mm.yyyy, mm-dd-yy etc.)
+    num_date = extract_numerical_date_components(text)
+    if num_date:
+        return num_date
+
+    # Go over the different date patterns and search for a match
+    pattern_list = [HEB_FULL_DATE_REGEX,HEB_MONTH_YEAR_REGEX,HEB_DAY_MONTH_REGEX,
+                    LATIN_DATE_REGEX,
+                    EN_DMY_REGEX,EN_MDY_REGEX,EN_YMD_REGEX,
+                    EN_DATE_REGEX]
+
+    matched = find_pattern(text,pattern_list)
     if matched:
-        return set_date_mention(matched,group_order=[1,2,3]) 
-   
+        return set_date_mention_from_pattern_group_names(matched)
+    
+    return DateMention()
+
+def find_pattern(text:str,patterns:List[str])-> Optional[re.Match]:
+    '''Receives text and a list of patterns and returns the matching pattern. 
+    If none of the patterns match, return None
+    :param text: the original text
+    :param patterns: a list of patterns
+    :return a matching pattern or None if none of the patterns matched the given text
+    '''
+    for pattern in patterns:
+        matched = re.search(pattern,text,re.IGNORECASE)
+        if matched:
+            return matched
+    return None
+
+def extract_numerical_date_components(text:str) -> Optional[DateMention]:
+    '''
+        Checks if the given text matches a numerical date pattern (dd.mm.yy, mm-dd-yyyy etc.) 
+       :param text: the original text
+       :return if a pattern was found, returns DateMention, otherwise returns None
+    '''
     # Numerical dates
     num_pattern = r"(\d+)(?:[/.-])(\d+)(?:(?:[/.-])(\d+))?"
     matched = re.search(num_pattern,text)
@@ -125,7 +159,7 @@ def extract_date_components(text: str) -> DateMention:
             return DateMention(day=day,month=month,text=text)        
         else:
             if int(matched.group(1))>31:        
-                year = set_date_mention(matched,ind=1)
+                year = set_date_mention_component(matched,ind=1)
                 if int(matched.group(2))>12:
                     month = set_date_mention_component(matched,ind=3)
                     day = set_date_mention_component(matched,ind=2)
@@ -141,4 +175,5 @@ def extract_date_components(text: str) -> DateMention:
                     month = set_date_mention_component(matched,ind=2)
                     day = set_date_mention_component(matched,ind=1)
             return DateMention(day=day,month=month, year=year,text=text)
-    return DateMention()
\ No newline at end of file
+        return None
+    
diff --git a/hebsafeharbor/common/prepositions.py b/hebsafeharbor/common/prepositions.py
index 33dddf3..2bd4bd4 100644
--- a/hebsafeharbor/common/prepositions.py
+++ b/hebsafeharbor/common/prepositions.py
@@ -1,3 +1,5 @@
-LOCATION_PREPOSITIONS = ["מ", "ל", "ב", "ו"]
-DISEASE_PREPOSITIONS = ["מ", "ל", "ב", "ו"]
-MEDICATION_PREPOSITIONS = ["מ", "ל", "ב", "ו"]
+HEBREW_PREPOSITIONS = ["מ", "ל", "ב", "ו"]
+LOCATION_PREPOSITIONS = HEBREW_PREPOSITIONS
+DISEASE_PREPOSITIONS = HEBREW_PREPOSITIONS
+MEDICATION_PREPOSITIONS = HEBREW_PREPOSITIONS
+MEDICAL_TEST_PREPOSITIONS = HEBREW_PREPOSITIONS
diff --git a/hebsafeharbor/common/terms_recognizer.py b/hebsafeharbor/common/terms_recognizer.py
index 2cc48b1..b5325cd 100644
--- a/hebsafeharbor/common/terms_recognizer.py
+++ b/hebsafeharbor/common/terms_recognizer.py
@@ -28,8 +28,11 @@ def __call__(self, text: str, prefixes: Optional[List[str]] = None) -> List[Tupl
                 pass
             else:
                 if prefixes:
-                    start_cond = offset == 0 or re.match(r"\W", text[offset - 1]) or \
-                                 re.match("|".join(prefixes), text[offset - 1])
+                    prefixes_pattern_raw = "|".join(prefixes)
+                    prefixes_pattern = r"\W(" + prefixes_pattern_raw + ")"
+                    start_cond = offset == 0 or re.match(r"\W", text[offset - 1]) or re.match(prefixes_pattern, text[
+                                                                                                                offset - 2:offset]) or (
+                                             offset == 1 and re.match(prefixes_pattern_raw, text[offset - 1]))
                 else:
                     start_cond = offset == 0 or re.match(r"\W", text[offset - 1])
                 is_phrase = start_cond \
diff --git a/hebsafeharbor/identifier/consolidation/consolidation_config.py b/hebsafeharbor/identifier/consolidation/consolidation_config.py
index aaa0312..3c03d3d 100644
--- a/hebsafeharbor/identifier/consolidation/consolidation_config.py
+++ b/hebsafeharbor/identifier/consolidation/consolidation_config.py
@@ -2,7 +2,7 @@
 
 ENTITY_TYPES_TO_IGNORE = {"MONEY", "PERCENT", "MISC__ENT", "MISC_EVENT", "WOA", "EVE", "DUC", "ANG"}
 
-ENTITY_TYPES_TO_POSTPROCESS = {"COUNTRY", "CITY", "DISEASE", "MEDICATION"}
+ENTITY_TYPES_TO_POSTPROCESS = {"COUNTRY", "CITY", "DISEASE", "MEDICATION", "MEDICAL_TEST"}
 
 ENTITY_TYPE_TO_CATEGORY = {
     "PERS": "NAME",
@@ -18,20 +18,25 @@
     "DATE_TIME": "DATE",
     "EMAIL_ADDRESS": "CONTACT",
     "IP_ADDRESS": "CONTACT",
+    "URL": "CONTACT",
     "PHONE_NUMBER": "CONTACT",
     "ISRAELI_ID_NUMBER": "ID",
     "ID": "ID",
     "COUNTRY": "LOCATION",
     "CITY": "LOCATION",
-    "DISEASE": "INTERNAL",
-    "MEDICATION": "INTERNAL"
+    "DISEASE": "MEDICAL",
+    "MEDICATION": "MEDICAL",
+    "MEDICAL_TEST": "MEDICAL"
 }
 
 CATEGORY_TO_CONTEXT_PHRASES = {
     "ID": ["תעודה", "זהות", "מזהה", "רישיון", "מ.ר", "מ.ז", "ת.ז", "מספר אישי", "רשיון", "מנוי", "עובד", "רכב", "בנק",
            "אשראי"],
     "CONTACT": ["מיקוד", "בטלפון", "טלפון", "טלפון נייח", "טלפון נייד", "פלאפון", "פקס", "טלפון בבית", "טלפון בעבודה",
-                "אימייל", "דואר אלקטרוני", "URL", "IP", "מייל"]
+                "אימייל", "דואר אלקטרוני", "URL", "IP", "מייל"],
+    "MEDICAL": ["שילוב", "לשלב", "נשלב", "אבחנת עבודה", "שדרוג", "לשדרג", "שודרג", "הוספה", "נוסיף", "להוסיף", "נוסף",
+                "הוספנו", "שינוי", "לשנות", "שונה", "שינינו", "מטופל", "מטופלת", "להתחיל", "יתחיל", "תתחיל", "נשלח",
+                "נישלח", "יישלח", "גרורות", "סיכום", "החלפה", "להחליף", "הוחלף", "נחליף", "נוסה", "ניסינו", "ניסיון"]
 }
 
 
diff --git a/hebsafeharbor/identifier/consolidation/consolidator.py b/hebsafeharbor/identifier/consolidation/consolidator.py
index 5593c8f..f034644 100644
--- a/hebsafeharbor/identifier/consolidation/consolidator.py
+++ b/hebsafeharbor/identifier/consolidation/consolidator.py
@@ -1,4 +1,5 @@
 import copy
+import re
 from typing import List
 
 from presidio_analyzer import RecognizerResult
@@ -7,7 +8,8 @@
 from hebsafeharbor.identifier.consolidation.conflict_handler import ExactMatch, SameCategory, SameBoundaries, Mixed
 from hebsafeharbor.identifier.consolidation.consolidation_config import ENTITY_TYPE_TO_CATEGORY, ENTITY_TYPES_TO_IGNORE, \
     ConflictCase, ENTITY_TYPES_TO_POSTPROCESS
-from hebsafeharbor.identifier.consolidation.post_consolidation.city_country_post_consolidator import CityCountryPostConsolidator
+from hebsafeharbor.identifier.consolidation.post_consolidation.city_country_post_consolidator import \
+    CityCountryPostConsolidator
 from hebsafeharbor.identifier.consolidation.overlap_resolver import PreferLongestEntity, ContextBasedResolver, \
     CategoryMajorityResolver
 from hebsafeharbor.identifier.consolidation.post_consolidation.medical_post_consolidator import MedicalPostConsolidator
@@ -40,13 +42,8 @@ def __call__(self, doc: Doc) -> Doc:
         """
 
         recognized_entities = copy.deepcopy(doc.smoothed_entities)
-        # filter out entities from irrelevant types
-        filtered_entities = filter(
-            lambda entity: entity.entity_type not in ENTITY_TYPES_TO_IGNORE.union(ENTITY_TYPES_TO_POSTPROCESS),
-            recognized_entities)
-
-        filtered_entities = sorted(filtered_entities, key=lambda entity: (entity.start, entity.end))
-        group = self.get_next_overlapped_entities_group(filtered_entities, 0)
+        filtered_entities = NerConsolidator.filter_entities(recognized_entities, doc)
+        group = NerConsolidator.get_next_overlapped_entities_group(filtered_entities, 0)
         consolidated_entities = []
         while len(group) > 0:
             selected_entity = self.consolidate_entities(group, doc)
@@ -56,7 +53,7 @@ def __call__(self, doc: Doc) -> Doc:
             else:
                 consolidated_entities.append(selected_entity)
                 last_entity = selected_entity
-            group = self.get_next_overlapped_entities_group(filtered_entities, last_entity.end)
+            group = NerConsolidator.get_next_overlapped_entities_group(filtered_entities, last_entity.end)
 
         # trigger the custom entity consolidators
         for custom_consolidator in self.postprocess_consolidators:
@@ -69,7 +66,8 @@ def __call__(self, doc: Doc) -> Doc:
         doc.consolidated_results = consolidated_entities
         return doc
 
-    def get_next_overlapped_entities_group(self, entities: List[RecognizerResult], start_offset: int) -> List[
+    @staticmethod
+    def get_next_overlapped_entities_group(entities: List[RecognizerResult], start_offset: int) -> List[
         RecognizerResult]:
         """
         Helper function for getting the next group of overlapped entities
@@ -92,7 +90,8 @@ def get_next_overlapped_entities_group(self, entities: List[RecognizerResult], s
                 return group
         return group
 
-    def keep_single_entity(self, entity: RecognizerResult, doc: Doc) -> bool:
+    @staticmethod
+    def keep_single_entity(entity: RecognizerResult, doc: Doc) -> bool:
         """
         Helper function which decides whether to keep an entity that doesn't overlap any other recognized entity
 
@@ -122,7 +121,7 @@ def consolidate_entities(self, entities_in_conflict: List[RecognizerResult], doc
         # if there is only one entity in group there is no conflict - keep it in case it satisfying the minimal
         # requirements
         if len(entities_in_conflict) == 1:
-            if self.keep_single_entity(entities_in_conflict[0], doc):
+            if NerConsolidator.keep_single_entity(entities_in_conflict[0], doc):
                 return entities_in_conflict[0]
             else:
                 return None
@@ -151,3 +150,54 @@ def infer_conflict_case(entities_in_conflict: List[RecognizerResult]) -> Conflic
         if same_boundaries:
             return ConflictCase.SAME_BOUNDARIES
         return ConflictCase.MIXED
+
+    @staticmethod
+    def filter_entities(recognized_entities: List[RecognizerResult], doc: Doc) -> List[RecognizerResult]:
+        """
+        filters recognized entities that are not satisfy some initial requirements and therefore should not be
+        considered as part of the consolidation:
+        1. remove entities from irrelevant types
+        2. filter out ORG and NAME entities that contains at least one English letter
+        3. filter out DATE entities that are float number
+
+        :param recognized_entities: list of recognized entities
+        :param doc: Doc object
+        :return an updated list of recognized entities after filtering
+        """
+        # filter out entities from irrelevant types
+        filtered_entities = filter(
+            lambda entity: entity.entity_type not in ENTITY_TYPES_TO_IGNORE.union(ENTITY_TYPES_TO_POSTPROCESS),
+            recognized_entities)
+
+        # filter out ORG and NAME entities that contains at least one English letter
+        ENGLISH_LETTER_REGEX = re.compile(r"[a-z]|[A-z]")
+        filtered_entities = list(filter(
+            lambda entity: ENTITY_TYPE_TO_CATEGORY[entity.entity_type] not in ["ORG",
+                                                                               "NAME"] or ENGLISH_LETTER_REGEX.search(
+                doc.text[entity.start:entity.end]) is None, filtered_entities))
+
+        # filter out DATE entities that are float number
+        result_entities = []
+        for entity in filtered_entities:
+            if ENTITY_TYPE_TO_CATEGORY[entity.entity_type] != "DATE":
+                result_entities.append(entity)
+            else:
+                entity_text = doc.text[entity.start:entity.end]
+                split_by_period = entity_text.split(".")
+
+                # if there aren't two parts it doesn't float number
+                if len(split_by_period) != 2:
+                    result_entities.append(entity)
+
+                # both parts should be numeric otherwise it is not a float number
+                elif not split_by_period[0].isnumeric() or not split_by_period[1].isnumeric():
+                    result_entities.append(entity)
+
+                # leading zero is allowed in float number only if the first part is zero
+                elif len(split_by_period[0]) == 1:
+                    result_entities.append(entity)
+                elif len(split_by_period[0]) > 1 and split_by_period[0][0] == "0":
+                    result_entities.append(entity)
+
+        filtered_entities = sorted(result_entities, key=lambda entity: (entity.start, entity.end))
+        return filtered_entities
diff --git a/hebsafeharbor/identifier/consolidation/overlap_resolver.py b/hebsafeharbor/identifier/consolidation/overlap_resolver.py
index 31fd693..af23abc 100644
--- a/hebsafeharbor/identifier/consolidation/overlap_resolver.py
+++ b/hebsafeharbor/identifier/consolidation/overlap_resolver.py
@@ -72,9 +72,8 @@ def __call__(self, entities_in_conflict: List[RecognizerResult], doc: Doc) -> Re
 
         for index, entity in enumerate(entities_in_conflict):
             entity_category = ENTITY_TYPE_TO_CATEGORY[entity.entity_type]
-            if len(category_to_end_offsets[entity_category]) > 0 and any(
-                    entity.start - end_offset <= self.window_size for end_offset in
-                    category_to_end_offsets[entity_category]):
+            preceding = list(filter(lambda offset: offset < entity.start, category_to_end_offsets[entity_category]))
+            if len(preceding) > 0 and any(entity.start - end_offset <= self.window_size for end_offset in preceding):
                 return entity
 
         # in case that there are no indicators in context, return the longest entity
diff --git a/hebsafeharbor/identifier/consolidation/post_consolidation/city_country_post_consolidator.py b/hebsafeharbor/identifier/consolidation/post_consolidation/city_country_post_consolidator.py
index 128682f..d311903 100644
--- a/hebsafeharbor/identifier/consolidation/post_consolidation/city_country_post_consolidator.py
+++ b/hebsafeharbor/identifier/consolidation/post_consolidation/city_country_post_consolidator.py
@@ -13,6 +13,8 @@ class CityCountryPostConsolidator(PostConsolidatorRule):
     if necessary.
     """
 
+    MINIMUM_CONFIDENCE_TO_RECOGNIZE = 0.5 #if final confidence score is below - exclude from entities
+
     def __init__(self):
         """
         Initializes CityCountryPostConsolidator
@@ -36,22 +38,39 @@ def __call__(self, consolidated_entities: List[RecognizerResult], custom_entitie
         if len(custom_entities) == 0:
             return consolidated_entities
 
-        consolidated_entities.extend(custom_entities)
+        consolidated_entities.extend(
+            [entity for entity in custom_entities if entity.score >= self.MINIMUM_CONFIDENCE_TO_RECOGNIZE])
         consolidated_entities = self.sort_entities_by_offset_start(consolidated_entities)
 
-        for i in range(1, len(consolidated_entities)):
-            if consolidated_entities[i].start <= consolidated_entities[i-1].end:
-                if self.prioritized_entity_types.index(consolidated_entities[i].entity_type) <= \
-                        self.prioritized_entity_types.index(consolidated_entities[i-1].entity_type):
-                    if (consolidated_entities[i].start - consolidated_entities[i - 1].start) > 1 & (
-                            consolidated_entities[i - 1].end - consolidated_entities[i].end) >= 1:
-                        consolidated_entities[i].end = consolidated_entities[i].start
-                    else:
-                        consolidated_entities[i - 1].end = consolidated_entities[i].start
+        prev_entity_id = 0 # to handle cases where overlap is between more than 2 entities. Ex. שרון גשר מר"ג
+        for cur_entity_id in range(1, len(consolidated_entities)):
+            if consolidated_entities[cur_entity_id].start <= consolidated_entities[prev_entity_id].end:
+                # Define which entity type has priority
+                if self.prioritized_entity_types.index(consolidated_entities[cur_entity_id].entity_type) <= \
+                        self.prioritized_entity_types.index(consolidated_entities[prev_entity_id].entity_type):
+                    primary_entity_id = cur_entity_id
                 else:
-                    consolidated_entities[i].start = consolidated_entities[i - 1].end \
-                        if consolidated_entities[i - 1].end <= consolidated_entities[i].end \
-                        else consolidated_entities[i].end
+                    primary_entity_id = prev_entity_id
+
+                # If entity is within [from both sides] longer entity - we prefer longer entity regardless of priority
+                if (consolidated_entities[cur_entity_id].start - consolidated_entities[prev_entity_id].start) > 1 & (
+                        consolidated_entities[prev_entity_id].end - consolidated_entities[cur_entity_id].end) >= 1:
+                    consolidated_entities[cur_entity_id].end = consolidated_entities[cur_entity_id].start
+                    # prev_entity_id stays the same
+                # if current entity has priority, we'll adjust previous
+                elif cur_entity_id == primary_entity_id:
+                    consolidated_entities[prev_entity_id].end = consolidated_entities[cur_entity_id].start
+                    prev_entity_id = cur_entity_id
+                # if previous entity has priority, we'll adjust current
+                else:
+                    if consolidated_entities[prev_entity_id].end <= consolidated_entities[cur_entity_id].end:
+                        consolidated_entities[cur_entity_id].start = consolidated_entities[prev_entity_id].end
+                        prev_entity_id = cur_entity_id
+                    else:
+                        consolidated_entities[cur_entity_id].start = consolidated_entities[cur_entity_id].end
+                        # prev_entity_id stays the same
+            else:
+                prev_entity_id = cur_entity_id
 
         # .......            | ........            | ........... -> ........... | ........... -> ....******* |
         # ******* -> ******* |  ******* -> ******* |   ********                 |     *******                |
@@ -59,7 +78,8 @@ def __call__(self, consolidated_entities: List[RecognizerResult], custom_entitie
         # ******* -> ******* | ********** -> ********** | ******** -> ********| ********  -> ********..|
         # .......            |   .....                  |  .......            |  .........             |
 
-        for entity in consolidated_entities:
+        # remove entity scraps
+        for entity in reversed(consolidated_entities):
             if (entity.entity_type in self.lower_preference_entity_types) | (
                     entity.entity_type in self.supported_entity_types):
                 if (entity.end - entity.start) == 0:
diff --git a/hebsafeharbor/identifier/consolidation/post_consolidation/medical_post_consolidator.py b/hebsafeharbor/identifier/consolidation/post_consolidation/medical_post_consolidator.py
index 09368f3..0c53fe3 100644
--- a/hebsafeharbor/identifier/consolidation/post_consolidation/medical_post_consolidator.py
+++ b/hebsafeharbor/identifier/consolidation/post_consolidation/medical_post_consolidator.py
@@ -3,8 +3,12 @@
 from presidio_analyzer import RecognizerResult
 
 from hebsafeharbor import Doc
-from hebsafeharbor.common.prepositions import DISEASE_PREPOSITIONS, MEDICATION_PREPOSITIONS
+from hebsafeharbor.common.prepositions import DISEASE_PREPOSITIONS, MEDICATION_PREPOSITIONS, MEDICAL_TEST_PREPOSITIONS
+from hebsafeharbor.common.terms_recognizer import TermsRecognizer
+from hebsafeharbor.identifier.consolidation.consolidation_config import CATEGORY_TO_CONTEXT_PHRASES, \
+    ENTITY_TYPE_TO_CATEGORY
 from hebsafeharbor.identifier.consolidation.post_consolidation.post_consolidator_rule import PostConsolidatorRule
+from hebsafeharbor.lexicons.healthcare_professional import HEALTHCARE_PROFESSIONAL
 
 
 class MedicalPostConsolidator(PostConsolidatorRule):
@@ -12,15 +16,18 @@ class MedicalPostConsolidator(PostConsolidatorRule):
     This post processor make sure that medication or disease won't be wrongly recognized as PHI entity
     """
 
+    MEDICAL_PHRASE_WINDOW_SIZE = 15
+    HEALTHCATRE_PROFESSIONAL_WINDOW_SIZE = 5
+
     def __init__(self):
         """
         Initializes MedicalPostConsolidator
         """
-        super().__init__(supported_entity_types=["DISEASE", "MEDICATION"],
+        super().__init__(supported_entity_types=["DISEASE", "MEDICATION", "MEDICAL_TEST"],
                          lower_preference_entity_types=["PERS", "PER", "ORG", "FAC"],
                          prefer_other_types=False)
 
-        self.medical_prepositions = set(DISEASE_PREPOSITIONS + MEDICATION_PREPOSITIONS)
+        self.medical_prepositions = set(DISEASE_PREPOSITIONS + MEDICATION_PREPOSITIONS + MEDICAL_TEST_PREPOSITIONS)
 
     def __call__(self, consolidated_entities: List[RecognizerResult], custom_entities: List[RecognizerResult],
                  doc: Doc) -> List[RecognizerResult]:
@@ -33,11 +40,30 @@ def __call__(self, consolidated_entities: List[RecognizerResult], custom_entitie
         :param custom_entities: list of recognized medical entities
         :param doc: document which stores the recognized entities
         """
-        if len(custom_entities) == 0:
-            return consolidated_entities
 
-        offset_to_medical_entity = MedicalPostConsolidator.map_offset_to_entity(custom_entities)
-        post_consolidated_entities = []
+        post_consolidated_entities = consolidated_entities
+        if len(custom_entities) > 0:
+            post_consolidated_entities = self.remove_entity_overlap_with_medical(custom_entities,
+                                                                                 post_consolidated_entities, doc)
+
+        post_consolidated_entities = self.infer_by_context(doc, post_consolidated_entities)
+        post_consolidated_entities = self.remove_person_not_in_beginning(doc, post_consolidated_entities)
+
+        return post_consolidated_entities
+
+    def remove_entity_overlap_with_medical(self, medical_entities: List[RecognizerResult],
+                                           consolidated_entities: List[RecognizerResult], doc: Doc) \
+            -> List[RecognizerResult]:
+        """
+        Removes ORG and NAME entities that overlap with medical entities
+
+        :param medical_entities: recognized medical entities
+        :param consolidated_entities: entities after consolidation
+        :param doc: Doc object
+        :return: updated list of consolidated entities
+        """
+        no_overlap_entities = []
+        offset_to_medical_entity = MedicalPostConsolidator.map_offset_to_entity(medical_entities)
         for entity in consolidated_entities:
             if entity.entity_type in self.lower_preference_entity_types:
                 overlapping_medical_entities = MedicalPostConsolidator.get_entities_in_span(offset_to_medical_entity,
@@ -45,11 +71,10 @@ def __call__(self, consolidated_entities: List[RecognizerResult], custom_entitie
                 if len(overlapping_medical_entities) == 0 or not any(
                         self.is_full_overlap(entity, medical_entity, doc) for medical_entity in
                         overlapping_medical_entities):
-                    post_consolidated_entities.append(entity)
+                    no_overlap_entities.append(entity)
             else:
-                post_consolidated_entities.append(entity)
-
-        return post_consolidated_entities
+                no_overlap_entities.append(entity)
+        return no_overlap_entities
 
     def is_full_overlap(self, entity: RecognizerResult, medical_entity: RecognizerResult, doc: Doc) -> bool:
         """
@@ -100,3 +125,54 @@ def get_entities_in_span(offset_to_entity: Dict[int, RecognizerResult], start: i
             if i in offset_to_entity:
                 entities.append(offset_to_entity[i])
         return set(entities)
+
+    def infer_by_context(self, doc: Doc, consolidated_entities: List[RecognizerResult]) -> List[RecognizerResult]:
+        """
+        Removes ORG and NAME entities in case that they follow at least one medical context phrase in specific window
+        size
+
+        :param doc: Doc object
+        :param consolidated_entities: recognized entities
+        :return: updated list of consolidated entities
+        """
+        medical_rec = TermsRecognizer(CATEGORY_TO_CONTEXT_PHRASES["MEDICAL"])
+        offsets = medical_rec(doc.text, list(self.medical_prepositions))
+        end_offsets = list(map(lambda offset: offset[0] + offset[1] - 1, offsets))
+        res = []
+        for entity in consolidated_entities:
+            if entity.entity_type in self.lower_preference_entity_types:
+                preceding = list(filter(lambda offset: offset < entity.start, end_offsets))
+                if not any(
+                        entity.start - end_offset <= MedicalPostConsolidator.MEDICAL_PHRASE_WINDOW_SIZE for end_offset
+                        in preceding):
+                    res.append(entity)
+            else:
+                res.append(entity)
+        return res
+
+    def remove_person_not_in_beginning(self, doc: Doc, consolidated_entities: List[RecognizerResult]) -> List[
+        RecognizerResult]:
+        """
+        Removes NAME entities in case that they don't appear in the first 20% of the document and there isn't at least
+        one healthcare professional phrase that precedes them (in specific window size)
+
+        :param doc: Doc object
+        :param consolidated_entities: recognized entities
+        :return: updated list of consolidated entities
+        """
+        healthcare_professional_rec = TermsRecognizer(HEALTHCARE_PROFESSIONAL)
+        offsets = healthcare_professional_rec(doc.text, list(self.medical_prepositions))
+        end_offsets = list(map(lambda offset: offset[0] + offset[1] - 1, offsets))
+        res = []
+        for entity in consolidated_entities:
+            if ENTITY_TYPE_TO_CATEGORY[entity.entity_type] == "NAME":
+                if entity.start >= int(0.2 * len(doc.text)):
+                    preceding = list(filter(lambda offset: offset < entity.start, end_offsets))
+                    if any(entity.start - end_offset <= MedicalPostConsolidator.HEALTHCATRE_PROFESSIONAL_WINDOW_SIZE for
+                           end_offset in preceding):
+                        res.append(entity)
+                else:
+                    res.append(entity)
+            else:
+                res.append(entity)
+        return res
diff --git a/hebsafeharbor/identifier/entity_spliters/date_entity_splitter.py b/hebsafeharbor/identifier/entity_spliters/date_entity_splitter.py
index 57e4f28..03aac84 100644
--- a/hebsafeharbor/identifier/entity_spliters/date_entity_splitter.py
+++ b/hebsafeharbor/identifier/entity_spliters/date_entity_splitter.py
@@ -36,9 +36,10 @@ def __call__(self, doc: Doc) -> Doc:
         birth_date_end_offsets = list(map(lambda offset: offset[0] + offset[1] - 1, birth_date_offsets))
 
         for entity in date_entities:
-            if any(entity.start - end_offset < DateEntitySplitter.WINDOW_SIZE for end_offset in birth_date_end_offsets):
+            preceding = list(filter(lambda offset: offset < entity.start, birth_date_end_offsets))
+            if any(entity.start - end_offset < DateEntitySplitter.WINDOW_SIZE for end_offset in preceding):
                 entity.entity_type = "BIRTH_DATE"
             else:
                 entity.entity_type = "MEDICAL_DATE"
 
-        return doc
\ No newline at end of file
+        return doc
diff --git a/hebsafeharbor/identifier/phi_identifier.py b/hebsafeharbor/identifier/phi_identifier.py
index 867865a..9d9d84b 100644
--- a/hebsafeharbor/identifier/phi_identifier.py
+++ b/hebsafeharbor/identifier/phi_identifier.py
@@ -1,9 +1,12 @@
 from typing import List
 
-from hebsafeharbor.common.city_utils import BELOW_THRESHOLD_CITIES_LIST, ABOVE_THRESHOLD_CITIES_LIST, ABBREVIATIONS_LIST
+from hebsafeharbor.common.city_utils import BELOW_THRESHOLD_CITIES_LIST, ABOVE_THRESHOLD_CITIES_LIST, \
+    ABBREVIATIONS_LIST, AMBIGOUS_BELOW_THRESHOLD_CITIES_LIST, AMBIGOUS_ABOVE_THRESHOLD_CITIES_LIST, \
+    AMBIGUOUS_CITIES_CONTEXT
 from hebsafeharbor.common.country_utils import COUNTRY_DICT
 from hebsafeharbor.common.document import Doc
-from hebsafeharbor.common.prepositions import LOCATION_PREPOSITIONS, DISEASE_PREPOSITIONS, MEDICATION_PREPOSITIONS
+from hebsafeharbor.common.prepositions import LOCATION_PREPOSITIONS, DISEASE_PREPOSITIONS, MEDICATION_PREPOSITIONS, \
+    MEDICAL_TEST_PREPOSITIONS
 from hebsafeharbor.identifier import HebSpacyNlpEngine
 from hebsafeharbor.identifier.consolidation.consolidator import NerConsolidator
 from hebsafeharbor.identifier.entity_smoother.entity_smoother_rule_executor import EntitySmootherRuleExecutor
@@ -13,13 +16,16 @@
 from hebsafeharbor.identifier.signals.heb_date_recognizer import HebDateRecognizer
 from hebsafeharbor.identifier.signals.heb_preposition_date_recognizer import PrepositionDateRecognizer
 from hebsafeharbor.identifier.signals.heb_latin_date_recognizer import HebLatinDateRecognizer
+from hebsafeharbor.identifier.signals.hebrew_city_recognizer import AmbiguousHebrewCityRecognizer
 from hebsafeharbor.identifier.signals.israeli_id_recognizer import IsraeliIdNumberRecognizer
 from presidio_analyzer import AnalyzerEngine, LocalRecognizer, RecognizerRegistry
 from presidio_analyzer.predefined_recognizers import CreditCardRecognizer, DateRecognizer, EmailRecognizer, \
-    IpRecognizer, PhoneRecognizer, SpacyRecognizer
+    IpRecognizer, PhoneRecognizer, SpacyRecognizer, UrlRecognizer
 
 from hebsafeharbor.identifier.signals.lexicon_based_recognizer import LexiconBasedRecognizer
 from hebsafeharbor.lexicons.disease import DISEASES
+from hebsafeharbor.lexicons.medical_device import MEDICAL_DEVICE
+from hebsafeharbor.lexicons.medical_tests import MEDICAL_TESTS
 from hebsafeharbor.lexicons.medications import MEDICATIONS
 
 
@@ -106,6 +112,7 @@ def _init_analyzer_signals(self) -> List[LocalRecognizer]:
             EmailRecognizer(supported_language="he", context=["אימייל", "דואל", "email", "דואר אלקטרוני"]))
         ner_signals.append(IpRecognizer(supported_language="he", context=["IP", "כתובת IP", "כתובת איי פי"]))
         ner_signals.append(PhoneRecognizer(supported_language="he", context=["טלפון", "סלולרי", "פקס"]))
+        ner_signals.append(UrlRecognizer(supported_language="he", context=["אתר אינטרנט"]))
 
         hebspacy_recognizer = self.init_hebspacy_recognizer()
 
@@ -115,19 +122,32 @@ def _init_analyzer_signals(self) -> List[LocalRecognizer]:
         # init general id recognizer
         ner_signals.append(GeneralIdRecognizer())
         # init dates in hebrew
-        # ner_signals.append(HebDateRecognizer())
+        ner_signals.append(HebDateRecognizer())
         # init dates with preposition
         ner_signals.append(PrepositionDateRecognizer())
         # init latin dates
         ner_signals.append(HebLatinDateRecognizer())
         # init Hebrew country recognizer
-        # ner_signals.append(LexiconBasedRecognizer("CountryRecognizer", "COUNTRY", COUNTRY_DICT.keys(),
-        #                                           allowed_prepositions=LOCATION_PREPOSITIONS))
-        # init Hebrew city recognizer
-        # ner_signals.append(LexiconBasedRecognizer("IsraeliCityRecognizer", "CITY",
-        #                                           set(BELOW_THRESHOLD_CITIES_LIST).union(
-        #                                               set(ABOVE_THRESHOLD_CITIES_LIST)).union(set(ABBREVIATIONS_LIST)),
-        #                                           allowed_prepositions=LOCATION_PREPOSITIONS))
+        ner_signals.append(LexiconBasedRecognizer("CountryRecognizer", "COUNTRY", COUNTRY_DICT.keys(),
+                                                  allowed_prepositions=LOCATION_PREPOSITIONS))
+        # init Hebrew city recognizers
+        cities_set = set(BELOW_THRESHOLD_CITIES_LIST).union(
+            set(ABOVE_THRESHOLD_CITIES_LIST)).union(set(ABBREVIATIONS_LIST))
+        ambiguous_cities_set = set(
+            AMBIGOUS_BELOW_THRESHOLD_CITIES_LIST).union(
+            set(AMBIGOUS_ABOVE_THRESHOLD_CITIES_LIST))
+        disambiguated_cities_set = cities_set - ambiguous_cities_set
+        ner_signals.append(LexiconBasedRecognizer("IsraeliCityRecognizer", "CITY",
+                                                  disambiguated_cities_set,
+                                                  allowed_prepositions=LOCATION_PREPOSITIONS))
+        # ner_signals.append(AmbiguousHebrewCityRecognizer("AmbiguousIsraeliCityRecognizer", "CITY",
+        #                                                  ambiguous_cities_set,
+        #                                                  allowed_prepositions=LOCATION_PREPOSITIONS,
+        #                                                  endorsing_entities=['LOC', 'GPE'],
+        #                                                  context=AMBIGUOUS_CITIES_CONTEXT,
+        #                                                  ),
+        #                    )
+        
         # init disease recognizer
         ner_signals.append(
             LexiconBasedRecognizer("DiseaseRecognizer", "DISEASE", DISEASES, allowed_prepositions=DISEASE_PREPOSITIONS))
@@ -135,6 +155,10 @@ def _init_analyzer_signals(self) -> List[LocalRecognizer]:
         ner_signals.append(
             LexiconBasedRecognizer("MedicationRecognizer", "MEDICATION", MEDICATIONS,
                                    allowed_prepositions=MEDICATION_PREPOSITIONS))
+        # init medical tests recognizer
+        ner_signals.append(
+            LexiconBasedRecognizer("MedicalTestRecognizer", "MEDICAL_TEST", MEDICAL_TESTS + MEDICAL_DEVICE,
+                                   allowed_prepositions=MEDICAL_TEST_PREPOSITIONS))
         return ner_signals
 
     def init_hebspacy_recognizer(self):
diff --git a/hebsafeharbor/identifier/signals/heb_date_recognizer.py b/hebsafeharbor/identifier/signals/heb_date_recognizer.py
index 863720f..5b668f1 100644
--- a/hebsafeharbor/identifier/signals/heb_date_recognizer.py
+++ b/hebsafeharbor/identifier/signals/heb_date_recognizer.py
@@ -1,7 +1,7 @@
 from typing import Optional
 
 from presidio_analyzer import PatternRecognizer, Pattern
-from hebsafeharbor.common.date_regex import HEB_DATE_REGEX
+from hebsafeharbor.common.date_regex import HEB_FULL_DATE_REGEX,HEB_MONTH_YEAR_REGEX,HEB_DAY_MONTH_REGEX
 
 class HebDateRecognizer(PatternRecognizer):
     """
@@ -10,7 +10,17 @@ class HebDateRecognizer(PatternRecognizer):
     PATTERNS = [
         Pattern(
             "Hebrew full date",  
-            HEB_DATE_REGEX,
+            HEB_FULL_DATE_REGEX,
+            0.6
+        ),  
+        Pattern(
+            "Hebrew month year",  
+            HEB_MONTH_YEAR_REGEX,
+            0.6
+        ),      
+        Pattern(
+            "Hebrew day month",  
+            HEB_DAY_MONTH_REGEX,
             0.6
         ),        
         
diff --git a/hebsafeharbor/identifier/signals/heb_latin_date_recognizer.py b/hebsafeharbor/identifier/signals/heb_latin_date_recognizer.py
index f533bd2..6be9724 100644
--- a/hebsafeharbor/identifier/signals/heb_latin_date_recognizer.py
+++ b/hebsafeharbor/identifier/signals/heb_latin_date_recognizer.py
@@ -1,7 +1,7 @@
 from typing import Optional
 
 from presidio_analyzer import PatternRecognizer, Pattern
-from hebsafeharbor.common.date_regex import LATIN_DATE_REGEX
+from hebsafeharbor.common.date_regex import LATIN_DATE_REGEX,EN_DATE_REGEX
 
 
 
@@ -13,10 +13,15 @@ class HebLatinDateRecognizer(PatternRecognizer):
     
     PATTERNS = [
         Pattern(
-            "day month year",
+            "dates written in Hebrew",
             LATIN_DATE_REGEX,
             0.6
-        ),                
+        ), 
+        Pattern(
+          "dates written in English",
+          EN_DATE_REGEX,
+          0.6
+        ),               
     ]
 
     SUPPORTED_ENTITY = "DATE"
diff --git a/hebsafeharbor/identifier/signals/heb_preposition_date_recognizer.py b/hebsafeharbor/identifier/signals/heb_preposition_date_recognizer.py
index 7e9b5f5..64ed845 100644
--- a/hebsafeharbor/identifier/signals/heb_preposition_date_recognizer.py
+++ b/hebsafeharbor/identifier/signals/heb_preposition_date_recognizer.py
@@ -1,6 +1,8 @@
 from typing import Optional, List
 from presidio_analyzer.predefined_recognizers import DateRecognizer
 from presidio_analyzer import Pattern
+from hebsafeharbor.common.date_regex import EN_DMY_REGEX,EN_MDY_REGEX,EN_YMD_REGEX
+
 
 class PrepositionDateRecognizer(DateRecognizer):
     """
@@ -19,10 +21,24 @@ def __init__(
         for p in patterns:
             pattern_dict = p.to_dict()
             pattern = pattern_dict['regex']
-            new_regex = pattern[:pattern.index(r'\b')+2] + '(?:ה|ב|מ|מה?)' + pattern[pattern.index(r'\b')+2:]
-            pattern_dict['regex'] = new_regex
+            pattern_with_preposition = pattern[:pattern.index(r'\b')+2] + '(?:ה|ב|מ|מה)?' + pattern[pattern.index(r'\b')+2:]
+            pattern_dict['regex'] = pattern_with_preposition
             AUG_PATTERNS.append(Pattern.from_dict(pattern_dict))
-        
+
+        # continuous date (10122018)
+        PATTERNS = [Pattern(
+            "ddmmyyyy or ddmmyy",
+            EN_DMY_REGEX,
+            0.6),   
+            Pattern(
+            "mmddyyyy or mmddyy",
+            EN_DMY_REGEX,
+            0.6),
+            Pattern(
+            "yyyymmdd or yymmdd",
+            EN_YMD_REGEX,
+            0.6)]          
+        AUG_PATTERNS = AUG_PATTERNS + PATTERNS
         super().__init__(
             supported_entity=supported_entity,
             patterns=AUG_PATTERNS,
diff --git a/hebsafeharbor/identifier/signals/hebrew_city_recognizer.py b/hebsafeharbor/identifier/signals/hebrew_city_recognizer.py
new file mode 100644
index 0000000..72bdc9f
--- /dev/null
+++ b/hebsafeharbor/identifier/signals/hebrew_city_recognizer.py
@@ -0,0 +1,83 @@
+import re
+from typing import List
+from presidio_analyzer import EntityRecognizer, RecognizerResult, AnalysisExplanation, LemmaContextAwareEnhancer
+from presidio_analyzer.nlp_engine import NlpArtifacts
+
+from hebsafeharbor.identifier.signals.lexicon_based_recognizer import LexiconBasedRecognizer
+
+
+class AmbiguousHebrewCityRecognizer(LexiconBasedRecognizer):
+    """
+    A class which extends the EntityRecognizer (@Presidio) and recognize entities based on a lexicon
+    and additional restrictions
+    """
+
+    DEFAULT_CONFIDENCE_LEVEL = 0.2  # expected confidence level for this recognizer
+    LOCATION_OVERLAP_FACTOR = 0.8  # enhancement factor for this recognizer if overlap with another geo entity found
+
+    def __init__(self, name: str, supported_entity: str, phrase_list: List[str], supported_language: str = "he",
+                 endorsing_entities=List[str], allowed_prepositions=[], context=List[str]):
+        """
+        Initializes AmbiguousHebrewCityRecognizer
+
+        :param name: recognizer's name
+        :param supported_entity: entity type to be associated with the entities recognized by the lexicon based
+        recognizer
+        :param phrase_list: lexicon's phrases
+        :param supported_language: the language that the recognizer supports. Hebrew is the default
+        :param allowed_prepositions: prepositions that allowed to be recognized as part of the entity (in addition to
+        the lexicon phrase itself). Empty list (which means prepositions are not allowed) is the default
+        :param endorsing_entities: if recognized entity has overlap with at least one entity from this list,
+        its score increases
+        :param context: if any of words in the list are found around entity, its sore increases
+        """
+        super().__init__(name=name, supported_entity=supported_entity, phrase_list=phrase_list,
+                         supported_language=supported_language, allowed_prepositions=allowed_prepositions)
+        self.endorsing_entities = endorsing_entities
+        self.context = context
+
+    def load(self) -> None:
+        """No loading is required."""
+        pass
+
+    def analyze(
+            self, text: str, entities: List[str], nlp_artifacts: NlpArtifacts
+    ) -> List[RecognizerResult]:
+        """
+        Recognize entities based on lexicon
+        :param text: text for recognition
+        :param entities: supported entities
+        :param nlp_artifacts: artifacts of the nlp engine
+        :return list of entities recognized based on the lexicon
+        """
+        results = []
+
+        terms_offsets = self.terms_recognizer(text, prefixes=self.allowed_prepositions)
+
+        if len(terms_offsets) == 0:
+            return results
+
+        # iterate over the spaCy tokens, and find all the position indices for endorsing entities
+        geo_entities_position_set = set()
+        for entity in nlp_artifacts.entities:
+            if entity.label_ in self.endorsing_entities:
+                for char in range(entity.start_char, entity.end_char):
+                    geo_entities_position_set.add(char)
+
+        # iterate over potential city offsets and endorse the results using overlap with geo-entities or support words
+        for term_start, term_len in terms_offsets:
+            overlap_ratio = len(
+                set(range(term_start, term_start + term_len)).intersection(geo_entities_position_set)) / term_len
+            adjusted_score = self.DEFAULT_CONFIDENCE_LEVEL + (overlap_ratio * self.LOCATION_OVERLAP_FACTOR)
+            result = RecognizerResult(
+                entity_type="CITY",
+                start=term_start,
+                end=term_start + term_len,
+                score=adjusted_score,
+                analysis_explanation=AnalysisExplanation(self.name, adjusted_score),
+                recognition_metadata={RecognizerResult.RECOGNIZER_NAME_KEY: self.name},
+            )
+
+            results.append(result)
+
+        return results
diff --git a/hebsafeharbor/identifier/signals/lexicon_based_recognizer.py b/hebsafeharbor/identifier/signals/lexicon_based_recognizer.py
index ce8ada3..52ce822 100644
--- a/hebsafeharbor/identifier/signals/lexicon_based_recognizer.py
+++ b/hebsafeharbor/identifier/signals/lexicon_based_recognizer.py
@@ -54,7 +54,8 @@ def analyze(
                 start=start_offset,
                 end=start_offset + length,
                 score=self.DEFAULT_CONFIDENCE_LEVEL,
-                analysis_explanation=AnalysisExplanation(self.name, self.DEFAULT_CONFIDENCE_LEVEL)
+                analysis_explanation=AnalysisExplanation(self.name, self.DEFAULT_CONFIDENCE_LEVEL),
+                recognition_metadata={RecognizerResult.RECOGNIZER_NAME_KEY: self.name}
             )
             results.append(result)
 
diff --git a/hebsafeharbor/lexicons/healthcare_professional.py b/hebsafeharbor/lexicons/healthcare_professional.py
new file mode 100644
index 0000000..763a807
--- /dev/null
+++ b/hebsafeharbor/lexicons/healthcare_professional.py
@@ -0,0 +1,16 @@
+HEALTHCARE_PROFESSIONAL = [
+    "ד\"ר",
+    "דר",
+    "דוקטור",
+    "פרופסור",
+    "פרופ\'",
+    "פרופ",
+    "רופא",
+    "רופאה",
+    "אחות",
+    "אח",
+    "מיילד",
+    "מיילדת",
+    "מילד",
+    "מילדת"
+]
diff --git a/hebsafeharbor/lexicons/medical_device.py b/hebsafeharbor/lexicons/medical_device.py
new file mode 100644
index 0000000..648aa8b
--- /dev/null
+++ b/hebsafeharbor/lexicons/medical_device.py
@@ -0,0 +1,16 @@
+# wiki-id: Q6554101
+MEDICAL_DEVICE = [
+	"הולטר",
+	"דקס",
+	"קתטר",
+	"פרוטזה",
+	"פרותזה",
+	"צינור הזנה",
+	"תותבות",
+	"קטטר",
+	"נקז חזה",
+	"הזנה בצינור",
+	"גלוקו-מטר",
+	"תותבת",
+	"מד סוכר",
+]
diff --git a/hebsafeharbor/version.py b/hebsafeharbor/version.py
index 3504ab2..bb41510 100644
--- a/hebsafeharbor/version.py
+++ b/hebsafeharbor/version.py
@@ -1,5 +1,5 @@
 _MAJOR = "0"
 _MINOR = "0"
-_REVISION = "3"
+_REVISION = "4"
 
 VERSION = f"{_MAJOR}.{_MINOR}.{_REVISION}"
diff --git a/images/demo_application.png b/images/demo_application.png
new file mode 100644
index 0000000..83339cc
Binary files /dev/null and b/images/demo_application.png differ
diff --git a/requirements_server.txt b/requirements-server.txt
similarity index 100%
rename from requirements_server.txt
rename to requirements-server.txt
diff --git a/scripts/wikidata_lexicon_extractor.py b/scripts/wikidata_lexicon_extractor.py
index b4c87a8..fa9d1a9 100644
--- a/scripts/wikidata_lexicon_extractor.py
+++ b/scripts/wikidata_lexicon_extractor.py
@@ -10,7 +10,7 @@
 You can explore wikidata for ideas of relevant categories https://www.wikidata.org/wiki/Wikidata:Main_Page
 
 Usage example:
-python wikidata_lexicon_extractor.py Q515 cities_lexicon.py CITIES_LEXICON
+python wikidata_lexicon_extractor.py Q515 cities_lexicon
 """
 
 from typing import List
@@ -20,11 +20,12 @@
 import argparse
 
 WIKI_DATA_URL = 'https://query.wikidata.org/sparql'
+RELEVANT_RELATIONS = ["P31", "P279"]
 QUERY_TEMPLATE = """
 SELECT ?item ?itemLabel ?itemAltLabel
 WHERE 
 {
-  ?item wdt:P31 wd:<WIKI_ID>.
+  ?item wdt:<RELATION> wd:<WIKI_ID>.
   SERVICE wikibase:label { bd:serviceParam wikibase:language "he". } # Helps get the label in your language, if not, then en language
 }
 """
@@ -34,9 +35,13 @@
 
 
 def wikidata_query(wiki_id: str):
-    r = requests.get(WIKI_DATA_URL, params={'format': 'json', 'query': QUERY_TEMPLATE.replace("<WIKI_ID>", wiki_id)})
-    data = r.json()
-    return data["results"]['bindings']
+    data = []
+    for relation in RELEVANT_RELATIONS:
+        r = requests.get(WIKI_DATA_URL, params={
+            'format': 'json', 
+            'query': QUERY_TEMPLATE.replace("<WIKI_ID>", wiki_id).replace("<RELATION>", relation)})
+        data += r.json()["results"]['bindings']
+    return data
 
 
 def process_wikidata_response(data: List) -> List[str]:
@@ -52,8 +57,9 @@ def process_wikidata_response(data: List) -> List[str]:
     return list(all_names)
 
 
-def save_python_file(all_names: List[str], output_file: str, lexicon_name: str):
+def save_python_file(wiki_id: str, all_names: List[str], output_file: str, lexicon_name: str):
     with open(output_file, 'w', encoding="utf-8") as fp:
+        fp.write(f"# wiki-id: {wiki_id}\n")
         fp.write(f"{lexicon_name} = [\n")
         for name in all_names:
             fp.write(f'\t"{name}",\n')
@@ -63,15 +69,15 @@ def save_python_file(all_names: List[str], output_file: str, lexicon_name: str):
 def main(wiki_id: str, output_file: str, lexicon_name: str):
     data = wikidata_query(wiki_id)
     all_names = process_wikidata_response(data)
-    save_python_file(all_names, output_file, lexicon_name)
+    save_python_file(wiki_id, all_names, output_file, lexicon_name)
 
 
 if __name__ == "__main__":
     parser = argparse.ArgumentParser()
     parser.add_argument('wiki_id', help="a wikiID you want to list all instances of")
-    parser.add_argument('output_file', help="output python file")
-    parser.add_argument('lexicon_name', help="variable name in python file")
+    parser.add_argument('lexicon_name', help="the name of the lexicon (will be used for output python file and variable inside it")
 
     args = parser.parse_args()
-
-    main(args.wiki_id, args.output_file, args.lexicon_name)
+    output_file = args.lexicon_name + ".py"
+    lexicon_name = args.lexicon_name.upper()
+    main(args.wiki_id, output_file, lexicon_name)
diff --git a/server.py b/server.py
index 91f66c3..b861130 100644
--- a/server.py
+++ b/server.py
@@ -144,4 +144,4 @@ def ready(response: Response):
 hsh_service.load_async()
 
 if __name__ == '__main__':
-    uvicorn.run(app, host="0.0.0.0", port=8080)
+    uvicorn.run(app, host="0.0.0.0", port=8000)
diff --git a/setup.py b/setup.py
index 660bea3..af87146 100644
--- a/setup.py
+++ b/setup.py
@@ -40,8 +40,12 @@ def get_requirements_from_files(*files):
 for requirement in install_requires_:
     print("adding requirement: " + requirement)
 
-with open(path.join(this_directory, "README.MD"), encoding="utf-8") as f:
-    long_description = f.read()
+try:
+    with open(path.join(this_directory, "README.md"), encoding="utf-8") as f:
+        long_description = f.read()
+except FileNotFoundError:
+    long_description = ""
+    print("Could not find README.md - Skipping")
 
 setup(
     name="hebsafeharbor",


Test patch:
diff --git a/hebsafeharbor/lexicons/medical_tests.py b/hebsafeharbor/lexicons/medical_tests.py
new file mode 100644
index 0000000..be2c942
--- /dev/null
+++ b/hebsafeharbor/lexicons/medical_tests.py
@@ -0,0 +1,30 @@
+# wiki-id: Q2671652
+MEDICAL_TESTS = [
+	"אקו-לב",
+	"בדיקת אולטרה סאונד להריון",
+	"אקו-לב עוברי",
+	"אאג",
+	"בדיקת הריון",
+	"דימות תהודה מגנטית גרעינית",
+	"סקירה מוקדמת",
+	"תכשיר לבדיקת הריון",
+	"אלקטרוקרדיוגרמה",
+	"אלקטרוקרדיוגרפיה",
+	"בדיקת סטטוס פסיכיאטרי",
+	"אלקטרואנצפלוגרם",
+	"רשמת לב חשמלית",
+	"הדמיית תהודה מגנטית",
+	"סקירה מאוחרת",
+	"סטטוס פסיכיאטרי",
+	"בדיקת שדה ראיה",
+	"הדמייה רפואית",
+	"אנדוסקופ",
+	"אקו לב",
+	"רשמת מוח חשמלית",
+	"אקו-לב עובר",
+	"רמח",
+	"אקג",
+	"סקירת מערכות",
+	"הדמיה רפואית",
+	"אלקטרואנצפלוגרמה",
+]