diff --git a/__init__.py b/__init__.py
index 16518bf90611f2ba33459df24451575be07997fd..43b770dc3f4bae39e7cc12b870ffdf41ab5eb135 100644
--- a/__init__.py
+++ b/__init__.py
@@ -2,4 +2,4 @@ from flask import Flask
 
 app = Flask(__name__, template_folder="templates")
 
-import my_flask_app.main
+from . import main
diff --git a/__pycache__/__init__.cpython-311.pyc b/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..10a22a88935ac987aeb97db41430e3e2d4a6dbd8
Binary files /dev/null and b/__pycache__/__init__.cpython-311.pyc differ
diff --git a/__pycache__/__init__.cpython-39.pyc b/__pycache__/__init__.cpython-39.pyc
index 32aa421ba46b9a29d50d12b8ea9ead324ab514c9..206099422aa956812462937fecf40b36f1cb7cbb 100644
Binary files a/__pycache__/__init__.cpython-39.pyc and b/__pycache__/__init__.cpython-39.pyc differ
diff --git a/__pycache__/main.cpython-311.pyc b/__pycache__/main.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..3d15975a5b1a12e3a15f7be1710a1cb8b3dfbcf9
Binary files /dev/null and b/__pycache__/main.cpython-311.pyc differ
diff --git a/__pycache__/main.cpython-39.pyc b/__pycache__/main.cpython-39.pyc
index 0f6447fa55eaa8f10df992e71e8b5cd526f6f6d1..d378229d7ae9fbc0df103aa88b1b69fcb108054c 100644
Binary files a/__pycache__/main.cpython-39.pyc and b/__pycache__/main.cpython-39.pyc differ
diff --git a/main.py b/main.py
index 36e5cf9c442d5675312204c44df7402a1f94dd8b..7b8a8497169868c60da3fddc8195cf3ca9e342c8 100644
--- a/main.py
+++ b/main.py
@@ -1,16 +1,17 @@
 from datetime import datetime
 import pandas as pd
-from my_flask_app import app
+from . import app
 from .models.models import CustomTable, CustomColumn, Theme, CompressedDataType, Observation_Spec, RegType, RegRole
 from flask_sqlalchemy import SQLAlchemy
 from flask import jsonify, make_response, redirect, render_template, request, session, url_for, json, send_file
-from sqlalchemy import ARRAY, BIGINT, BOOLEAN, DOUBLE_PRECISION, FLOAT, INT, INTEGER, JSON, NUMERIC, SMALLINT, TIMESTAMP, UUID, VARCHAR, MetaData, String, create_engine, text, inspect
+from sqlalchemy import ARRAY, BIGINT, BOOLEAN, FLOAT, INT, INTEGER, JSON, NUMERIC, SMALLINT, TIMESTAMP, UUID, VARCHAR, MetaData, String, create_engine, text, inspect
 import pydot, base64, os, logging, io
 from sqlalchemy.orm import scoped_session, sessionmaker
 from sqlalchemy.dialects.postgresql.base import ischema_names
 from sqlalchemy.dialects.postgresql import JSONB, TSTZRANGE, INTERVAL, BYTEA, JSON, UUID, DOUBLE_PRECISION, BYTEA, ARRAY, REAL, TSTZRANGE, UUID, BYTEA, JSONB, JSON, ARRAY, FLOAT, INTEGER, TIMESTAMP, TEXT, BOOLEAN, VARCHAR, NUMERIC, REAL
 from sqlalchemy.dialects.sqlite import JSON, FLOAT, INTEGER, TIMESTAMP, TEXT, BOOLEAN, VARCHAR, NUMERIC, REAL
 from bs4 import BeautifulSoup
+from sqlalchemy.exc import SQLAlchemyError
 
 # Set up database (call db.engine)
 app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
@@ -28,12 +29,6 @@ ischema_names['_timescaledb_internal.compressed_data'] = CompressedDataType
 ischema_names['regtype'] = RegType
 ischema_names['regrole'] = RegRole
 
-@app.errorhandler(400)
-def log_bad_request(error):
-    logging.error(f"Bad request: {request} {request.data} {request.args}")
-    # You can add more request details to log here
-    return "Bad request", 400
-
 @app.route('/', methods=['POST', 'GET'])
 def index():
     try:
@@ -42,71 +37,73 @@ def index():
             print("2")
             database_uri = request.form.get('database_uri')
             print(database_uri)
-            if database_uri != '' and database_uri != None:
-                print("3")
-                if database_uri != session.get('db_uri', ''):
-                    session['db_uri'] = database_uri
-                    session['target_table_names'] = []
-                    session['target_table_name'] = ''
-                    session['self_defined_labels'] = []
-                    session['schema_selected'] = ''
-                    session['show_all'] = False
-                    session['object_name'] = {}
-                    session['data_header']={'event':[], 'measurement':[], 'segment':[], 'segmentData':[]}
-                    session['current_data_header'] = {'tablename': '', 'type': '', 'label': [], 'features_name': []}
-                    print("4")
-                # Initialize inspector here, outside the inner if-else
-                print("4.5")
-                engine = create_engine(database_uri)
-                insp = inspect(engine)
-                session_factory = sessionmaker(bind=engine)
-                db.session = scoped_session(session_factory)
-                metadata_obj = MetaData()
-                print("5")
-
-            else:
-                database_uri = session.get('db_uri', '')
-                engine = create_engine(database_uri)
-                insp = inspect(engine)
-                session_factory = sessionmaker(bind=engine)
-                db.session = scoped_session(session_factory)
-                print("6")
-
-            database = database_name_from_uri(engine, database_uri) if database_uri != '' else ''
-            schemas = getSchema(insp) if session['db_uri'] != '' else []
-            themes = getThemes()
-            tables_selected = []
-            dropped_items = session.get('target_table_names', [])
-            self_labels = session.get('self_defined_labels', [])
-            schema_Selected = request.form.get('schema', None)
-            if schema_Selected != None:
-                session['schema_selected'] = schema_Selected
-                print("888" + schema_Selected)
-            show_all = request.form.get('show_all') == 'True'
-            if show_all != False:
-                session['show_all'] = show_all
-            
+            try:
+                if database_uri != '' and database_uri != None:
+                    print("3")
+                    if database_uri != session.get('db_uri', ''):
+                        session['db_uri'] = database_uri
+                        session['target_table_names'] = []
+                        session['target_table_name'] = ''
+                        session['self_defined_labels'] = []
+                        session['schema_selected'] = ''
+                        session['show_all'] = False
+                        session['object_name'] = {}
+                        session['data_header']={'event':[], 'measurement':[], 'segment':[], 'segmentData':[]}
+                        session['current_data_header'] = {'tablename': '', 'type': '', 'label': [], 'features_name': []}
+                        session['data_table'] = {'O':[], 'S':[], 'SD':[]}
+                        print("4")
+                    # Initialize inspector here, outside the inner if-else
+                    print("4.5")
+                    engine = create_engine(database_uri)
+                    insp = inspect(engine)
+                    session_factory = sessionmaker(bind=engine)
+                    db.session = scoped_session(session_factory)
+                    metadata_obj = MetaData()
+                    print("5")
 
-            tables1 = importMetadata(engine, schema_Selected, None, show_all)
-            graph_DOT1 = createGraph(tables1, themes["Blue Navy"], True, True, True)
-            image1 = generate_erd(graph_DOT1)
-
-            print("111")
-            for name in dropped_items:
-                print(name)
-            if dropped_items == []:
-                image2 = ""
-            else:
-                tables2 = importMetadata(engine, None, dropped_items, False)
-                graph_DOT2 = createGraph(tables2, themes["Blue Navy"], True, True, True)
-                image2 = generate_erd(graph_DOT2)
-                print("222")
+                else:
+                    database_uri = session.get('db_uri', '')
+                    engine = create_engine(database_uri)
+                    insp = inspect(engine)
+                    session_factory = sessionmaker(bind=engine)
+                    db.session = scoped_session(session_factory)
+                    print("6")
+
+                database = database_name_from_uri(engine, database_uri) if database_uri != '' else ''
+                schemas = getSchema(insp) if session['db_uri'] != '' else []
+                themes = getThemes()
+                tables_selected = []
+                dropped_items = session.get('target_table_names', [])
+                self_labels = session.get('self_defined_labels', [])
+                schema_Selected = request.form.get('schema', None)
+                if schema_Selected != None:
+                    session['schema_selected'] = schema_Selected
+                    print("888" + schema_Selected)
+                show_all = request.form.get('show_all') == 'True'
+                if show_all != False:
+                    session['show_all'] = show_all
+                
 
+                tables1 = importMetadata(engine, schema_Selected, None, show_all)
+                graph_DOT1 = createGraph(tables1, themes["Blue Navy"], True, True, True)
+                image1 = generate_erd(graph_DOT1)
 
-            # extract_ME_table(engine, 'event_data', 'E', 'time', ['col', 'machine_id'], [' col ', ' name ', ' Z_ACTUAL_ZERO_POINT '], ['value(fine, coarse)'], datetime(2022, 11, 1, 17, 5), datetime(2022, 11, 3, 0, 0))
+                print("111")
+                for name in dropped_items:
+                    print(name)
+                if dropped_items == []:
+                    image2 = ""
+                else:
+                    tables2 = importMetadata(engine, None, dropped_items, False)
+                    graph_DOT2 = createGraph(tables2, themes["Blue Navy"], True, True, True)
+                    image2 = generate_erd(graph_DOT2)
+                    print("222")
 
-            return render_template('app.html', database=database, schemas=schemas, show_all=show_all, schema_Selected=schema_Selected, tables=tables1, image1=image1, image2=image2, dropped_items=dropped_items, self_labels=self_labels)
-        
+                return render_template('app.html', database=database, schemas=schemas, show_all=show_all, schema_Selected=schema_Selected, tables=tables1, image1=image1, image2=image2, dropped_items=dropped_items, self_labels=self_labels)
+            
+            except SQLAlchemyError as e:
+                # If there's a database error, send an error message to the frontend
+                return render_template('app.html', success=False, message="Failed to connect to the database. Please check the connection details.")
         else:
             # Display the form
             return render_template('app.html')
@@ -118,24 +115,6 @@ def index():
 @app.route('/handle-drop', methods=['POST'])
 def handle_drop():
     data = request.json
-    # if data.get('reset') == True or data.get('reset') != None:
-    #     print(data.get('reset'))
-    #     session['target_table_names'] = []
-    #     dropped_items = []
-    #     graph_DOT2 = "digraph {};"
-    #     image2 = generate_erd(graph_DOT2)
-
-    #     database_uri = session.get('db_uri', '')
-    #     engine = create_engine(database_uri)
-    #     insp = inspect(engine)
-    #     schema_Selected = session.get('schema', None)
-    #     print("999"+ str(schema_Selected))
-    #     show_all = session.get('show_all', False)
-    #     tables_in_CustomTable = importMetadata(engine, schema_Selected, None, show_all)
-    #     tables1 = list(tables_in_CustomTable.keys()) if tables_in_CustomTable != {} else []
-
-    #     return jsonify(image2=image2, dropped_items=dropped_items, tables=tables1)
-
     item_name = data.get('item') 
     action = data.get('action')
     dropped_items = session.get('target_table_names', [])
@@ -155,6 +134,7 @@ def handle_drop():
 
     return jsonify(image2=image2)
 
+
 @app.route('/reset-target-table', methods=['POST'])
 def reset_target_table():
     print("reset")
@@ -162,6 +142,7 @@ def reset_target_table():
     engine = create_engine(database_uri)
     session['target_table_names'] = []
     schema_Selected = session.get('schema_selected', None)
+    print(schema_Selected)
     show_all = session.get('show_all', False)
 
     # Regenerate ERD based on the updated dropped_items
@@ -175,6 +156,7 @@ def reset_target_table():
 
     return jsonify(image2=image2, tables=tables1)
 
+
 @app.route('/get-table-data', methods=['POST'])
 def get_table_data():
     data = request.json
@@ -191,19 +173,30 @@ def get_table_data():
 
     # Get the table columns and values
     table_instance = getTableInstance(engine, table_name)
-    table_columns = [column.name for column in table_instance.columns]
-    sorted_table_columns = sorted(table_columns)
+    table_columns = []
+    for column in table_instance.columns:
+        if column.datatype == "varchar" or column.datatype == "numeric" or column.datatype == "string" or column.datatype == "text":
+            table_columns.append(column.name)
+    # table_columns = [column.name for column in table_instance.columns]
+    sorted_table_columns = sorted(table_columns)  
 
     # de-nested the JSON columns from the feature_columns
-    feature_columns = sorted_table_columns
+    column_names = []
+
+    for column in table_instance.columns:
+        if column.datatype != "timestamp" and column.datatype != "uuid":
+            column_names.append(column.name)
+
+    feature_columns = sorted(column_names)
     if check_json_column(engine, table_name) != []:
         json_column_names = check_json_column(engine, table_name)
         for column_name in json_column_names:
-            feature_columns.remove(column_name)
-            jsonKeys = handle_json_column(engine, table_name, column_name) #[('line',), ('coarse', 'fine'), ('name',), ('percent',), ('axisID', 'coarse', 'fine')]
-            for key in jsonKeys:
-                feature_columns.append( column_name + str(key) ) if len(key) > 1 else feature_columns.append( column_name +  str(key).replace(',', ''))
-
+            if column_name in feature_columns:
+                feature_columns.remove(column_name)
+                jsonKeys = handle_json_column(engine, table_name, column_name) #[('line',), ('coarse', 'fine'), ('name',), ('percent',), ('axisID', 'coarse', 'fine')]
+                for key in jsonKeys:
+                    feature_columns.append( column_name + str(key) ) if len(key) > 1 else feature_columns.append( column_name +  str(key).replace(',', ''))
+    
     return jsonify({ 'html_table': html_table, 'table_columns': sorted_table_columns, 'feature_columns': feature_columns })
 
 
@@ -243,6 +236,78 @@ def add_label():
     return jsonify({'defined_labels': self_defined_labels})
 
 
+@app.route('/constraint-feature-columns', methods=['POST'])
+def constraint_feature_columns():
+    engine = create_engine(session.get('db_uri',''))
+    data = request.json
+    table_name = session.get('target_table_name', '')
+    label_column = data.get('label_column', '')
+    label = data.get('label', '')
+    if table_name == None or table_name == '':
+        print("table_name is None" + table_name)
+        return jsonify({})
+    if check_json_column(engine, table_name) != [] and label_column != '' and label != '':
+        print("constraint_feature_columns")
+        # Get the table columns and values
+        table_instance = getTableInstance(engine, table_name)
+        # de-nested the JSON columns from the feature_columns
+        column_names = []
+        for column in table_instance.columns:
+            if column.datatype != "timestamp" and column.datatype != "uuid":
+                column_names.append(column.name)
+
+        feature_columns = sorted(column_names)
+        json_column_names = check_json_column(engine, table_name)
+        for column_name in json_column_names:
+            if column_name in feature_columns:
+                feature_columns.remove(column_name)
+                jsonKeys = get_JSON_keys(engine, table_name, column_name, label_column, label) #[('line',), ('coarse', 'fine'), ('name',), ('percent',), ('axisID', 'coarse', 'fine')]
+                for key in jsonKeys:
+                    feature_columns.append( column_name + str(key) ) if len(key) > 1 else feature_columns.append( column_name +  str(key).replace(',', ''))
+        print(feature_columns)
+        return jsonify({'feature_columns': feature_columns })
+    
+    else:
+        print("abfhakfbdahf")
+        print(table_name)
+        print(label_column)
+        print(label)
+        return jsonify({})
+    
+def get_JSON_keys(engine, table_name, column_name, label_column, label):
+    insp = inspect(engine)
+    isSQLite = insp.dialect.name == 'sqlite' 
+
+    # Create a connection from the engine
+    with engine.connect() as conn:
+        # Prepare the SQL query to fetch a sample JSON object from the specified column
+        if insp.dialect.name == 'postgresql':
+            schema = getTableSchema(table_name)
+            query = f"SELECT DISTINCT {column_name} FROM {schema}.{table_name} WHERE {label_column} = '{label}'"
+        else:
+            query = f"SELECT DISTINCT {column_name} FROM {table_name} WHERE {label_column} = '{label}'"
+        
+        # Execute the query and fetch the result
+        result = conn.execute(text(query)).fetchall()
+        # df = pd.read_sql_query(query, engine)
+        conn.close()
+
+        jsonKeys = []
+        for row in result:  # row is a tuple, row[0] is a dictionary
+            # Convert the keys to a sorted tuple for consistency
+            if type(row[0]) == dict:
+                name = tuple(sorted(row[0].keys()))
+            else:
+                name = tuple(sorted(json.loads(row[0]).keys()))
+
+            # Append the key list if it's not already in jsonKeys
+            if name not in jsonKeys:
+                jsonKeys.append(name)
+
+        print(jsonKeys) 
+        return jsonKeys
+
+
 @app.route('/add-data-header', methods=['POST'])
 def add_data_header():
     data_header = session.get('data_header', {'event':[], 'measurement':[], 'segment':[], 'segmentData':[]})
@@ -275,11 +340,7 @@ def add_data_header():
         obj = session.get('object_name', {})
         obj[current_table] = object_column
         session['object_name'] = obj
-        return jsonify()
 
-    print(observation.to_dict())
-    print("88888")
-    print(data_header)
     session['data_header'] = data_header
 
     data_header_table = generate_html_header_table()
@@ -304,6 +365,7 @@ def init_data_header_table():
 @app.route('/delete-data-header', methods=['POST'])
 def delete_data_header():
     data_header = session.get('data_header', {'event':[], 'measurement':[], 'segment':[], 'segmentData':[]})
+    obj = session.get('object_name', {})
     if data_header == {'event':[], 'measurement':[], 'segment':[], 'segmentData':[]}:
         data_header_table = generate_html_header_table()
         return jsonify({'data_header_table': data_header_table})
@@ -322,6 +384,10 @@ def delete_data_header():
         data_header['segment'].remove(res)
     elif type == 'SD':
         data_header['segmentData'].remove(res)
+    elif type == 'O':
+        print("delete object", res['tablename'], res)
+        obj.pop(res['tablename'], None)
+        session['object_name'] = obj
     session['data_header'] = data_header
 
     data_header_table = generate_html_header_table()
@@ -350,13 +416,16 @@ def get_MD_info():
     elif type == 'S':
         time = getTimeColumns(res['tablename'])          # list
         object = getObjectColumns(res['tablename'])      # list
-        # index = 
-        return jsonify({'time': time, 'object': object})
+        index = getIndexColumns(res['tablename'])        # list
+        return jsonify({'time': time, 'object': object, 'index': index})
     elif type == 'SD':
-        time = getTimeColumns(res['tablename'])          # list
-        object = getObjectColumns(res['tablename'])
-        # index = 
-        return jsonify({'time': time, 'object': object})
+        data_header = session.get('data_header', {'event':[], 'measurement':[], 'segment':[], 'segmentData':[]})
+        object = getObjectColumns(res['tablename'])      # list
+        index = getIndexColumns(res['tablename'])        # list
+        segment = [segment['label'][2] for segment in data_header['segment']]
+        print("Segment options")
+        print(segment)
+        return jsonify({'object': object, 'index': index, 'segment': segment})
 
 
 @app.route('/get-ME-table', methods=['POST'])
@@ -398,22 +467,259 @@ def get_ME_table():
     return jsonify({'table_HTML': table_HTML})
 
 
+@app.route('/get-S-table', methods=['POST'])
+def get_S_table():
+    engine = create_engine(session.get('db_uri', ''))
+    data = request.json
+    current_data_header = session.get('current_data_header', {'tablename': '', 'type': '', 'label': [], 'features_name': []})
+    table_name = current_data_header['tablename']
+    type = current_data_header['type']
+    object_column = data['object_column']
+    optgroupLabel = data['optgroupLabel']
+    object_list = [optgroupLabel, object_column]
+    index_column = data['index_column']
+    starttime_column = data['starttime_column']
+    endtime_column = data['endtime_column']
+    label_list = current_data_header['label']
+    
+    start_time = datetime.strptime(data['minDatetime'], '%Y-%m-%d %H:%M:%S') if 'minDatetime' in data else None
+    end_time = datetime.strptime(data['maxDatetime'], '%Y-%m-%d %H:%M:%S') if 'maxDatetime' in data else None
+
+    print(table_name)
+    print(type)
+    print(starttime_column)
+    print(endtime_column)
+    print(object_list)
+    print(label_list)
+
+    query_result = extract_S_table(engine, table_name, starttime_column, endtime_column, index_column, object_list, label_list, start_time, end_time)
+    table_HTML = get_ME_table_HTML(query_result)
+
+    if start_time == None and end_time == None:
+        min_datetime, max_datetime = get_min_max_datetime2(engine, table_name, starttime_column, endtime_column)
+        return jsonify({'table_HTML': table_HTML, 'min_datetime': min_datetime, 'max_datetime': max_datetime})
+
+    return jsonify({'table_HTML': table_HTML})
+
+
+@app.route('/get-SD-table', methods=['POST'])
+def get_SD_table():
+    engine = create_engine(session.get('db_uri', ''))
+    # Get the current data header from the session
+    current_data_header = session.get('current_data_header', {'tablename': '', 'type': '', 'label': [], 'features_name': []})
+    table_name = current_data_header['tablename']
+    type = current_data_header['type']
+    label_list = current_data_header['label']
+    features = []
+    for feature in current_data_header['features_name']:
+        if '(' in feature and ')' in feature:         # "value('coarse', 'fine')"
+            feature = feature.replace("'", "")
+            features.append(feature)
+        else:
+            features.append(feature)
+    # Input data from the frontend
+    data = request.json    # { 'object_column': object_column, 'optgroupLabel': optgroupLabel, 'index_column': index_column, 'segment_column': segment_column}
+    object_column = data['object_column']
+    optgroupLabel = data['optgroupLabel']
+    object_list = [optgroupLabel, object_column]
+    index_column = data['index_column']
+    segment_column = data['segment_column']
+
+    print("get_SD_table")
+    print(table_name)
+    print(type)
+    print(segment_column)
+    print(object_list)
+    print(label_list)
+
+    index_from = int(data['index_from']) if 'index_from' in data else None
+    index_to = int(data['index_to']) if 'index_to' in data else None
+
+    query_result = extract_SD_table(engine, table_name, object_list, label_list, segment_column, index_column, features, index_from, index_to)
+    table_HTML = get_ME_table_HTML(query_result)
+
+    if index_from == None and index_to == None:
+        min_index, max_index = get_min_max_index(engine, table_name, index_column)
+        return jsonify({'table_HTML': table_HTML, 'min_index': min_index, 'max_index': max_index})
+
+    return jsonify({'table_HTML': table_HTML})
+
+
+@app.route('/add-data-table', methods=['POST'])
+def add_data_table():
+    data = request.json
+    selected_rows = data['selectedRowsData']
+    current_row_type = data['currentRowType'] # 'E', 'M', 'S', 'SD'
+    data_tables = session.get('data_tables', {'O':[], 'S':[], 'SD':[]})
+
+    for i in selected_rows:
+        print(i)   #{'column0': '', 'column1': '1560628', 'column2': ' label A ', 'column3': '215', 'column4': '2000-07-16 22:00:00.000000', 'column5': '2000-07-17 21:59:59.999000'}
+
+    if current_row_type in ['E', 'M']:
+        data_tables['O'].extend(selected_rows)
+        data_tables['O'].sort(key=lambda x: datetime.strptime(x.get('column1', '9999-12-31 23:59:59.00000'), '%Y-%m-%d %H:%M:%S.%f'))  # Adjust 'columnTime' to your time column key
+    elif current_row_type == 'S':
+        data_tables[current_row_type].extend(selected_rows)
+        data_tables['S'].sort(key=lambda x:  datetime.strptime(x.get('column4', '9999-12-31 23:59:59.00000'), '%Y-%m-%d %H:%M:%S.%f'))  # Adjust 'columnTime' to your time column key
+    else :
+        data_tables['SD'].extend(selected_rows)
+        data_tables['SD'].sort(key=lambda x: x.get('column2', ''))  # Group data by 'label'
+    
+    session['data_tables'] = data_tables
+    table_html = generate_html_data_table(data_tables[current_row_type], current_row_type) if current_row_type in ['S', 'SD'] else generate_html_data_table(data_tables['O'], 'O')
+
+    return jsonify({'table_HTML': table_html})
+
+
+@app.route('/reset-machine-data-table', methods=['POST'])
+def reset_machine_data_table():
+
+    data_tables = {'O':[], 'S':[], 'SD':[]}
+    session['data_tables'] = data_tables
+
+    return jsonify({})
+
+
+@app.route('/export-Header-to-csv', methods=['POST'])
+def export_Header_to_csv():
+    data = request.get_json()  # This is the data sent from the frontend
+    if not data:
+        raise ValueError("No data provided for export.")
+    
+    # Find the maximum number of columns in any row
+    max_columns = max(len(row) for row in data)
+    
+    # Ensure all rows have the same number of columns (pad with None if necessary)
+    for row in data:
+        if row[1] == 'O':
+            data.remove(row)
+        while len(row) < max_columns:
+            row.append(None)
+    
+    headers = ['type', 'label'] # List your headers here
+    if max_columns > (len(headers) + 1):
+        headers.extend([f'f_{index + 1}' for index in range(max_columns-len(headers)-1)])
+    
+    # Skip the first column
+    df = pd.DataFrame(data)
+    df = df.iloc[:, 1:] 
+    
+    # Rename the DataFrame headers
+    df.columns = headers 
+
+    # Convert the DataFrame to a CSV string
+    csv_output = io.StringIO()
+    df.to_csv(csv_output, index=False)
+    csv_output.seek(0)
+
+    # Create a Flask response
+    response = make_response(csv_output.getvalue())
+    response.headers["Content-Disposition"] = "attachment; filename=header.csv"
+    response.headers["Content-Type"] = "text/csv"
+
+    return response
+
+
 @app.route('/export-to-csv', methods=['POST'])
 def export_to_csv():
 
     data = request.get_json()  # This is the data sent from the frontend
+    if not data:
+        raise ValueError("No data provided for export.")
+
+    # Find the maximum number of columns in any row
+    max_columns = max(len(row) for row in data)
+    
+    # Ensure all rows have the same number of columns (pad with None if necessary)
+    for row in data:
+        while len(row) < max_columns:
+            row.append(None)
+    
+    # Create a DataFrame from the data
     df = pd.DataFrame(data)
 
+    # Adjust the dataframe to skip the first column and rename the headers
+    headers = ['time', 'object', 'type', 'label'] # List your headers here
+    if max_columns > len(headers):
+        headers.extend([f'f_{index + 1}' for index in range(max_columns-len(headers))])
+
+    # Rename the DataFrame headers
+    df.columns = headers 
+
+     # Convert the DataFrame to a CSV string
+    csv_output = io.StringIO()
+    df.to_csv(csv_output, index=False)
+    csv_output.seek(0)
+
+    # Create a Flask response
+    response = make_response(csv_output.getvalue())
+    response.headers["Content-Disposition"] = "attachment; filename=observations.csv"
+    response.headers["Content-Type"] = "text/csv"
+
+    return response
+
+
+@app.route('/export-S-to-csv', methods=['POST'])
+def export_S_to_csv():
+
+    data = request.get_json()  # This is the data sent from the frontend
     if not data:
         raise ValueError("No data provided for export.")
 
+    # Find the maximum number of columns in any row
+    max_columns = max(len(row) for row in data)
+    
+    # Ensure all rows have the same number of columns (pad with None if necessary)
+    for row in data:
+        while len(row) < max_columns:
+            row.append(None)
+    
+    # Create a DataFrame from the data
+    df = pd.DataFrame(data)
+
     # Adjust the dataframe to skip the first column and rename the headers
-    df = df.iloc[:, 1:]  # Skip the first column
-    headers = ['time', 'object', 'type', 'label'] # List your headers here
-    num_features = len(data[0]) - len(headers) - 1
-    headers.extend([f'f_{i+1}' for i in range(num_features)])
-    df.columns = headers # Rename the DataFrame headers
+    headers = ['object', 'segment', 'segment_index', 'start', 'end'] # List your headers here
+    if max_columns > len(headers):
+        headers.extend([f'f_{index + 1}' for index in range(max_columns-len(headers))])
+
+    # Rename the DataFrame headers
+    df.columns = headers 
+     # Convert the DataFrame to a CSV string
+    csv_output = io.StringIO()
+    df.to_csv(csv_output, index=False)
+    csv_output.seek(0)
+
+    # Create a Flask response
+    response = make_response(csv_output.getvalue())
+    response.headers["Content-Disposition"] = "attachment; filename=segments.csv"
+    response.headers["Content-Type"] = "text/csv"
 
+    return response
+
+
+@app.route('/export-SD-to-csv', methods=['POST'])
+def export_SD_to_csv():
+
+    data = request.get_json()  # This is the data sent from the frontend
+    
+    # Find the maximum number of columns in any row
+    max_columns = max(len(row) for row in data)
+    
+    # Ensure all rows have the same number of columns (pad with None if necessary)
+    for row in data:
+        while len(row) < max_columns:
+            row.append(None)
+    
+    # Create a DataFrame from the data
+    df = pd.DataFrame(data)
+
+    # Adjust the dataframe to skip the first column and rename the headers
+    headers = ['object', 'segment', 'segment_index', 'label']  # List your headers here
+    if max_columns > len(headers):
+        headers.extend([f'f_{index + 1}' for index in range(max_columns-len(headers))])
+
+    # Rename the DataFrame headers
+    df.columns = headers 
 
      # Convert the DataFrame to a CSV string
     csv_output = io.StringIO()
@@ -422,11 +728,12 @@ def export_to_csv():
 
     # Create a Flask response
     response = make_response(csv_output.getvalue())
-    response.headers["Content-Disposition"] = "attachment; filename=exported_data.csv"
+    response.headers["Content-Disposition"] = "attachment; filename=segment_data.csv"
     response.headers["Content-Type"] = "text/csv"
 
     return response
 
+
 def readHeaderHTML(str):
     soup = BeautifulSoup(str, 'html.parser')
     tds = soup.find_all('td')
@@ -434,25 +741,28 @@ def readHeaderHTML(str):
     res = {'tablename': '', 'type': '', 'label': [], 'features_name': []}
     res['tablename'] = tds[1].get_text()
     res['type'] = tds[2].get_text()
-    res['label'] = json.loads(tds[3]['data-value'])
-    features = []
-    for td in tds[4:]:
-        data_value = td['data-value']
-        value_list = json.loads(data_value)
-        if value_list[0] == '':
-            a = value_list[1]
-            features.append(a)
-        else:
-            a = value_list[0] + '(' 
-            for i in range(len(value_list)-1):
-                a += "'" + value_list[i+1] + "', "
-            a = a[:len(a)-2]
-            a += ')'
-            if a not in features:
+    if res['type'] == 'O':
+        data_value = tds[3].get_text()
+    else: 
+        res['label'] = json.loads(tds[3]['data-value'])
+        features = []
+        for td in tds[4:]:
+            data_value = td['data-value']
+            value_list = json.loads(data_value)
+            if value_list[0] == '':
+                a = value_list[1]
                 features.append(a)
-    res['features_name'] = features   # ['machine_id', "value('coarse', 'fine')"]
+            else:
+                a = value_list[0] + '(' 
+                for i in range(len(value_list)-1):
+                    a += "'" + value_list[i+1] + "', "
+                a = a[:len(a)-2]
+                a += ')'
+                if a not in features:
+                    features.append(a)
+        res['features_name'] = features   # ['machine_id', "value('coarse', 'fine')"]
 
-    print(features)
+        print(features)
 
     return res
 
@@ -501,7 +811,7 @@ def handle_json_column(engine, table_name, column_name):
             if name not in jsonKeys:
                 jsonKeys.append(name)
 
-        print(jsonKeys)
+        print(jsonKeys) 
         return jsonKeys
 
 
@@ -557,7 +867,7 @@ def generate_html_header_table():
     for key in content.keys():
         for dict_item in content[key]:
             table_html += f"<tr onclick='getRowData(this)'>"
-            table_html += "<td><button type='button' class='btn-close'  aria-label='Close' data-bs-dismiss='modal' onclick='deleteRow1(event, this)'></button></td>"
+            table_html += "<td><button type='button' class='btn-close'  aria-label='Close' onclick='deleteRow1(event, this)'></button></td>"
             table_html += f"<td>{dict_item.get('tablename', '')}</td>"
             table_html += f"<td data-id>{dict_item.get('type', '')}</td>"
             print("723723")
@@ -584,11 +894,80 @@ def generate_html_header_table():
                     table_html += f"<td data-value='{data_value}'>{value}</td>"
             index += 1
             table_html += "</tr>"
+
+    # Add object table row to header table
+    obj = session.get('object_name', {})
+    for key in obj.keys():
+        table_html += "<tr>"
+        table_html += "<td><button type='button' class='btn-close'  aria-label='Close' onclick='deleteRow1(event, this)'></button></td>"
+        table_html += f"<td>{key}</td>"
+        table_html += f"<td>O</td>"
+        table_html += f"<td>{obj[key]}</td>"
+        table_html += "</tr>"
+
     table_html += "</tbody></table>"
     print(table_html)
     return table_html
 
 
+def generate_html_data_table(data_tables:list, table_type:str):
+    # Generate column headers
+    table_html = "<thead><tr>"
+    table_html += "<th></th>"
+    if table_type == 'O':
+        table_html += "<th class='uk-table-expand'>time</th>"
+        table_html += "<th>object</th>"
+        table_html += "<th>type</th>"
+        table_html += "<th class='uk-table-expand'>label</th>"
+        max_features = max(len(row) - 5 for row in data_tables) # Assuming first 4 keys are not features
+        for i in range(max_features): 
+            table_html += f"<th>f_{i+1}</th>"
+    elif table_type == 'S':
+        table_html += "<th>object</th>"
+        table_html += "<th class='uk-table-expand'>segment</th>"
+        table_html += "<th>segment_index</th>"
+        table_html += "<th class='uk-table-expand'>start</th>"
+        table_html += "<th class='uk-table-expand'>end</th>"
+
+    elif table_type == 'SD':
+        table_html += "<th>object</th>"
+        table_html += "<th class='uk-table-expand'>segment</th>"
+        table_html += "<th>segment_index</th>"
+        table_html += "<th class='uk-table-expand'>label</th>"
+        max_features = max(len(row) - 5 for row in data_tables) # Assuming first 4 keys are not features
+        for i in range(max_features): 
+            table_html += f"<th>f_{i+1}</th>"
+
+    table_html += "</tr></thead><tbody>"
+
+    # Generate table rows
+    if table_type == 'SD':
+        for row in data_tables:
+            table_html += f"<tr>"
+            table_html += "<td><button type='button' class='btn-close'  aria-label='Close' onclick='deleteRow2(event, this)'></button></td>"
+            for i in range(len(row) - 1):
+                if i == 1:
+                    table_html += f"<td>{row.get('column3', '')}</td>"
+                elif i == 2:
+                    table_html += f"<td>{row.get('column4', '')}</td>"
+                elif i == 3:
+                    table_html += f"<td>{row.get('column2', '')}</td>"
+                else:
+                    table_html += f"<td>{row.get('column' + str(i+1), '')}</td>"
+            table_html += "</tr>"
+    else:    
+        for row in data_tables:
+            table_html += f"<tr>"
+            table_html += "<td><button type='button' class='btn-close'  aria-label='Close' data-bs-dismiss='modal' onclick='deleteRow2(event, this)'></button></td>"
+            for i in range(len(row) - 1):
+                table_html += f"<td>{row.get('column' + str(i+1), '')}</td>"
+            table_html += "</tr>"
+
+    table_html += "</tbody>"
+    print(table_html)
+    return table_html
+
+
 def generate_html_table(content):
     if not content:
         return "No data found."
@@ -616,6 +995,7 @@ def getTimeColumns(table_name:str) -> list:
     schema = getTableSchema(table_name) if insp.dialect.name == 'postgresql' else insp.default_schema_name
     columns = insp.get_columns(table_name, schema)
     timestamp_columns = [column['name'] for column in columns if str(column['type']) == 'TIMESTAMP']
+    print("timestamp columns")
     print(timestamp_columns)
 
     return timestamp_columns
@@ -626,12 +1006,25 @@ def getObjectColumns(table_name:str) -> list:
     insp = inspect(engine)
     schema = getTableSchema(table_name) if insp.dialect.name == 'postgresql' else insp.default_schema_name
     columns = insp.get_columns(table_name, schema)
-    object_columns = [column['name'] for column in columns if str(column['type']) == 'VARCHAR' or str(column['type']) == 'INTEGER' or  str(column['type']) == 'NUMERIC']
+    object_columns = [column['name'] for column in columns if str(column['type']) == 'VARCHAR' or str(column['type']) == 'INTEGER' or  str(column['type']) == 'NUMERIC' or  str(column['type']) == 'TEXT' or  str(column['type']) == 'SMALLINT']
+    print("object columns")
     print(object_columns)
 
     return object_columns
 
 
+def getIndexColumns(table_name:str) -> list:
+    engine = create_engine(session.get('db_uri', ''))
+    insp = inspect(engine)
+    schema = getTableSchema(table_name) if insp.dialect.name == 'postgresql' else insp.default_schema_name
+    columns = insp.get_columns(table_name, schema)
+    index_columns = [column['name'] for column in columns if str(column['type']) == 'INTEGER' or  str(column['type']) == 'NUMERIC' or  str(column['type']) == 'BIGINT' or  str(column['type']) == 'SMALLINT']
+    print("index columns")
+    print(index_columns)
+
+    return index_columns
+
+
 def query_database_for_table_content(engine, table_name, number=200):
     # Initialize content list
     content_list = []
@@ -727,6 +1120,46 @@ def get_min_max_datetime(engine, table_name, time_column, start_time=None, end_t
         return None, None
 
 
+def get_min_max_datetime2(engine, table_name, starttime_column, endtime_column, start_time=None, end_time=None):
+    schema = getTableSchema(table_name) if engine.dialect.name == 'postgresql' else engine.dialect.default_schema_name
+    # Formulate the SQL query using the text function
+    query = text(f"SELECT MIN({starttime_column}) AS start_datetime, MAX({endtime_column}) AS end_datetime FROM {schema}.{table_name};")
+
+    # Execute the query
+    with engine.connect() as connection:
+        row = connection.execute(query).mappings().fetchone()
+
+    # Extract the min and max datetime values
+    if row:
+        min_datetime, max_datetime = row['start_datetime'], row['end_datetime']
+        print("Minimum datetime:", min_datetime)
+        print("Maximum datetime:", max_datetime)
+        return min_datetime, max_datetime
+    else:
+        print("No datetimes found.")
+        return None, None
+
+
+def get_min_max_index(engine, table_name, index_column):
+    schema = getTableSchema(table_name) if engine.dialect.name == 'postgresql' else engine.dialect.default_schema_name
+    # Formulate the SQL query using the text function
+    query = text(f"SELECT MIN({index_column}) AS start_index, MAX({index_column}) AS end_index FROM {schema}.{table_name};")
+
+    # Execute the query
+    with engine.connect() as connection:
+        row = connection.execute(query).mappings().fetchone()
+
+    # Extract the min and max datetime values
+    if row:
+        min_index, max_index = row['start_index'], row['end_index']
+        print("Minimum index:", min_index)
+        print("Maximum index:", max_index)
+        return min_index, max_index
+    else:
+        print("No indexes found.")
+        return None, None
+
+
 def extract_ME_table(engine, table_name: str, type: str, time_column: str, object: list, label: list, features_name: list, start_time: datetime = None, end_time: datetime = None) -> list:
     conn = engine.connect()
     insp = inspect(engine)
@@ -799,9 +1232,6 @@ def extract_ME_table(engine, table_name: str, type: str, time_column: str, objec
     if end_time:
         params['end_time'] = end_time
 
-
-    # res = conn.execute(text(sql_query), params).fetchall()
-        
     # Print the query for debugging
     print("SQL Query:", sql_query)
     print("Parameters:", params)
@@ -831,6 +1261,197 @@ def extract_ME_table(engine, table_name: str, type: str, time_column: str, objec
     return final_res
 
 
+def extract_S_table(engine, table_name: str, starttime_column: str, endtime_column: str, index_column: str, object: list, label: list, start_time: datetime = None, end_time: datetime = None) -> list:
+    conn = engine.connect()
+    insp = inspect(engine)
+    database_name = insp.dialect.name      # 'postgresql' or 'sqlite'
+    table_instance = getTableInstance(engine, table_name)
+    label_column = label[1].strip()
+    label_value = label[2].strip()
+    object_column_value = object[1].strip()
+    join_clause = ''
+
+    full_table_name = f"{table_instance.schema}.{table_instance.name}" if table_instance.schema else table_instance.name
+    sql_columns = []
+
+    # Handling object_column logic
+    if object[0].strip()  != 'self' and object[0].strip()  == 'col':
+        print("1")
+        object_column = table_instance.getColumn(object_column_value)
+        object_column_name = object_column.fkof.table.name if object_column.fkof else ''
+        if object_column and object_column.fkof and object_column_name in session.get('object_name', {}):
+            related_table_instance = getTableInstance(engine,  object_column_name)
+            full_related_table_name = f"{related_table_instance.schema}.{related_table_instance.name}" if related_table_instance.schema else related_table_instance.name
+            join_clause = f"LEFT JOIN {full_related_table_name} ON {full_table_name}.{object_column.name} = {full_related_table_name}.{object_column.fkof.name}"
+            sql_columns.append(f"{full_related_table_name}.{session.get('object_name').get(object_column_name)} AS {object_column_value}")
+        else:
+            sql_columns.append(f"{full_table_name}.{object_column.name}")
+    print("12")
+    # If label[0] is not 'self', add it to SQL columns
+    if label[0].strip() != 'self':
+        sql_columns.append(f"{full_table_name}.{label_column}")
+    print("123")
+
+    # Adding index, starttime, endtime columns to the select clause
+    sql_columns.append(f"{full_table_name}.{index_column}")
+    sql_columns.append(f"{full_table_name}.{starttime_column}")
+    sql_columns.append(f"{full_table_name}.{endtime_column}")
+    
+    # Adding JSON extractions to the select clause
+    sql_select = ', '.join(sql_columns)
+
+    # Constructing SQL query
+    sql_joins = join_clause
+    if label[0].strip() == 'col':
+        sql_where = f"WHERE {full_table_name}.{label_column} = :label_value"
+        if start_time:
+            sql_where += f" AND {full_table_name}.{starttime_column} >= :start_time AND {full_table_name}.{endtime_column} >= :start_time"
+        if end_time:
+            sql_where += f" AND {full_table_name}.{starttime_column} <= :end_time AND {full_table_name}.{endtime_column} <= :end_time"
+    else:
+        sql_where = ''
+        if start_time:
+            sql_where += f"WHERE {full_table_name}.{starttime_column} >= :start_time AND {full_table_name}.{endtime_column} >= :start_time"
+        if end_time:
+            sql_where += f" AND {full_table_name}.{starttime_column} <= :end_time AND {full_table_name}.{endtime_column} <= :end_time"
+
+    sql_query = f"SELECT {sql_select} FROM {full_table_name} {sql_joins} {sql_where} ORDER BY {starttime_column} ASC LIMIT 500"
+    print("12345")
+    # Executing the query
+    params = {'label_value': label_value}
+    if start_time:
+        params['start_time'] = start_time
+    if end_time:
+        params['end_time'] = end_time
+
+    # Print the query for debugging
+    print("SQL Query:", sql_query)
+    print("Parameters:", params)
+    
+    # Executing the query
+    try:
+        res = conn.execute(text(sql_query), params).fetchall()
+    except Exception as e:
+        print(f"Error executing query: {e}")
+        return []
+
+    # Append object and label values if necessary
+    final_res = []
+    for row in res:
+        modified_row = list(row)
+        if object[0].strip()  == 'self':
+            modified_row.insert(0, object_column_value)
+        if label[0].strip()  == 'self':
+            label_index = 1 if object[0].strip()  != 'self' else 0
+            modified_row.insert(label_index, label[2])
+
+        final_res.append(modified_row)
+
+    for row in final_res:
+        print(row)
+
+    return final_res
+
+
+def extract_SD_table(engine, table_name: str, object: list, label: list, segment_column: str, index_column: str, features_name: list, index_from: int = None, index_to: int = None) -> list:
+    conn = engine.connect()
+    insp = inspect(engine)
+    database_name = insp.dialect.name      # 'postgresql' or 'sqlite'
+    table_instance = getTableInstance(engine, table_name)
+    label_column = label[1].strip()
+    label_value = label[2].strip()
+    object_column_value = object[1].strip()
+    join_clause = ''
+
+    full_table_name = f"{table_instance.schema}.{table_instance.name}" if table_instance.schema else table_instance.name
+    sql_columns = []
+
+    # Handling object_column logic
+    if object[0].strip()  != 'self' and object[0].strip()  == 'col':
+        print("1")
+        object_column = table_instance.getColumn(object_column_value)
+        object_column_name = object_column.fkof.table.name if object_column.fkof else ''
+        if object_column and object_column.fkof and object_column_name in session.get('object_name', {}):
+            related_table_instance = getTableInstance(engine,  object_column_name)
+            full_related_table_name = f"{related_table_instance.schema}.{related_table_instance.name}" if related_table_instance.schema else related_table_instance.name
+            join_clause = f"LEFT JOIN {full_related_table_name} ON {full_table_name}.{object_column.name} = {full_related_table_name}.{object_column.fkof.name}"
+            sql_columns.append(f"{full_related_table_name}.{session.get('object_name').get(object_column_name)} AS {object_column_value}")
+        else:
+            sql_columns.append(f"{full_table_name}.{object_column.name}")
+    print("12")
+    # If label[0] is not 'self', add it to SQL columns
+    if label[0].strip() != 'self':
+        sql_columns.append(f"{full_table_name}.{label_column}")
+    print("123")
+    # Adding index columns to the select clause 
+    sql_columns.append(f"{full_table_name}.{index_column}")
+    # Handling JSON extractions
+    json_extractions = []
+    for feature in features_name:
+        if '(' in feature and ')' in feature:
+            column_name, keys = feature[:-1].split('(')
+            keys = keys.split(', ')
+            for key in keys:
+                if database_name == 'postgresql':
+                    json_extraction = f"{full_table_name}.{column_name}->>'{key}' AS {key}"
+                elif database_name == 'sqlite':
+                    json_extraction = f"json_extract({full_table_name}.{column_name}, '$.{key}') AS {key}"
+                json_extractions.append(json_extraction)
+        else:
+            sql_columns.append(f"{full_table_name}.{feature}")
+    print("1234")
+    # Adding JSON extractions to the select clause
+    sql_select = ', '.join(sql_columns + json_extractions)
+    
+    # Constructing SQL query
+    sql_joins = join_clause
+    if label[0].strip() == 'col':
+        sql_where = f"WHERE {full_table_name}.{label_column} = :label_value"
+        if index_from:
+            sql_where += f" AND {full_table_name}.{index_column} >= :index_from"
+        if index_to:
+            sql_where += f" AND {full_table_name}.{index_column} <= :index_to"
+    else:
+        sql_where = ''
+        if index_from:
+            sql_where += f" WHERE {full_table_name}.{index_column} >= :index_from"
+        if index_to:
+            sql_where += f" AND {full_table_name}.{index_column} <= :index_to"
+
+    sql_query = f"SELECT {sql_select} FROM {full_table_name} {sql_joins} {sql_where} ORDER BY {index_column} ASC LIMIT 500"
+    print("12345")
+    # Executing the query
+    params = {'label_value': label_value, 'index_from': index_from, 'index_to': index_to}
+
+    # Print the query for debugging
+    print("SQL Query:", sql_query)
+    print("Parameters:", params)
+    
+    # Executing the query
+    try:
+        res = conn.execute(text(sql_query), params).fetchall()
+    except Exception as e:
+        print(f"Error executing query: {e}")
+        return []
+
+    # Append object and label values if necessary
+    final_res = []
+    for row in res:
+        modified_row = list(row)
+        if object[0].strip()  == 'self':
+            modified_row.insert(0, object_column_value)
+        if label[0].strip()  == 'self':
+            label_index = 1 if object[0].strip()  != 'self' else 0
+            modified_row.insert(label_index, label[2])
+        modified_row.insert(2, segment_column)
+        final_res.append(modified_row)
+
+    for row in final_res:
+        print(row)
+
+    return final_res
+
+
 def get_ME_table_HTML(data: list) -> str:
     # Start the HTML <body> content with an opening <table> tag
     html_content = ""
@@ -841,7 +1462,7 @@ def get_ME_table_HTML(data: list) -> str:
         for cell in row:
             if isinstance(cell, datetime):
                 # cell = cell.isoformat()
-                cell = cell.strftime('%Y-%m-%d %H:%M:%S:%f') 
+                cell = cell.strftime('%Y-%m-%d %H:%M:%S.%f') 
             html_content += f"<td>{cell}</td>"
         html_content += "</tr>\n"
 
diff --git a/models/__pycache__/__init__.cpython-311.pyc b/models/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..df4fecfba13b7c10abc18bb87debc8b989d42686
Binary files /dev/null and b/models/__pycache__/__init__.cpython-311.pyc differ
diff --git a/models/__pycache__/models.cpython-311.pyc b/models/__pycache__/models.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..780e177e25900a2bae7265a22e612d24724b20c3
Binary files /dev/null and b/models/__pycache__/models.cpython-311.pyc differ
diff --git a/models/__pycache__/models.cpython-39.pyc b/models/__pycache__/models.cpython-39.pyc
index 2e0a8d9d8d7c2f1d91d5104ea76cf387a4a83dbe..4dcb5a8fa921e8dc45deed97019797f6eac214e2 100644
Binary files a/models/__pycache__/models.cpython-39.pyc and b/models/__pycache__/models.cpython-39.pyc differ
diff --git a/models/models.py b/models/models.py
index f01eeb36ba9657d8d40b20a327537ccb37de939e..9c517d5a92206c629955aaf2bfd651ce5d57d44b 100644
--- a/models/models.py
+++ b/models/models.py
@@ -1,4 +1,3 @@
-from sqlalchemy import ARRAY, BIGINT, BOOLEAN, DOUBLE_PRECISION, FLOAT, INTEGER, JSON, NUMERIC, SMALLINT, TIMESTAMP, UUID, VARCHAR, MetaData, String, create_engine, text, inspect
 from sqlalchemy.types import UserDefinedType
 import re
 
@@ -7,7 +6,7 @@ class Observation_Spec:
     def __init__(self, tablename:str, type:str, label:list[str], features_name:list = None):
         self.tablename = tablename
         self.type = type    # 'event' or 'measurement'
-        self.label = label  # (self-define or from column, column name, column value orself-define label)
+        self.label = label  # (self-define or from column, column name, column value or self-define label)
         self.features_name = features_name if features_name else []
 
     def add_feature(self, name):
diff --git a/templates/app.html b/templates/app.html
index f8e43df24b8acb232936589e2520ef1094a7c523..44e755e687a21cce520d16cf6b2a50aad96e83cc 100644
--- a/templates/app.html
+++ b/templates/app.html
@@ -222,7 +222,7 @@
         }
         .uk-table-hover tbody tr:hover {
             background-color: #5ea9e2;
-            color: white;
+            color:#add8e6;
         }
         .terminal.resizing .terminal-header {
             cursor: ns-resize;
@@ -283,7 +283,16 @@
             position: sticky;
             top: 0;
         }
-
+        .uk-tooltip {
+            border-radius: 5px !important; 
+        }
+        .accordion-container {
+            margin-top: 26px;
+            display: flex;
+            flex-direction: column;
+            height: 83vh; /* or adjust as necessary */
+            overflow: hidden; /* This prevents the overall container from scrolling */
+        }
     </style>
 </head>
 <body>
@@ -292,14 +301,14 @@
     <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js" integrity="sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy" crossorigin="anonymous"></script>
     
     <div id="sidebar1">   <!--class="uk-panel uk-panel-scrollable" -->
-        <legend>Database:</legend>
+        <legend uk-tooltip="title: Show the database name.; pos: right">Database:</legend>
         <div class="mb-3">
             <label for="disabledTextInput" class="form-label" style="margin-top: 10px;">{{database}}.db</label>
         </div>
         
         <ul uk-accordion>
             <li>
-                <a class="uk-accordion-title" href="#">Database URL</a>
+                <a class="uk-accordion-title" href="#" style="text-decoration: none;" uk-tooltip="title: Provide a valid databsae connection here.; pos: right">Database URL</a>
                 <div class="uk-accordion-content">
                     
                     <form method="post" action="/">
@@ -315,7 +324,7 @@
 
 
             <li>
-                <a class="uk-accordion-title" href="#">Filter</a>
+                <a class="uk-accordion-title" href="#" style="text-decoration: none;" uk-tooltip="title: Use these filters to refine the tables displayed below; pos: right">Filter</a>
                 <div class="uk-accordion-content">
 
                     <div class="accordion">
@@ -333,7 +342,7 @@
                                         <label class="form-check-label" for="showAllClick" style="margin-top: 3px;">
                                             Primary Tables
                                         </label>
-                                        <select class="form-select" name="schema" id="schemaSelect" onchange="this.form.submit()" onclick="openTables()" style="padding: 0px 1px 2px 1px;">
+                                        <select class="form-select" name="schema" id="schemaSelect" onchange="this.form.submit()" style="padding: 0px 1px 2px 1px;">
                                             <option value="">Choose here</option>
                                             {% for schema in schemas %}
                                             <option value="{{ schema }}" {% if schema == schema_Selected %} selected {% endif %}>{{ schema }}</option>
@@ -385,15 +394,15 @@
             </li>
 
 
-            <li class="uk-class">
-                <a class="uk-accordion-title" href="#">Tables</a>
+            <li class="uk-class uk-open"></li>
+                <a class="uk-accordion-title" href="#" style="text-decoration: none;" uk-tooltip="title: Reorder the tables by dragging the rows to the designated area below.; pos: right">Tables</a>
                 <div class="uk-accordion-content">
 
                     <div class="border border-secondary rounded" id="table_list" style="margin-bottom: 5px; margin-top: -10px;">
                         <div id="table_list_source">
                             <div id="show_tables1" uk-sortable="group: sortable-group" class="uk-list  uk-list-collapse">
                                 {% for table in tables %}
-                                    <div id="show_tables2" class="uk-margin" style="height: 15px; margin-bottom: -4px;">
+                                    <div id="show_tables2" class="uk-margin" style="height: 15px; margin-bottom: -4px; width: 230px;">
                                         <div class="list-group-item-action uk-card uk-card-default uk-card-body uk-card-small " style="height: 15px; padding-top: 5px;">{{ table }}</div>
                                     </div>
                                 {% endfor %}
@@ -406,27 +415,26 @@
         </ul>
 
 
-        <legend style="margin-top: 3px;">Target Tables:</legend>
+        <legend style="margin-top: 3px;" uk-tooltip="title: Activate the selected table to populate the data in the scrollable terminal section and for Step 2 procedures.; pos: right">Target Tables:</legend>
         <div class="border border-secondary rounded" id="table_list" >
             <div id="dropped_items" uk-sortable="group: sortable-group" class="uk-list uk-list-collapse ">
-                <!-- <div > -->
                 {% for item in dropped_items %}
-                    <div class="uk-margin" style="height: 15px; margin-bottom: -4px;">
+                    <div class="uk-margin" style="height: 15px; margin-bottom: -4px; width: 230px;">
                         <div class="list-group-item-action uk-card uk-card-default uk-card-body uk-card-small"  style="height: 15px; padding-top: 5px;">{{ item }}</div>
                     </div>
                 {% endfor %}
-                <!-- </div> -->
             </div>
         </div>
-        <button id="resetButton" class="btn btn-secondary headerButton">Reset</button>
+        <button id="resetButton" class="btn btn-secondary headerButton" uk-tooltip="title: Empty target table.; pos: bottom">Reset</button>
     </div> 
     
     <div id="content">
         <button class="uk-button uk-button-default uk-button-small custom-push-button" type="button" uk-toggle="target: #sidebar1" onclick="toggleSidebar()"></button>      
         <ul uk-tab class="uk-flex-center" data-uk-tab="{connect:'#my-id'}" style="margin-top: 10px; z-index: 0;">
-            <li><a href="#">ERD</a></li>
-            <li><a href="#">Create Data Header</a></li>
-            <li><a href="#">Create Data instance</a></li>
+            <li><a href="#" style="text-decoration: none;" uk-tooltip="title: Display a comprehensive summary of the database contents.;pos: bottom">Step1: Overview</a></li>
+            <li><a href="#" style="text-decoration: none;" uk-tooltip="title: Construct the data header based on the selection from the prior step, to be utilized in Step 3.;pos: bottom">Step2: Create Data Header</a></li>
+            <li><a href="#" style="text-decoration: none;" uk-tooltip="title: Generate a detailed data table corresponding to each row of the data header, with options for additional refinement.;pos: bottom">Step3: Create Data instance</a></li>
+            <li><a href="#" style="text-decoration: none;" uk-tooltip="title: Display the generated data tables, with options for exporting to csv files.;pos: bottom">Step4: Established Data Table</a></li>
         </ul>
 
         <!-- <div> -->
@@ -476,10 +484,10 @@
                     <div style="flex-grow: 1; padding-left: 10px; margin-top: 3px; display: flex; flex-direction: column;">
                     
                     <fieldset>
-                        <legend style="margin: .2em .2em .4em -.4em; color:#5ea9e2; border-bottom: 1px solid gray; padding-bottom: 5px; padding-right: 3px;">Data Header</legend>
+                        <legend style="margin: .2em .2em .4em -.4em; color:#5ea9e2; border-bottom: 1px solid gray; padding-bottom: 5px; padding-right: 3px;" uk-tooltip="title: Define the structure of the header table to be used in Step 3; pos: right">Data Header</legend>
 
-                        <div class="mb-3">
-                            <label class="form-label" style="margin-top: 14px">Type</label>
+                        <div class="mb-3" style="padding-bottom: 5px; border-bottom: 1px dashed black; margin-bottom: 3px;">
+                            <label class="form-label" style="margin-top: 8px;" uk-tooltip="title: Select the type of data header; each type requires different information to be specified; pos: left">Type</label>
                             <div class="uk-grid-small uk-child-width-auto uk-grid">
                                 <label><input class="uk-radio type-radio" type="radio" name="radio1" value="measurement" checked> Measurement </label><br><br>
                                 <label><input class="uk-radio type-radio" type="radio" name="radio1" value="event"> Event </label><br><br>
@@ -491,13 +499,13 @@
 
 
                         <div class="mb-3" id="self-defined-object-selection" style="display: none; border-bottom: 1px dashed black;">
-                            <label class="form-label">Self-defined Object</label><br>
-                            <input type="text" id="defined-object" class="form-control headerSelect">
-                            <button class="btn btn-primary headerButton" onclick="selfdefinedObject()">add</button>
+                            <label class="form-label" uk-tooltip="title: Create a custom object name that can be used in a header instead of using predefined database table data; pos: left">Self-defined Object</label><br>
+                            <input type="text" id="defined-object" class="form-control headerSelect" placeholder="Enter object name">
+                            <button class="btn btn-primary headerButton" onclick="selfdefinedObject()">add</button><span id="selfdefinedObject" style="color: red; font-size: 80%; margin-left: 2px;"></span>
                         </div>
 
                         <div class="mb-3" id="object-column-selection" style="display: none;">
-                            <label class="form-label">Object name</label><br>
+                            <label class="form-label" uk-tooltip="title: Designate a specific column from the selected table to represent unique object names; pos: left">Object name</label><br>
                             <select id="select_column_object" class="form-select headerSelect" name="column" style="margin-right: 5px; display: inline;">
                             {% for column in columns %}
                                 <option>Select a table first...</option>
@@ -506,14 +514,14 @@
                             </select><span style="color: red; font-size: 80%;">*</span>
                         </div>
 
-                        <div class="mb-3" id="self-defined-label-selection">
-                            <label class="form-label">Self-defined Label</label><br>
-                            <input type="text" id="defined-label" class="form-control headerSelect">
-                            <button class="btn btn-primary headerButton" onclick="addLabel()">add</button>
+                        <div class="mb-3" id="self-defined-label-selection" style="border-bottom: 1px dashed black;">
+                            <label class="form-label" uk-tooltip="title: Create a custom label that can be used in the label selection below instead of using predefined database table columns.; pos: left">Self-defined Label</label><br>
+                            <input type="text" id="defined-label" class="form-control headerSelect" placeholder="Enter label name">
+                            <button class="btn btn-primary headerButton" onclick="addLabel()">add</button><span id="addLabel" style="color: red; font-size: 80%; margin-left: 2px;"></span>
                         </div>
                         
                         <div class="mb-3" id="label-selection">
-                            <label class="form-label">Label</label>
+                            <label class="form-label" uk-tooltip="title: Choose a label from the available columns in the selected database table.; pos: left">Label</label>
                             <select id="select_column" class="form-select headerSelect" name="column" onchange='handleLabelColumnClick(value)'>
                             {% for column in columns %}
                                 <option>Select a table first...</option>
@@ -538,18 +546,20 @@
                         </div>
 
                         <div class="mb-3" id="featuresSelection">
-                            <label class="form-label">Feature</label><br />
-                            <select id="select_features" name = "value_column[]" data-placeholder="Slect a table first..." multiple class="chosen-select" tabindex="4">        
-                                {% for column in columns %}
-                                    <option>Column select...</option>
-                                    <option value="{{label}}">{{ label }}</option>
-                                {% endfor %}
+                            <label class="form-label" uk-tooltip="title: Select one or multiple feature columns from the chosen table to include in the data header.; pos: left">Feature</label><br />
+                            <select id="select_features" name = "value_column[]" data-placeholder="Slect a table first..." multiple class="chosen-select">        
                             </select>  
-                            <script> $(".chosen-select").chosen({tabindex: 6}); $("#select_features").css('font-size','25px'); </script>
+                            <script> 
+                                $(document).ready(function() {
+                                    $(".chosen-select").chosen({
+                                        tabindex: 2
+                                    }).css('font-size', '25px');
+                                }); 
+                            </script>
                             <span id="span"></span><span style="color: red; font-size: 80%;">*</span><br>
                         </div>
 
-                            <button type="submit" class="btn btn-primary headerButton" onclick="submitDataHeader()" style="margin-top: -11px;">Submit</button>
+                            <button type="submit" class="btn btn-primary headerButton" onclick="submitDataHeader()" style="margin-top: -11px;">Submit</button><span id="submitDataHeader" style="color: red; font-size: 80%; margin-bottom: 5px;"></span>
                     </fieldset>
                     </div>
 
@@ -564,7 +574,7 @@
                         <button type="submit" class="btn btn-primary uk-button-small headerButton" style="margin-top: -3px;" onclick="resetDataHeaderTable()">Reset</button>
                     </div>
                     <div class="uk-overflow-auto" id="data-header-table" style="flex-grow: 1; overflow-y: auto; max-height: max-content; margin-top: -20px;">
-                        <table class='uk-table uk-table-small uk-table-hover uk-table-divider'>
+                        <table id="H-table" class='uk-table uk-table-small uk-table-hover uk-table-divider'>
                             <thead>
                                 <tr>
                                     <th></th>
@@ -578,22 +588,22 @@
                     <div class="mb-3">
                         <h4 style="display: inline; margin-left: .2em;">Machine Data Table (LIMIT 500)</h4>
                         <button type="submit" class="btn btn-primary uk-button-small headerButton" style="margin-top: -3px;" onclick="resetMachineDataTable()">Reset</button>
-                        <button type="submit" class="btn btn-primary uk-button-small headerButton" style="margin-top: -3px;" onclick="">Add</button>
-                        <button type="submit" class="btn btn-primary uk-button-small headerButton" style="margin-top: -3px;" onclick="exportSelectedRowsToCSV()">Export</button>
+                        <button type="submit" class="btn btn-primary uk-button-small headerButton" style="margin-top: -3px;" onclick="addDataTable()">Add</button>
+                        <span id="addDataTable" style="color: red; font-size: 80%; margin-left: 2px; margin-bottom: 1px;"></span>
                     </div>
                     <div class="uk-overflow-auto" id="machine-data-table" style="flex-grow: 1; overflow-y: auto; max-height: max-content; margin-top: -20px;" >
                         <table  id="MD-table" class="uk-table uk-table-hover uk-table-small uk-table-middle uk-table-divider uk-table-striped" style="cursor: pointer;">
                             <thead>
                                 <tr class="uk-table-middle">
                                     <th class="uk-table-shrink">
-                                        <input class="uk-checkbox" onclick="click_all_MD_table(this)" type="checkbox" aria-label="Checkbox" style="margin-top: 7px;">
+                                        <input class="uk-checkbox" id="click_all" onclick="click_all_MD_table(this)" type="checkbox" aria-label="Checkbox" style="margin-top: 7px;">
                                     </th>
 
                                     <th data-id="time" class="uk-table-expand">
                                         <span style="display: flex; flex-direction: row; margin-bottom: -4px;">
                                             time
-                                            <select id="table_select_time"  class="time-object-select" style="width: 80px; height: 20px; margin-top: -3px; margin-left: 3px;">
-                                                <option>Select a data header first...</option>
+                                            <select id="table_select_time"  class="observation-select" style="width: 160px; height: 20px; margin-top: -3px; margin-left: 3px;">
+                                                <option value="no">Select a data header first...</option>
                                             </select>
                                         </span>
                                     </th>
@@ -601,7 +611,7 @@
                                     <th data-id="object" class="uk-table-expand">
                                         <span style="display: flex; flex-direction: row; margin-bottom: -4px;">
                                             object
-                                            <select id="table_object" class="time-object-select" style="width: 80px; height: 20px; margin-top: -3px; margin-left: 3px;">
+                                            <select id="table_object" class="observation-select segment-select segment-data-select" style="width: 160px; height: 20px; margin-top: -3px; margin-left: 3px;">
                                                 <option value="no">Select a data header first...</option>
                                                 
                                                 <optgroup id="defined_object_values" label="self-defined object">
@@ -615,15 +625,29 @@
                                     </th>
 
                                     <th data-id="type" class="uk-width-small">type</th>
-                                    <th data-id="label" class="uk-table-expand">label</th>
-                                    <th data-id="segment" class="uk-table-expand">segment</th>
-                                    <th data-id="index" class="uk-table-expand">index</th>
+                                    <th data-id="label" class="uk-width-small">label</th>
+                                    <th data-id="segment" class="uk-table-expand">
+                                        <span style="display: flex; flex-direction: row; margin-bottom: -4px;">
+                                            segment
+                                            <select id="segment-label-select" class="segment-data-select" style="width: 160px; height: 20px; margin-top: -3px; margin-left: 3px;">
+                                                <option value="no">Select a column first...</option>
+                                            </select>
+                                        </span>
+                                    </th>
+                                    <th data-id="index" class="uk-table-expand">
+                                        <span style="display: flex; flex-direction: row; margin-bottom: -4px;">
+                                            index
+                                            <select id="index-select" class="segment-select segment-data-select" style="width: 160px; height: 20px; margin-top: -3px; margin-left: 3px;">
+                                                <option value="no">Select a column first...</option>
+                                            </select>
+                                        </span>
+                                    </th>
                                     
                                     <th data-id="starttime" class="uk-table-expand">
                                         <span style="display: flex; flex-direction: row; margin-bottom: -4px;">
                                             start time
-                                            <select id="starttime-select" style="width: 80px; height: 20px; margin-top: -3px; margin-left: 3px;">
-                                                <option val="no">Select a column first...</option>
+                                            <select id="starttime-select" class="segment-select" style="width: 160px; height: 20px; margin-top: 6px; margin-left: 3px;">
+                                                <option value="no">Select a column first...</option>
                                             </select>
                                         </span>
                                     </th>
@@ -631,8 +655,8 @@
                                     <th data-id="endtime" class="uk-table-expand">
                                         <span style="display: flex; flex-direction: row; margin-bottom: -4px;">
                                             end time
-                                            <select id="endtime-select" style="width: 80px; height: 20px; margin-top: -3px; margin-left: 3px;">
-                                                <option val="no">Select a column first...</option>
+                                            <select id="endtime-select" class="segment-select" style="width: 160px; height: 20px; margin-top: 6px; margin-left: 3px;">
+                                                <option value="no">Select a column first...</option>
                                             </select>
                                         </span>
                                     </th>
@@ -645,6 +669,36 @@
                     </div>
                 </div>
             </li>
+            <li>
+                <div class="accordion-container">
+                    <button type="submit" class="btn btn-primary uk-button-small headerButton" onclick="resetMachineDataTable2()" style="position: absolute; right: 13vh; top:32px;">Reset</button>
+                    <button type="submit" class="btn btn-primary uk-button-small headerButton" onclick="exportSelectedRowsToCSV()" style="position: absolute; right: 1vh; top:32px;">Export</button>
+                    <ul uk-accordion>
+                        <li class="uk-open">
+                            <a class="uk-accordion-title" style="text-decoration: none; background-color: #ccc;" href>Observation Table</a>
+                            <div class="uk-accordion-content" style="max-height: 60vh; flex: 1; overflow-y: auto;">
+                                <!-- <h4 style="display: inline; margin-left: .2em;">Observation Table</h4> -->
+                                <table  id="ME-table" class="uk-table uk-table-hover uk-table-small uk-table-middle uk-table-divider uk-table-striped" style="cursor: pointer;">
+                                </table>
+                            </div>
+                        </li>
+                        <li>
+                            <a class="uk-accordion-title" style="text-decoration: none; background-color: #ccc;" href>Segment Table</a>
+                            <div class="uk-accordion-content" style="max-height: 60vh; flex: 1; overflow-y: auto;">
+                                <table  id="S-table" class="uk-table uk-table-hover uk-table-small uk-table-middle uk-table-divider uk-table-striped" style="cursor: pointer;">
+                                </table>
+                            </div>
+                        </li>
+                        <li>
+                            <a class="uk-accordion-title" style="text-decoration: none; background-color: #ccc;" href>Segment Data Table</a>
+                            <div class="uk-accordion-content" style="max-height: 60vh; flex: 1; overflow-y: auto;">
+                                <table  id="SD-table" class="uk-table uk-table-hover uk-table-small uk-table-middle uk-table-divider uk-table-striped" style="cursor: pointer;">
+                                </table>
+                            </div>
+                        </li>
+                    </ul>
+                </div>
+            </li>
         </ul>
         <!-- </div> -->
 
@@ -666,17 +720,16 @@
     <div id="sidebar2">
         <ul uk-accordion>
             <li>
-                <a class="uk-accordion-title" href="#">Filter</a>
+                <a class="uk-accordion-title" style="text-decoration: none;" href="#">Filter</a>
                 <div class="uk-accordion-content">
-
                     <div class="accordion">
                         <div class="accordion-item">
                           <h2 class="accordion-header">
-                            <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseTwo" aria-expanded="true" aria-controls="collapseTwo">
+                            <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapse1" aria-expanded="true" aria-controls="collapse1">
                               Time
                             </button>
                           </h2>
-                          <div id="collapseTwo" class="accordion-collapse collapse" data-bs-parent="#accordionExample">
+                          <div id="collapse1" class="accordion-collapse collapse" data-bs-parent="#accordionExample">
                             <div class="accordion-body">
                                 <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
                                 <script src="//code.jquery.com/jquery-3.6.0.min.js"></script>
@@ -693,6 +746,35 @@
                             </div>
                           </div>
                         </div>
+                        <div class="accordion-item">
+                            <h2 class="accordion-header">
+                                <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapse2" aria-expanded="true" aria-controls="collapse2">
+                                    Segment Index
+                                </button>
+                            </h2>
+                            <div id="collapse2" class="accordion-collapse collapse" data-bs-parent="#accordionExample">
+                                <div class="accordion-body">
+                                    <p style="margin: -4px -21px 5px -17px; padding: 0px;">
+                                        <label for="fromInput">From: </label>
+                                        <input type="number" id="fromInput" min="0" step="1" style="width: 8vh;"/><br><br>
+                                        <label for="toInput">To: </label>
+                                        <input type="number" id="toInput" min="0" step="1" style="width: 8vh; margin-left: 20px;"/>
+                                    </p>
+                                    <button type="submit" class="btn btn-primary headerButton" style="margin: 10px 0px -5px -10px;" onclick="filter_SD_data_table()">Submit</button>
+                                    <script>
+                                        var fromInput = document.getElementById('fromInput');
+                                        var toInput = document.getElementById('toInput');
+
+                                        fromInput.addEventListener('input', function() {
+                                            toInput.min = this.value;
+                                            if (parseInt(toInput.value) < parseInt(this.value)) {
+                                                toInput.value = this.value;
+                                            }
+                                        });
+                                    </script>
+                                </div>
+                            </div>
+                          </div>
                     </div>
         
                 </div>
@@ -705,6 +787,8 @@
     </div> 
 <!----------------------------------------------------------------------------------------------------->
     <script>
+        var currentRowType = null; // Defined at a higher scope, accessible globally
+
         var jq = jQuery.noConflict();
         function initializeSlider(minDatetime, maxDatetime) {
             // Default values if min or max datetime is not provided
@@ -770,7 +854,38 @@
         }
 
 
-        function exportSelectedRowsToCSV() {
+        // Function to check if the necessary information is filled in the Machine Data table
+        function checkBottomTableInfo() {
+            // Check the values of inputs/selects in the bottom table
+            var objectSelected = document.getElementById('table_object').value;
+            var timeSelected = document.getElementById('table_select_time').value;
+            var segmentSelected = document.getElementById('segment-label-select').value;
+            var indexSelected = document.getElementById('index-select').value;
+            var starttimeSelected = document.getElementById('starttime-select').value;
+            var endtimeSelected = document.getElementById('endtime-select').value;
+
+            if (currentRowType === 'M' || currentRowType === 'E'){
+                 // Check if the values are not empty or not equal to the default "no" value
+                if (objectSelected === 'no' || timeSelected === 'no') {
+                    return false; // Information is not complete
+                }
+            } else if (currentRowType === 'S') {
+                if (objectSelected === 'no' || indexSelected === 'no' || starttimeSelected === 'no' || endtimeSelected === 'no') {
+                    return false; // Information is not complete
+                }
+            } else if (currentRowType === 'SD') {
+                if (objectSelected === 'no' || segmentSelected === 'no' || indexSelected === 'no') {
+                    return false; // Information is not complete
+                }
+            } else {
+                console.error('Unknown type:', currentRowType);
+                return false; // Information is not complete
+            }
+            return true; // Information is complete
+        }
+
+
+        function addDataTable() {
             // Collect all selected rows from the Machine Data Table
             var selectedRowsData = [];
             document.querySelectorAll('#MD-table input[type="checkbox"]:checked').forEach(function(checkbox) {
@@ -781,27 +896,191 @@
                 });
                 selectedRowsData.push(rowData);
             });
+            document.getElementById("click_all").checked = false;
 
-            // Send the selected rows data to the Flask backend
-            fetch('/export-to-csv', {
-                method: 'POST',
-                body: JSON.stringify(selectedRowsData),
-                headers: {
-                    'Content-Type': 'application/json'
+            if (currentRowType != null && selectedRowsData.length > 0) {
+                // Check if the necessary information is filled in the Machine Data table
+                if (!checkBottomTableInfo()) {
+                    alert('Please fill in the necessary information in the Machine Data table.');
+                    return;
                 }
-            })
-            .then(response => response.blob()) // Get the file blob from the response
-            .then(blob => {
-                // Create a link element and click it to download the file
-                var url = window.URL.createObjectURL(blob);
-                var a = document.createElement('a');
-                a.href = url;
-                a.download = 'exported_data.csv';
-                document.body.appendChild(a);
-                a.click();
-                a.remove();
-            })
-            .catch(error => console.error('Error:', error));
+                document.getElementById("addDataTable").textContent = "Add successfully!";
+                setTimeout(function() {
+                    document.getElementById("addDataTable").textContent = "";
+                }, 2000);
+
+                // Send the selected rows data to the Flask backend
+                fetch('/add-data-table', {
+                    method: 'POST',
+                    body: JSON.stringify({'selectedRowsData': selectedRowsData, 'currentRowType': currentRowType}),
+                    headers: {
+                        'Content-Type': 'application/json'
+                    }
+                })
+                .then(response => response.json())
+                .then(data => {
+                    // Update the Machine Data Table with the new data
+                    if (currentRowType == 'M' || currentRowType == 'E') {
+                        const table = document.getElementById('ME-table');
+                        table.innerHTML = data['table_HTML'];
+                    } else if (currentRowType == 'S') {
+                        const table = document.getElementById('S-table');
+                        table.innerHTML = data['table_HTML'];
+                    } else if (currentRowType == 'SD') {
+                        const table = document.getElementById('SD-table');
+                        table.innerHTML = data['table_HTML'];
+                    }
+                })
+
+            } else if (currentRowType == null) {
+                alert('Please select a row from the Data Header table.');
+                return;
+            } else {
+                alert('Please select a row from the Machine Data table.');
+                return;
+            }
+        }
+
+
+        function exportSelectedRowsToCSV() {
+            //////////////// Collect all selected rows from the Machine Data Table -- Observation Table/////////////////
+            var selectedRowsData = [];
+            document.querySelectorAll('#ME-table tbody tr').forEach(function(row) {
+                var rowData = [];
+                row.querySelectorAll('td').forEach(function(td, index) {
+                    // Exclude the first column with the button
+                    if (index !== 0) { 
+                        rowData.push(td.textContent.trim());
+                    }
+                });
+                selectedRowsData.push(rowData);
+            });
+            if (selectedRowsData.length > 0) {
+                // Send the selected rows data to the Flask backend
+                fetch('/export-to-csv', {
+                    method: 'POST',
+                    body: JSON.stringify(selectedRowsData),
+                    headers: {
+                        'Content-Type': 'application/json'
+                    }
+                })
+                .then(response => response.blob()) // Get the file blob from the response
+                .then(blob => {
+                    // Create a link element and click it to download the file
+                    var url = window.URL.createObjectURL(blob);
+                    var a = document.createElement('a');
+                    a.href = url;
+                    a.download = 'observations.csv';
+                    document.body.appendChild(a);
+                    a.click();
+                    a.remove();
+                })
+                .catch(error => console.error('Error:', error));
+            }
+            //////////////// Collect all selected rows from the Machine Data Table -- Segment Table/////////////////
+            var selectedRowsDataS = [];
+            document.querySelectorAll('#S-table tbody tr').forEach(function(row) {
+                var rowData = [];
+                row.querySelectorAll('td').forEach(function(td, index) {
+                    // Exclude the first column with the button
+                    if (index !== 0) { 
+                        rowData.push(td.textContent.trim());
+                    }
+                });
+                selectedRowsDataS.push(rowData);
+            });
+            if (selectedRowsDataS.length > 0) {
+                // Send the selected rows data to the Flask backend
+                fetch('/export-S-to-csv', {
+                    method: 'POST',
+                    body: JSON.stringify(selectedRowsDataS),
+                    headers: {
+                        'Content-Type': 'application/json'
+                    }
+                })
+                .then(response => response.blob()) // Get the file blob from the response
+                .then(blob => {
+                    // Create a link element and click it to download the file
+                    var url = window.URL.createObjectURL(blob);
+                    var a = document.createElement('a');
+                    a.href = url;
+                    a.download = 'segments.csv';
+                    document.body.appendChild(a);
+                    a.click();
+                    a.remove();
+                })
+                .catch(error => console.error('Error:', error));
+            }
+            //////////////// Collect all selected rows from the Machine Data Table -- Segment Data Table/////////////////
+            var selectedRowsDataSD = [];
+            document.querySelectorAll('#SD-table tbody tr').forEach(function(row) {
+                var rowData = [];
+                row.querySelectorAll('td').forEach(function(td, index) {
+                    // Exclude the first column with the button
+                    if (index !== 0) { 
+                        rowData.push(td.textContent.trim());
+                    }
+                });
+                selectedRowsDataSD.push(rowData);
+            });
+            if (selectedRowsDataSD.length > 0) {
+                // Send the selected rows data to the Flask backend
+                fetch('/export-SD-to-csv', {
+                    method: 'POST',
+                    body: JSON.stringify(selectedRowsDataSD),
+                    headers: {
+                        'Content-Type': 'application/json'
+                    }
+                })
+                .then(response => response.blob()) // Get the file blob from the response
+                .then(blob => {
+                    // Create a link element and click it to download the file
+                    var url = window.URL.createObjectURL(blob);
+                    var a = document.createElement('a');
+                    a.href = url;
+                    a.download = 'segment_data.csv';
+                    document.body.appendChild(a);
+                    a.click();
+                    a.remove();
+                })
+                .catch(error => console.error('Error:', error));
+            }
+            //////////////// Collect all selected rows from the Machine Data Table -- Header Table/////////////////
+            var selectedRowsDataHeader = [];
+            document.querySelectorAll('#data-header-table table tbody tr').forEach(function(row) {
+                var rowData = [];
+                row.querySelectorAll('td').forEach(function(td, index) {
+                    // Exclude the first column with the button
+                    if (index !== 0) { 
+                        rowData.push(td.textContent.trim());
+                    }
+                });
+                selectedRowsDataHeader.push(rowData);
+            });
+            console.log("Header csv");
+            console.log(selectedRowsDataHeader);
+            // Send the selected rows data to the Flask backend
+            if (selectedRowsDataHeader.length > 0) {
+                fetch('/export-Header-to-csv', {
+                    method: 'POST',
+                    body: JSON.stringify(selectedRowsDataHeader),
+                    headers: {
+                        'Content-Type': 'application/json'
+                    }
+                })
+                .then(response => response.blob()) // Get the file blob from the response
+                .then(blob => {
+                    // Create a link element and click it to download the file
+                    var url = window.URL.createObjectURL(blob);
+                    var a = document.createElement('a');
+                    a.href = url;
+                    a.download = 'header.csv';
+                    document.body.appendChild(a);
+                    a.click();
+                    a.remove();
+                })
+                .catch(error => console.error('Error:', error));
+            }
         }
 
 
@@ -816,6 +1095,26 @@
         function resetMachineDataTable() {
             const table = document.getElementById('MD-table');
             table.querySelector('tbody').innerHTML = ""
+            document.getElementById("click_all").checked = false;
+            table.querySelectorAll('select').forEach(function(select) {
+                select.value = "no";
+            });
+        }
+
+
+        function resetMachineDataTable2() {
+            const tableME = document.getElementById('ME-table');
+            tableME.innerHTML = "";
+            const tableS = document.getElementById('S-table');
+            tableS.innerHTML = "";
+            const tableSD = document.getElementById('SD-table');
+            tableSD.innerHTML = "";
+            fetch('/reset-machine-data-table', {
+                method: 'POST',
+                headers: {
+                    'Content-Type': 'application/json'
+                }
+            })
         }
         
 
@@ -826,6 +1125,7 @@
             var value = r.innerHTML;
             r.style.backgroundColor = "#5ea9e2";
             const type = r.querySelectorAll("td")[2].innerHTML; // type: M, E, S, SD
+            currentRowType = type; // Store the type in the higher scope variable
             var numColumns = r.querySelectorAll("td").length;
 
             const table = document.getElementById('MD-table');
@@ -849,7 +1149,7 @@
                 });
                 for (let i = 1; i <= numColumns - 4; i++) {
                     let th = tr.appendChild(document.createElement('th'));
-                    th.classList.add("uk-table-shrink");
+                    th.classList.add("uk-width-small");
                     th.innerHTML = "F_" + i;
                 }
             } else if (type == "S") {
@@ -862,10 +1162,14 @@
                 });
                 for (let i = 1; i <= numColumns - 4; i++) {
                     let th = tr.appendChild(document.createElement('th'));
-                    th.classList.add("uk-table-shrink");
+                    th.classList.add("uk-width-small");
                     th.innerHTML = "F_" + i;
                 }
             }
+            document.getElementById("click_all").checked = false;
+            table.querySelectorAll('select').forEach(function(select) {
+                select.value = "no";
+            });
 
             fetch('/get-MD-info', {
                 method: 'POST',
@@ -876,12 +1180,15 @@
             })
             .then(response => response.json())
             .then(data => {
-                // Set all the select elements to the default value
-                var selectTime = document.getElementById('table_select_time');
-                selectTime.value = "no";
+                // Set the select element to the default value
                 var selectObject = document.getElementById('table_object');
                 selectObject.value = "no";
                 
+                // Find the option with the value "no" and update its text content
+                var selectOption = document.querySelector('#table_object option[value="no"]');
+                if (selectOption) {
+                    selectOption.textContent = "Select a object...";
+                }
                 //////////////////////////////////////////////////////////////////////////
                 if (type == "M" || type == "E") {
                     // Update the time select with the new time columns
@@ -891,6 +1198,7 @@
                     init.value = "no";
                     init.textContent = "Select a column...";
                     selectTime.appendChild(init);
+                    selectTime.value = "no";
                     data['time'].forEach(label_value => {
                         const optionElement = document.createElement('option');
                         optionElement.value = label_value;
@@ -907,7 +1215,100 @@
                         selectObject.appendChild(optionElement);  
                     });
                 } else if (type == "S") {
+                    // Update the time select with the new time columns
+                    const selectStartTime = document.getElementById('starttime-select');
+                    const selectEndTime = document.getElementById('endtime-select');
+                    selectStartTime.innerHTML = '';  // Clear existing options
+                    selectEndTime.innerHTML = '';    // Clear existing options
+
+                    // Create initial "Select a column..." option for startTime
+                    let initStartTime = document.createElement('option');
+                    initStartTime.value = "no";
+                    initStartTime.textContent = "Select a column...";
+                    selectStartTime.appendChild(initStartTime);
+
+                    // Create initial "Select a column..." option for endTime
+                    let initEndTime = document.createElement('option');
+                    initEndTime.value = "no";
+                    initEndTime.textContent = "Select a column...";
+                    selectEndTime.appendChild(initEndTime);
+
+                    // Ensure both selects are set to the "no" value
+                    selectStartTime.value = "no";
+                    selectEndTime.value = "no";
+
+                    data['time'].forEach(label_value => {
+                        // Create option element for selectStartTime
+                        let optionElementStart = document.createElement('option');
+                        optionElementStart.value = label_value;
+                        optionElementStart.textContent = label_value;
+                        selectStartTime.appendChild(optionElementStart);
+
+                        // Create option element for selectEndTime
+                        let optionElementEnd = document.createElement('option');
+                        optionElementEnd.value = label_value;
+                        optionElementEnd.textContent = label_value;
+                        selectEndTime.appendChild(optionElementEnd);
+                    });
+                    // Update the object select with the new object columns
+                    const selectObject = document.getElementById('table_select_object');
+                    selectObject.innerHTML = '';  // Clear existing options
+                    data['object'].forEach(label_value => {
+                        const optionElement = document.createElement('option');
+                        optionElement.value = label_value;
+                        optionElement.textContent = label_value;
+                        selectObject.appendChild(optionElement);  
+                    });
+                    // Update the index select with the new index columns
+                    const selectIndex = document.getElementById('index-select');
+                    selectIndex.innerHTML = '';  // Clear existing options
+                    let initIndex = document.createElement('option');
+                    initIndex.value = "no";
+                    initIndex.textContent = "Select a column...";
+                    selectIndex.appendChild(initIndex);
+                    data['index'].forEach(label_value => {
+                        const optionElement = document.createElement('option');
+                        optionElement.value = label_value;
+                        optionElement.textContent = label_value;
+                        selectIndex.appendChild(optionElement);  
+                    });
                 } else if (type == "SD") {
+                    // Update the index select with the new time columns
+                    const selectIndex = document.getElementById('index-select');
+                    selectIndex.innerHTML = '';       // Clear existing options
+                    const initIndex = document.createElement('option');
+                    initIndex.value = "no";
+                    initIndex.textContent = "Select a column...";
+                    selectIndex.appendChild(initIndex);
+                    
+                    data['index'].forEach(label_value => {
+                        const optionElement = document.createElement('option');
+                        optionElement.value = label_value;
+                        optionElement.textContent = label_value;
+                        selectIndex.appendChild(optionElement);  
+                    });
+                    // Update the object select with the new object columns
+                    const selectSegment = document.getElementById('segment-label-select');
+                    selectSegment.innerHTML = '';     // Clear existing options
+                    const initSegment = document.createElement('option');
+                    initSegment.value = "no";
+                    initSegment.textContent = "Select a segment...";
+                    selectSegment.appendChild(initSegment);
+                    data['segment'].forEach(label_value => {
+                        const optionElement = document.createElement('option');
+                        optionElement.value = label_value;
+                        optionElement.textContent = label_value;
+                        selectSegment.appendChild(optionElement);  
+                    });
+                    // Update the object select with the new object columns
+                    const selectObject = document.getElementById('table_select_object');
+                    selectObject.innerHTML = '';  // Clear existing options
+                    data['object'].forEach(label_value => {
+                        const optionElement = document.createElement('option');
+                        optionElement.value = label_value;
+                        optionElement.textContent = label_value;
+                        selectObject.appendChild(optionElement);  
+                    });
                 }
             })
             .catch(error => {
@@ -916,26 +1317,269 @@
             });
         }
 
-
+        ///////////////////////////////////////OBSERVATION HEADER ROW///////////////////////////////////
         // Select only the specified select elements
-        const time_object_selects = document.querySelectorAll('.time-object-select');
+        const time_object_selects = document.querySelectorAll('.observation-select');
 
-        function checkSelects() {
-        for (let select of time_object_selects) {
-            if (select.value === 'no') {
-            return false; // If any watched select is not chosen, return false
+        function checkSelects(selects) {
+            for (let select of selects) {
+                console.log(select.value);
+                if (select.value == 'no') {
+                    return false; // If any watched select is not chosen, return false
+                }
             }
-        }
-        return true; // If all watched selects have a value, return true
+            return true; // If all watched selects have a value, return true
         }
 
         time_object_selects.forEach(select => {
-        select.addEventListener('change', () => {
-            if (checkSelects()) {
+            select.addEventListener('change', () => {
+                if (checkSelects(time_object_selects)) {
+                    console.log("get-ME-table");
+                    var $ = function(id) { return document.getElementById(id); };
+                    // All specified selects have a value, call the fetch function
+                    var time_column = document.getElementById('table_select_time').value;
+                    var object_column = document.getElementById('table_object').value;
+
+                    var selectedOption = $("table_object").options[$("table_object").selectedIndex]; // Get the selected option
+                    var optgroupLabel = selectedOption.parentNode.label;   // Get the label of the optgroup
+                    if (optgroupLabel == "self-defined object") {
+                        optgroupLabel = "self";
+                    } else if (optgroupLabel == "object column") {
+                        optgroupLabel = "col";
+                    }
+                    console.log(optgroupLabel);
+                    console.log(object_column);
+                    console.log(time_column);
+
+                    fetch('/get-ME-table', {
+                        method: 'POST',
+                        body: JSON.stringify({ 'time_column': time_column, 'object_column': object_column, 'optgroupLabel': optgroupLabel }),
+                        headers: {
+                            'Content-Type': 'application/json'
+                        }
+                    })
+                    .then(response => response.json())
+                    .then(data => {
+                        console.log(data['table_HTML']);
+                        const table = document.getElementById('MD-table');
+                        table.querySelector('tbody').innerHTML = ""
+                        table.querySelector('tbody').innerHTML = data['table_HTML'];
+
+                        if ('min_datetime' in data && 'max_datetime' in data) {
+                            // Initialize the slider with the min and max datetime from the server
+                            console.log("ME: initialize slider with min and max datetime from the server");
+                            initializeSlider(data['min_datetime'], data['max_datetime']);
+                        }
+                    })
+                    .catch(error => {
+                        // Handle any error that occurred during the fetch
+                        console.error('Error:', error);
+                    });
+                }
+            });
+        });
+        //////////////////////////////////////////////SEGMENT HEADER ROW//////////////////////////////////////////
+        const segment_selects = document.querySelectorAll('.segment-select');
+        
+        segment_selects.forEach(select => {
+            select.addEventListener('change', () => {
+                if (checkSelects(segment_selects)) {
+                    console.log("get-S-table");
+                    var $ = function(id) { return document.getElementById(id); };
+                    // All specified selects have a value, call the fetch function
+                    var index_column = $('index-select').value;
+                    var starttime_column = $('starttime-select').value;
+                    var endtime_column = $('endtime-select').value;
+                    var object_column = $("table_object").value;
+
+                    var selectedOption = $("table_object").options[$("table_object").selectedIndex]; // Get the selected option
+                    var optgroupLabel = selectedOption.parentNode.label;   // Get the label of the optgroup
+                    if (optgroupLabel == "self-defined object") {
+                        optgroupLabel = "self";
+                    } else if (optgroupLabel == "object column") {
+                        optgroupLabel = "col";
+                    }
+                    console.log(optgroupLabel);
+                    console.log(object_column);
+                    console.log(index_column);
+                    console.log(starttime_column);
+                    console.log(endtime_column);
+
+                    fetch('/get-S-table', {
+                        method: 'POST',
+                        body: JSON.stringify({ 'object_column': object_column, 'optgroupLabel': optgroupLabel , 'index_column': index_column, 'starttime_column': starttime_column, 'endtime_column': endtime_column}),
+                        headers: {
+                            'Content-Type': 'application/json'
+                        }
+                    })
+                    .then(response => response.json())
+                    .then(data => {
+                        console.log(data['table_HTML']);
+                        const table = document.getElementById('MD-table');
+                        table.querySelector('tbody').innerHTML = ""
+                        table.querySelector('tbody').innerHTML = data['table_HTML'];
+
+                        if ('min_datetime' in data && 'max_datetime' in data) {
+                            // Initialize the slider with the min and max datetime from the server
+                            console.log("S: initialize slider with min and max datetime from the server");
+                            initializeSlider(data['min_datetime'], data['max_datetime']);
+                        }
+                    })
+                    .catch(error => {
+                        // Handle any error that occurred during the fetch
+                        console.error('Error:', error);
+                    });
+                }
+            });
+        });
+        //////////////////////////////////////////////SEGMENT DATA HEADER ROW//////////////////////////////////////////
+        const segment_data_selects = document.querySelectorAll('.segment-data-select');
+        
+        segment_data_selects.forEach(select => {
+            select.addEventListener('change', () => {
+                if (checkSelects(segment_data_selects)) {
+                    console.log("get-SD-table");
+                    var $ = function(id) { return document.getElementById(id); };
+                    // All specified selects have a value, call the fetch function
+                    var index_column = $('index-select').value;
+                    var segment_column = $('segment-label-select').value;
+                    var object_column = $("table_object").value;
+
+                    var selectedOption = $("table_object").options[$("table_object").selectedIndex]; // Get the selected option
+                    var optgroupLabel = selectedOption.parentNode.label;   // Get the label of the optgroup
+                    if (optgroupLabel == "self-defined object") {
+                        optgroupLabel = "self";
+                    } else if (optgroupLabel == "object column") {
+                        optgroupLabel = "col";
+                    }
+                    console.log(optgroupLabel);
+                    console.log(object_column);
+                    console.log(index_column);
+                    console.log(segment_column);
+
+                    fetch('/get-SD-table', {
+                        method: 'POST',
+                        body: JSON.stringify({ 'object_column': object_column, 'optgroupLabel': optgroupLabel , 'index_column': index_column, 'segment_column': segment_column}),
+                        headers: {
+                            'Content-Type': 'application/json'
+                        }
+                    })
+                    .then(response => response.json())
+                    .then(data => {
+                        console.log(data['table_HTML']);
+                        const table = document.getElementById('MD-table');
+                        table.querySelector('tbody').innerHTML = ""
+                        table.querySelector('tbody').innerHTML = data['table_HTML'];
+
+                        if ('min_index' in data && 'max_index' in data) {
+                            // Initialize the slider with the min and max datetime from the server
+                            console.log("SD: initialize slider with min and max datetime from the server");
+                            document.getElementById('fromInput').value = min_index;
+                            document.getElementById('toInput').value = max_index;
+                        }
+                    })
+                    .catch(error => {
+                        // Handle any error that occurred during the fetch
+                        console.error('Error:', error);
+                    });
+                }
+            });
+        });
+
+
+        function filter_ME_data_table() {
+            var $ = function(id) { return document.getElementById(id); };
+            // Get min and max datetime from the slider
+            var minDatetime = $("amount1").value;
+            var maxDatetime = $("amount2").value;
+
+            // All specified selects have a value, call the fetch function
+            console.log(currentRowType);
+            var isInfoComplete = checkBottomTableInfo();
+            if (!isInfoComplete) {
+                // Information is not complete, warn the user
+                alert('Please complete all the required fields in the Machine Data Table before submitting.');
+            } else {
+                var object_column = document.getElementById('table_object').value;
+                var selectedOption = $("table_object").options[$("table_object").selectedIndex]; // Get the selected option
+                var optgroupLabel = selectedOption.parentNode.label;   // Get the label of the optgroup
+                if (optgroupLabel == "self-defined object") {
+                    optgroupLabel = "self";
+                } else if (optgroupLabel == "object column") {
+                    optgroupLabel = "col";
+                }
+
+                if (currentRowType == "M" || currentRowType == "E"){
+                    var time_column = document.getElementById('table_select_time').value;
+
+                    fetch('/get-ME-table', {
+                        method: 'POST',
+                        body: JSON.stringify({ 'time_column': time_column, 'object_column': object_column, 'optgroupLabel': optgroupLabel, 'minDatetime': minDatetime, 'maxDatetime': maxDatetime}),
+                        headers: {
+                            'Content-Type': 'application/json'
+                        }
+                    })
+                    .then(response => response.json())
+                    .then(data => {
+                        console.log(data['table_HTML']);
+                        const table = document.getElementById('MD-table');
+                        table.querySelector('tbody').innerHTML = ""
+                        table.querySelector('tbody').innerHTML = data['table_HTML'];
+                    })
+                    .catch(error => {
+                        // Handle any error that occurred during the fetch
+                        console.error('Error:', error);
+                    });
+                } else if (currentRowType == "S") {
+                    var index_column = document.getElementById('index-select').value;
+                    var starttime_column = document.getElementById('starttime-select').value;
+                    var endtime_column = document.getElementById('endtime-select').value;
+
+                    fetch('/get-S-table', {
+                        method: 'POST',
+                        body: JSON.stringify({ 'object_column': object_column, 'optgroupLabel': optgroupLabel, 'index_column': index_column, 'starttime_column': starttime_column, 'endtime_column': endtime_column, 'minDatetime': minDatetime, 'maxDatetime': maxDatetime}),
+                        headers: {
+                            'Content-Type': 'application/json'
+                        }
+                    })
+                    .then(response => response.json())
+                    .then(data => {
+                        console.log(data['table_HTML']);
+                        const table = document.getElementById('MD-table');
+                        table.querySelector('tbody').innerHTML = ""
+                        table.querySelector('tbody').innerHTML = data['table_HTML'];
+                    })
+                    .catch(error => {
+                        // Handle any error that occurred during the fetch
+                        console.error('Error:', error);
+                    });
+                } else if (currentRowType == "SD") {
+                    alert('This feature is not available for the Segment Data type.');
+                }
+            }
+        }
+
+
+        function filter_SD_data_table() {
+            var index_from = document.getElementById('fromInput').value;
+            var index_to = document.getElementById('toInput').value;
+            if (currentRowType != "SD") {
+                alert('This feature is only available for the Segment Data type.');
+                return;
+            } else if (index_from == "" || index_to == "") {
+                alert('Please fill in the index range.');
+                return;
+            } else if (parseInt(index_to) < parseInt(index_from)) {
+                index_to = index_from;
+            }
+
+            if (checkSelects(segment_data_selects)) {
+                console.log("get-SD-table");
                 var $ = function(id) { return document.getElementById(id); };
                 // All specified selects have a value, call the fetch function
-                var time_column = document.getElementById('table_select_time').value;
-                var object_column = document.getElementById('table_object').value;
+                var index_column = $('index-select').value;
+                var segment_column = $('segment-label-select').value;
+                var object_column = $("table_object").value;
 
                 var selectedOption = $("table_object").options[$("table_object").selectedIndex]; // Get the selected option
                 var optgroupLabel = selectedOption.parentNode.label;   // Get the label of the optgroup
@@ -944,13 +1588,10 @@
                 } else if (optgroupLabel == "object column") {
                     optgroupLabel = "col";
                 }
-                console.log(optgroupLabel);
-                console.log(object_column);
-                console.log(time_column);
 
-                fetch('/get-ME-table', {
+                fetch('/get-SD-table', {
                     method: 'POST',
-                    body: JSON.stringify({ 'time_column': time_column, 'object_column': object_column, 'optgroupLabel': optgroupLabel }),
+                    body: JSON.stringify({ 'object_column': object_column, 'optgroupLabel': optgroupLabel , 'index_column': index_column, 'segment_column': segment_column, 'index_from': index_from, 'index_to': index_to}),
                     headers: {
                         'Content-Type': 'application/json'
                     }
@@ -961,70 +1602,47 @@
                     const table = document.getElementById('MD-table');
                     table.querySelector('tbody').innerHTML = ""
                     table.querySelector('tbody').innerHTML = data['table_HTML'];
-
-                    if ('min_datetime' in data && 'max_datetime' in data) {
-                        // Initialize the slider with the min and max datetime from the server
-                        console.log("initialize slider with min and max datetime from the server");
-                        initializeSlider(data['min_datetime'], data['max_datetime']);
-                    }
                 })
                 .catch(error => {
                     // Handle any error that occurred during the fetch
                     console.error('Error:', error);
                 });
+            } else {
+                alert('Please complete all the required fields in the Machine Data Table before submitting.');
             }
-        });
-        });
-
-        function filter_ME_data_table() {
-            var $ = function(id) { return document.getElementById(id); };
-            // Get min and max datetime from the slider
-            var minDatetime = $("amount1").value;
-            var maxDatetime = $("amount2").value;
-
-            // All specified selects have a value, call the fetch function
-            var time_column = document.getElementById('table_select_time').value;
-            var object_column = document.getElementById('table_object').value;
-
-            var selectedOption = $("table_object").options[$("table_object").selectedIndex]; // Get the selected option
-            var optgroupLabel = selectedOption.parentNode.label;   // Get the label of the optgroup
-            if (optgroupLabel == "self-defined object") {
-                optgroupLabel = "self";
-            } else if (optgroupLabel == "object column") {
-                optgroupLabel = "col";
-            }
-            console.log(optgroupLabel);
-            console.log(object_column);
-            console.log(time_column);
-
-            fetch('/get-ME-table', {
-                method: 'POST',
-                body: JSON.stringify({ 'time_column': time_column, 'object_column': object_column, 'optgroupLabel': optgroupLabel, 'minDatetime': minDatetime, 'maxDatetime': maxDatetime}),
-                headers: {
-                    'Content-Type': 'application/json'
-                }
-            })
-            .then(response => response.json())
-            .then(data => {
-                console.log(data['table_HTML']);
-                const table = document.getElementById('MD-table');
-                table.querySelector('tbody').innerHTML = ""
-                table.querySelector('tbody').innerHTML = data['table_HTML'];
-            })
-            .catch(error => {
-                // Handle any error that occurred during the fetch
-                console.error('Error:', error);
-            });
         }
 
 
         function selfdefinedObject() {
             var object = document.getElementById('defined-object').value;
             var select = document.getElementById('defined_object_values');
-            var opt = document.createElement('option');
-            opt.value = object;
-            opt.innerHTML = object;
-            select.appendChild(opt);
+            // Check if the option already exists
+            var optionExists = Array.from(select.getElementsByTagName('option')).some(option => option.value === object);
+            console.log("optionExists");
+            console.log(optionExists);
+            if (object == "" || object == null || object == " ") {
+                document.getElementById("selfdefinedObject").textContent = "This field is required!";
+                setTimeout(function() {
+                    document.getElementById("selfdefinedObject").textContent = "";
+                }, 2000); // 5000 milliseconds = 5 seconds
+            }else if (!optionExists) {
+                var opt = document.createElement('option');
+                opt.value = object;
+                opt.innerHTML = object;
+                select.appendChild(opt);
+                document.getElementById("selfdefinedObject").textContent = "Submit successfully!";
+                setTimeout(function() {
+                    document.getElementById("selfdefinedObject").textContent = "";
+                }, 2000); // 5000 milliseconds = 5 seconds
+            } else {
+                document.getElementById("selfdefinedObject").textContent = "This object already exists!";
+                setTimeout(function() {
+                    document.getElementById("selfdefinedObject").textContent = "";
+                }, 2000); // 5000 milliseconds = 5 seconds
+            }
+            // Clear the input field
+            document.getElementById('defined-object').value = "";
+            
         }
 
 
@@ -1036,10 +1654,9 @@
             // var divv = document.getElementById("data-header-table");
             // divv.getElementsByTagName("table")[0].deleteRow(i);
 
-            var value = r.parentNode.parentNode.innerHTML
-            
-            console.log(value);
-            console.log("YYYYY");
+            var value = r.parentNode.parentNode.innerHTML 
+            console.log("heyheyyouyou");
+
             fetch('/delete-data-header', {
                 method: 'POST',
                 body: JSON.stringify({ 'value': value }),
@@ -1047,7 +1664,12 @@
                     'Content-Type': 'application/json'
                 }
             })
-            .then(response => response.json())
+            .then(response => {
+                if (!response.ok) {
+                    throw new Error('Network response was not ok');
+                }
+                return response.json();
+            })
             .then(data => {
                 const table = document.getElementById('data-header-table');
                 table.innerHTML = data['data_header_table'];
@@ -1060,6 +1682,14 @@
         }
 
 
+        function deleteRow2(event, r) {
+            event.stopPropagation(); // Stop the event from bubbling up to the <tr>
+            var i = r.parentNode.parentNode.rowIndex;
+            var table = r.closest("table");  // Find the closest table ancestor
+            table.deleteRow(i);
+        }
+
+
         function resetDataHeaderTable() {
             fetch('/reset-data-header-table', {
                 method: 'POST',
@@ -1101,14 +1731,13 @@
 
 
         function submitDataHeader() {
-            var $ = function(id) { return document.getElementById(id); };
             var isValid = true;
 
             var radioSelect = document.querySelector('input[name="radio1"]:checked');
 
-            var label_column = $("select_column").value;
-            var label = $("label_values").value; 
-            var selectedOption = $("label_values").options[$("label_values").selectedIndex]; // Get the selected option
+            var label_column = document.getElementById("select_column").value;
+            var label = document.getElementById("label_values").value; 
+            var selectedOption = document.getElementById("label_values").options[document.getElementById("label_values").selectedIndex]; // Get the selected option
             var optgroupLabel = selectedOption.parentNode.label;   // Get the label of the optgroup
             if (optgroupLabel == "label column data") {
                 optgroupLabel = "col";
@@ -1117,84 +1746,84 @@
             }
             var label_list = ' [" ' + optgroupLabel + ' "," ' + label_column + ' "," ' +  label + ' "] ';
 
-            var object_column = $("select_column_object").value;
+            var object_column = document.getElementById("select_column_object").value;
 
-            var tmp = $("select_features").selectedOptions;
+            var tmp = document.getElementById("select_features").selectedOptions;
             var features_list = Array.from(tmp).map(({ value }) => value);
 
             if (radioSelect.value == 'measurement') {
                 if (label == 'Label select...' || label == null || label == "") {
-                    $("label_values").nextElementSibling.textContent = "This field is required.";
+                    document.getElementById("label_values").nextElementSibling.textContent = "This field is required.";
                     // alert("Please select a label");
                     console.log("Label is required");
                     if (features_list.length == 0 || features_list == null || features_list == []) {
-                    $("span").nextElementSibling.textContent = "This field is required.";
-                    // alert("Please select a feature");
-                    console.log("Feature is required");
-                }
+                        document.getElementById("span").nextElementSibling.textContent = "This field is required.";
+                        // alert("Please select a feature");
+                        console.log("Feature is required");
+                    }
                     return;
                 }
                 if (features_list.length == 0 || features_list == null || features_list == []) {
-                    $("span").nextElementSibling.textContent = "This field is required.";
+                    document.getElementById("span").nextElementSibling.textContent = "This field is required.";
                     // alert("Please select a feature");
                     console.log("Feature is required");
                     return;
                 }
             } else if (radioSelect.value == 'event') {
                 if (label == 'Label select...' || label == null || label == "") {
-                    $("label_values").nextElementSibling.textContent = "This field is required.";
+                    document.getElementById("label_values").nextElementSibling.textContent = "This field is required.";
                     // alert("Please select a label");
                     console.log("Label is required");
                     if (features_list.length == 0 || features_list == null || features_list == []) {
-                    $("span").nextElementSibling.textContent = "This field is required.";
-                    // alert("Please select a feature");
-                    console.log("Feature is required");
-                }
+                        document.getElementById("span").nextElementSibling.textContent = "This field is required.";
+                        // alert("Please select a feature");
+                        console.log("Feature is required");
+                    }
                     return;
                 }
                 if (features_list.length == 0 || features_list == null || features_list == []) {
-                    $("span").nextElementSibling.textContent = "This field is required.";
+                    document.getElementById("span").nextElementSibling.textContent = "This field is required.";
                     // alert("Please select a feature");
                     console.log("Feature is required");
                     return;
                 }
             } else if (radioSelect.value == 'segment') {
                 if (label == 'Label select...' || label == null || label == '') {
-                    $("label_values").nextElementSibling.textContent = "This field is required.";
+                    document.getElementById("label_values").nextElementSibling.textContent = "This field is required.";
                     // alert("Please select a label");
                     console.log("Label is required");
                     return;
                 }
             } else if (radioSelect.value == 'segmentData') {
                 if (label == 'Label select...' || label == null || label == '') {
-                    $("label_values").nextElementSibling.textContent = "This field is required.";
+                    document.getElementById("label_values").nextElementSibling.textContent = "This field is required.";
                     // alert("Please select a label");
                     console.log("Label is required");
                     if (features_list.length == 0 || features_list == null || features_list == []) {
-                    $("span").nextElementSibling.textContent = "This field is required.";
-                    // alert("Please select a feature");
-                    console.log("Feature is required");
-                }
+                        document.getElementById("span").nextElementSibling.textContent = "This field is required.";
+                        // alert("Please select a feature");
+                        console.log("Feature is required");
+                    }
                     return;
                 }
                 if (features_list.length == 0 || features_list == null || features_list == []) {
-                    $("span").nextElementSibling.textContent = "This field is required.";
+                    document.getElementById("span").nextElementSibling.textContent = "This field is required.";
                     // alert("Please select a feature");
                     console.log("Feature is required");
                     return;
                 }
             } else if (radioSelect.value == 'object') {
                 if (object_column == 'Select a table first...' || object_column == null || object_column == '') {
-                    $("select_column_object").nextElementSibling.textContent = "This field is required.";
+                    document.getElementById("select_column_object").nextElementSibling.textContent = "This field is required.";
                     // alert("Please select an object column");
                     console.log("Object column is required");
                     return;
                 }
             }
 
-            $("label_values").nextElementSibling.textContent = "*";
-            $("span").nextElementSibling.textContent = "*";
-            $("select_column_object").nextElementSibling.textContent = "*";
+            document.getElementById("label_values").nextElementSibling.textContent = "*";
+            document.getElementById("span").nextElementSibling.textContent = "*";
+            document.getElementById("select_column_object").nextElementSibling.textContent = "*";
 
 
 
@@ -1208,10 +1837,20 @@
             })
             .then(response => response.json())
             .then(data => {
-                if (radioSelect.value != 'object') {
-                    const table = document.getElementById('data-header-table');
-                    table.innerHTML = data['data_header_table'];
-                }
+                const table = document.getElementById('data-header-table');
+                table.innerHTML = data['data_header_table'];
+                
+                // Set the select elements to their default options
+                document.getElementById("label_values").selectedIndex = 0;
+                // Reset the Chosen multi-select
+                $("#select_features").val([]).trigger("chosen:updated");
+                document.getElementById("select_column_object").selectedIndex = 0;
+                
+                // Show the success message
+                document.getElementById("submitDataHeader").textContent = "Submit successfully!";
+                setTimeout(function() {
+                    document.getElementById("submitDataHeader").textContent = "";
+                }, 2500); // 5000 milliseconds = 5 seconds
             })
             .catch(error => {
                 // Handle any error that occurred during the fetch
@@ -1224,6 +1863,14 @@
         function addLabel() {
             const labelValue = document.getElementById('defined-label').value; // Get the value of the input
 
+            if (labelValue == "" || labelValue == null || labelValue == " ") {
+                document.getElementById("addLabel").textContent = "This field is required!";
+                setTimeout(function() {
+                    document.getElementById("addLabel").textContent = "";
+                }, 2000); // 5000 milliseconds = 5 seconds
+                return;
+            }
+
             // Send the value to the server with fetch API
             fetch('/add-self-defined-label', {
                 method: 'POST',
@@ -1242,8 +1889,13 @@
                     optionElement.textContent = label_value;
                     selectElement1.appendChild(optionElement);  // Append to selectElement1
                 });
-                // Handle response data from the server
-                console.log(data);
+
+                // Show the success message
+                document.getElementById("addLabel").textContent = "Add successfully!";
+                setTimeout(function() {
+                    document.getElementById("addLabel").textContent = "";
+                }, 2500); // 5000 milliseconds = 5 seconds
+                
             })
             .catch(error => {
                 // Handle any error that occurred during the fetch
@@ -1362,6 +2014,16 @@
 
         // Function to handle the click on a dropped item
         function handleDroppedItemClick(itemName) {
+            // Change the color of the selected item
+            document.querySelectorAll('.list-group-item-action').forEach(item => {
+                if (item.textContent === itemName) {
+                    item.style.backgroundColor = '#5ea9e2';
+                } else {
+                    item.style.backgroundColor = 'white';
+                }
+            });
+            document.getElementById('select_label_values').innerHTML = '';
+
             // Send a POST request to Flask backend with the item name
             fetch('/get-table-data', {
                 method: 'POST',
@@ -1380,7 +2042,7 @@
                 selectElement0.innerHTML = '';
                 const optionElement0 = document.createElement('option');
                 optionElement0.value = '';
-                optionElement0.textContent = 'Column select...';
+                optionElement0.textContent = 'Select column...';
                 selectElement0.appendChild(optionElement0);
                 // Add the table columns as options
                 data.table_columns.forEach(column => {
@@ -1391,18 +2053,18 @@
                 });
 
                 // Assign data.table_columns to the select element
-                const selectElement = document.getElementById('select_column');
-                selectElement.innerHTML = '';
+                const selectColumn = document.getElementById('select_column'); 
+                selectColumn.innerHTML = '';
                 const optionElement = document.createElement('option');
                 optionElement.value = '';
-                optionElement.textContent = 'Column select...';
-                selectElement.appendChild(optionElement);
+                optionElement.textContent = 'Select column...';
+                selectColumn.appendChild(optionElement);
                 // Add the table columns as options
                 data.table_columns.forEach(column => {
                     const optionElement = document.createElement('option');
                     optionElement.value = column;
                     optionElement.textContent = column;
-                    selectElement.appendChild(optionElement);
+                    selectColumn.appendChild(optionElement);
                 });
                 
                 // Assign data.table_columns to the multi-select element
@@ -1419,8 +2081,6 @@
 
                 // Trigger Chosen to update its view
                 $(".chosen-select").trigger("chosen:updated");
-
-                // toggleTerminal(); // Show the terminal
             })
             .catch(error => console.error('Error:', error));
         }
@@ -1495,6 +2155,7 @@
             }
         }
 
+
         document.getElementById('resetButton').addEventListener('click', function() {
             // event.preventDefault();  // Prevent the default form submission
             console.log('Reset button clicked');
@@ -1512,7 +2173,7 @@
                 for (let i = 0; i < data.tables.length; i++) {
                     var item1 = document.createElement('div');
                     item1.className = "list-group-item-action uk-card uk-card-default uk-card-body uk-card-small";
-                    item1.style = "height: 15px; padding-top: 5px;";
+                    item1.style = "height: 15px; padding-top: 5px; width: 230px;";
                     item1.textContent = data.tables[i];
                     var item2 = document.createElement('div');
                     item2.className = "uk-margin";
@@ -1569,6 +2230,9 @@
 
 
         document.addEventListener('DOMContentLoaded', function() {
+            if ('{{message}}') {
+                UIkit.notification('{{message}}', {status: 'success'});
+            }
             // Show the ERD canvas
             showErdCanvas("erdCanvas1", "zoomInBtn1", "zoomOutBtn1", '{{ image1 }}');
             showErdCanvas("erdCanvas2", "zoomInBtn2", "zoomOutBtn2", '{{ image2 }}');
@@ -1692,20 +2356,47 @@
 
         });
     
+        document.addEventListener('DOMContentLoaded', function() {
+            // Get the select elements
+            var labelColumn = document.getElementById('select_column');
+            var labelValuesSelect = document.getElementById('label_values');
+            var featureSelect = document.getElementById('select_features'); // Assume you have a select element with this ID for features
+       
+            // Listen for changes on the label select
+            labelValuesSelect.addEventListener('change', function() {
+                // Check if the selected option is from 'label column data'
+                var selectedOption = this.options[this.selectedIndex];
+                var isLabelColumnData = selectedOption.parentNode.id === 'select_label_values';
+
+                // Apply constraints to the feature select based on the above condition
+                if(isLabelColumnData) {
+                    const droppedItemsDiv = document.querySelector('#dropped_items'); // Get the outer div
+                    
+                    fetch('/constraint-feature-columns', {
+                        method: 'POST',
+                        body: JSON.stringify({ 'label_column': labelColumn.value, 'label': selectedOption.value}),
+                        headers: {
+                            'Content-Type': 'application/json'
+                        }
+                    })
+                    .then(response => response.json())
+                    .then(data => {
+                        if (data['feature_columns']) {
+                            // Update the feature select element
+                            featureSelect.innerHTML = ''; // Clear existing options
+                            data.feature_columns.forEach(column => {
+                                const optionElement = document.createElement('option');
+                                optionElement.value = column;
+                                optionElement.textContent = column;
+                                featureSelect.appendChild(optionElement);
+                            });
+                            // Trigger Chosen to update its view
+                            $(".chosen-select").trigger("chosen:updated");
+                        }
+                    })
+                } 
+            });
+        });
     </script>
 </body>
-</html>
-
-
-<!-- For the pop up windows, I used the following code: -->
-        <!-- <div id="dropped_items">
-            <span onclick="UIkit.modal('#my-modal').show()">Click me</span>
-        </div>
-
-        <div id="my-modal" uk-modal>
-            <div class="uk-modal-dialog uk-modal-body">
-                <h2 class="uk-modal-title">Terminal</h2>
-                <p>Here is the content of your "terminal".</p>
-                <button class="uk-modal-close" type="button">Close</button>
-            </div>
-        </div> -->
\ No newline at end of file
+</html>
\ No newline at end of file