Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
134 commits
Select commit Hold shift + click to select a range
3327c55
add demographic_merge_event table migration
D3V41 Mar 19, 2026
9d8acd1
add DemographicTableIndex data class for merge copy engine
D3V41 Mar 19, 2026
29eeac4
add DemographicMergeEvent entity and DAO
D3V41 Mar 19, 2026
e6b1c4b
add MergeOperationDao skeleton and copyDemographic method
D3V41 Mar 19, 2026
875be82
add CaseMgmtCpp, CaseMgmtNote, CaseMgmtNoteExt, CaseMgmtNoteLink, Cas…
D3V41 Mar 20, 2026
a04596a
add setId() to AppointmentArchive, BillingONCHeader1, BillingONCHeader2,
D3V41 Mar 20, 2026
03de661
rewrite DemographicMergeOperationDao with typed domain-grouped method…
D3V41 Mar 20, 2026
6c57ea2
implement DemographicMergeOperationDaoImpl with full patient data cop…
D3V41 Mar 20, 2026
325709b
remove DemographicTableIndex
D3V41 Mar 20, 2026
a00de0d
uncomment setId() in DemographicContact
D3V41 Mar 20, 2026
06fd29f
fix: correct consultationRequestExtArchive FK query and remap in copy…
D3V41 Mar 23, 2026
9cae459
fix: implement secondary-pass gap-fill logic in copyIdentityTables
D3V41 Mar 23, 2026
ac948c9
fix: map duplicate issues to existing target PK so note-issue junctio…
D3V41 Mar 23, 2026
511732f
fix: skip and warn instead of persisting stale requestId in copyConsu…
D3V41 Mar 23, 2026
ac8507c
fix: copy erefer_attachment_data child rows in copyEreferGroup
D3V41 Mar 23, 2026
ce22242
fix: remap casemgmt_note_link appointment tableId after note copy
D3V41 Mar 23, 2026
a557282
refactor: replace JDBC with Hibernate new-object pattern for erefer_a…
D3V41 Mar 23, 2026
5348ef9
refactor: convert ctl_document copy from JDBC to Hibernate new-object…
D3V41 Mar 23, 2026
a2f630e
refactor: convert billing_on_transaction ch1Id remap from JDBC to JPQ…
D3V41 Mar 23, 2026
f9c0819
refactor: convert casemgmt_note_link tableId remap from JDBC to JPQL …
D3V41 Mar 23, 2026
6b85bab
feat: add demographic merge manager and MERGED patient status
D3V41 Mar 25, 2026
84ee7e1
feat: add DemographicMergeAction — Struts2 action for merge/unmerge
D3V41 Mar 25, 2026
c4ddced
feat: add JSPs and wire search through DemographicManager
D3V41 Mar 25, 2026
dbe4569
feat: wire - Struts mapping, nav links, and i18n for new merge workflow
D3V41 Mar 25, 2026
1651ca7
refactor: move demographic merge models to commn/model package
D3V41 Mar 26, 2026
80d3ef4
Replace one-insert-per-row loop with jdbcTemplate.batchUpdate() in c…
D3V41 Mar 26, 2026
10c36eb
replace O(n²) appointment-link remap with O(appointments) bulk UPDATE
D3V41 Mar 26, 2026
8278c79
refactor: replace magic number 11 with CaseManagementNoteLink.APPOINT…
D3V41 Mar 26, 2026
383bfef
refactor: replace "MERGE"/"UNMERGE" string literals with EventType enum
D3V41 Mar 26, 2026
2a63e31
fix: guard against NPE in DemographicMergeEvent.getSecondaryDemograph…
D3V41 Mar 26, 2026
286159c
refactor: remove dead limit1/limit2 pagination from DemographicMergeA…
D3V41 Mar 26, 2026
0f7355a
refactor: remove plan-phase labels (Part 1/2/T4x) from comments
D3V41 Mar 26, 2026
e950b90
refactor: collapse multi-line logger calls, query declarations, and m…
D3V41 Mar 26, 2026
121eac2
refactor: remove alignment padding and add braces to merge action rou…
D3V41 Mar 26, 2026
c10e76d
feat: extract copyAllergies() from copyClinicalDirectRecords to retur…
D3V41 Mar 26, 2026
ea5b0f6
feat: return drug PK map from copyDrugsGroup() for note-link tableId …
D3V41 Mar 26, 2026
b4479b8
feat: return eform PK map from copyEformGroup() for note-link tableId…
D3V41 Mar 26, 2026
e705558
feat: return email PK map from copyEmailGroup() for note-link tableId…
D3V41 Mar 26, 2026
37b5a55
feat: return prevention PK map from copyPreventionsGroup() for note-l…
D3V41 Mar 26, 2026
cbae220
feat: return tickler PK map from copyTicklerGroup() for note-link tab…
D3V41 Mar 26, 2026
ba43a8c
feat: add remapNoteLinkTableIds helper and remap all copied entity ty…
D3V41 Mar 26, 2026
061b7b6
feat: wire note-link tableId remap through DemographicMergeManagerImpl
D3V41 Mar 26, 2026
657b817
Minor changes
D3V41 Mar 26, 2026
555289d
fix: set @Column length=500 on DemographicMergeEvent.secondaryDemogra…
D3V41 Mar 26, 2026
7fd8c93
fix: add explicit isEmpty guard in copyFormONAREnhancedGroup
D3V41 Mar 26, 2026
fb4296b
fix: validate merged record C status before restoring A and secondari…
D3V41 Mar 26, 2026
e1c485d
fix: allow empty-keyword search and fix pagination in DemographicMerg…
D3V41 Mar 26, 2026
90a3aca
feat: collapse merge workflow to single page with old-style UX and Bo…
D3V41 Mar 26, 2026
d7e6ee5
chore: remove second-step merge page and clean up routing
D3V41 Mar 26, 2026
504b98c
logs
D3V41 Mar 27, 2026
ca164d2
fix: correct form_boolean_value column name field_value -> value in m…
D3V41 Mar 27, 2026
fccb65c
fix: clear billingItems collection before persisting BillingONCHeader…
D3V41 Mar 27, 2026
d1be743
fix: clear cascade collections before persist in copyEreferGroup to p…
D3V41 Mar 27, 2026
b9df682
fix: replace lazy EReferAttachment collection with new ArrayList befo…
D3V41 Mar 27, 2026
82a8352
fix: use getReference() to re-attach ProfessionalSpecialist after det…
D3V41 Mar 27, 2026
1b32fe2
fix: pre-detach ProfessionalSpecialist before archive copy loop to pr…
D3V41 Mar 27, 2026
bdfe4da
fix: use find() + cache instead of getReference() for ProfessionalSpe…
D3V41 Mar 27, 2026
d253716
fix: batch-detach archive rows upfront to prevent cascade PERSIST_ON_…
D3V41 Mar 27, 2026
1552b77
fix: skip duplicate CtlDocument entries when copying secondary source
D3V41 Mar 27, 2026
7927e7b
fix: split demographic status update into separate transaction to fix…
D3V41 Mar 27, 2026
263e70d
chore: add elapsed-time logging to all demographic merge copy operations
D3V41 Mar 27, 2026
4fe0652
feat: show spinner overlay while merge/unmerge operation is in progress
D3V41 Mar 27, 2026
536efc0
feat: return merged demographic ID from merge() and show success moda…
D3V41 Mar 27, 2026
d344fe8
refactor: replace JS alert/confirm dialogs with Bootstrap 5 modals in…
D3V41 Mar 27, 2026
1e79dff
fix: add correct unmerge search methods querying demographic_merge_ev…
D3V41 Mar 28, 2026
5d12cd7
feat: load merge event and source demographics in Action for unmerge …
D3V41 Mar 28, 2026
33f530d
feat: fix unmerge search query and add collapsible merge-history acco…
D3V41 Mar 28, 2026
f7c8883
fix: change native SQL alias from "d" to "de" in findActiveMergedDemo…
D3V41 Mar 28, 2026
54486f4
chore: remove link underline
D3V41 Mar 28, 2026
56a5208
fix: replace MERGED status with IN (inactive) for post-merge source r…
D3V41 Mar 28, 2026
2ba09ff
perf: Fix - replace MeasurementsDeleted row-by-row copy with HQL bulk…
D3V41 Mar 28, 2026
0b68d99
perf: Fix - replace DemographicExtArchive row-by-row copy with HQL bu…
D3V41 Mar 28, 2026
911df43
perf: Fix - replace AppointmentArchive row-by-row copy with HQL bulk …
D3V41 Mar 28, 2026
10f21be
perf: Fix - replace MeasurementsExt child copy with per-parent HQL bu…
D3V41 Mar 28, 2026
f7c9b3e
perf: Fix - replace EFormValue child copy with per-parent HQL bulk IN…
D3V41 Mar 28, 2026
8924685
perf: Fix - replace PreventionExt child copy with per-parent HQL bulk…
D3V41 Mar 28, 2026
7375a84
perf: Fix - replace ConsultationRequestExt child copy with per-parent…
D3V41 Mar 28, 2026
c976966
perf: Fix - replace ConsultationRequestExtArchive child copy with per…
D3V41 Mar 29, 2026
cf16e15
perf: Fix - replace BillingONCHeader2 and BillingONItem child copies …
D3V41 Mar 29, 2026
e280fa0
perf: Fix - replace DrugReason child copy with per-parent HQL bulk IN…
D3V41 Mar 29, 2026
7d980df
perf: Fix - replace TicklerLink child copy with per-parent HQL bulk I…
D3V41 Mar 29, 2026
941c686
perf: Fix - replace EmailAttachment child copy with native bulk INSER…
D3V41 Mar 29, 2026
9dbc97b
perf: Fix - bulk HQL INSERT for CaseMgmtNoteExt and CaseMgmtNoteLink …
D3V41 Mar 29, 2026
47b526c
perf: Fix - native INSERT-SELECT for EReferAttachmentData child rows
D3V41 Mar 29, 2026
d2e79d2
refactor: remove now-unused copyChildRows helper
D3V41 Mar 29, 2026
7d420df
perf: Fix - periodic entityManager.clear() in copyEntityRows to cap L…
D3V41 Mar 29, 2026
26fc3cd
perf: Fix - set JDBC fetchSize(1000) on copyEntityRows SELECT query
D3V41 Mar 29, 2026
606117b
perf: Fix - bulk CASE WHEN UPDATE in remapNoteLinkTableIds
D3V41 Mar 29, 2026
15a520e
perf: Fix - entityManager.clear() at start of every major group method
D3V41 Mar 29, 2026
9c7f7bc
perf: Fix bulk HQL INSERT for casemgmt_issue_notes junction rows
D3V41 Mar 29, 2026
31dfb78
fix: cast oldIds to List<Integer> in remapNoteLinkTableIds to match C…
D3V41 Mar 29, 2026
4b203e3
fix: cast oldNoteIds to List<Integer> in copyIssueNotesGroup to match…
D3V41 Mar 29, 2026
0820af5
feat: copy consultdocs rows in copyConsultationsGroup
D3V41 Mar 30, 2026
fcf7458
ui: improve demographicMergeRecord.jsp modal and table UX
D3V41 Mar 30, 2026
b25a0c8
fix: temp workaround for null 'deleted' column breaking demographic m…
D3V41 Mar 30, 2026
74c36c3
chore: Add new Patient Status column
D3V41 Mar 30, 2026
58dc3d1
chore: minor ui change
D3V41 Mar 30, 2026
15a55e1
chore: Update the code comments
D3V41 Mar 31, 2026
be1565e
refactor: reorder DemographicMergeOperationDaoImpl methods to match m…
D3V41 Mar 31, 2026
20399b6
fix: copy tickler_comments rows in copyTicklerGroup during demographi…
D3V41 Mar 31, 2026
2967b0f
chore: Add above-method comments to DemographicMergeOperationDaoImpl
D3V41 Apr 1, 2026
fda7e42
chore: minor ui change
D3V41 Apr 1, 2026
67a8801
Fix Hibernate EAGER-load bug in copyTicklerGroup: clear the comments …
D3V41 Apr 6, 2026
ec3863c
test: add DemographicMergeOperationDao integration tests and fix tick…
D3V41 Apr 6, 2026
d121ab8
feat: extend demographic_merged table for new merge feature
D3V41 Apr 10, 2026
07e5b6a
refactor: rename DemographicMergeEvent → DemographicMerge, point at d…
D3V41 Apr 10, 2026
5c8b216
refactor: delete old DemographicMerged entity and DAO
D3V41 Apr 10, 2026
b2dee75
refactor: delete all old demographic merge legacy code
D3V41 Apr 10, 2026
b34216e
refactor: remove old DemographicMergedDao wiring from DemographicManager
D3V41 Apr 10, 2026
539be06
refactor: update DemographicMergeManager to use DemographicMerge (ren…
D3V41 Apr 13, 2026
656ac19
refactor: update DemographicMergeAction import to use DemographicMerge
D3V41 Apr 13, 2026
4d9815c
refactor: remove old MergeRecords struts action and legacy admin.jsp …
D3V41 Apr 13, 2026
e41f8d5
chore: remove legacy admin.admin.mergeRec key from all properties files
D3V41 Apr 13, 2026
cd79e62
refactor: replace demographic_merged schema with merge-event model ac…
D3V41 Apr 14, 2026
7fc1f53
refactor: remove legacy merge model from all layers
D3V41 Apr 14, 2026
bce11e0
chore: update demographicMergeRecord.jsp for new merge model and fix …
D3V41 Apr 14, 2026
b90a2f3
feat: add REST endpoints for demographic merge/unmerge operations
D3V41 Apr 15, 2026
f3f681d
fix: add privilege checks to all merge manager methods and fix audit …
D3V41 Apr 16, 2026
beeb520
fix: map eventType in DemographicMergedConverter.getAsDomainObject
D3V41 Apr 16, 2026
5dbe499
fix: update DemographicServiceTest to match new merge API
D3V41 Apr 16, 2026
6b08c48
fix: update test classes to compile against new demographic merge API
D3V41 Apr 16, 2026
4cafc3d
fix: address security and data integrity issues in demographic merge …
D3V41 Apr 16, 2026
4605b1f
refactor: use new demographic_merged_event table instead of altering …
D3V41 Apr 22, 2026
f8f27d5
fix: guard merged-target records from re-merge and apply OWASP encodi…
D3V41 Apr 22, 2026
512fa0f
fix: exclude active merge sources from empty search and show merge in…
D3V41 Apr 23, 2026
79e0638
fix: exclude merge source records from all demographic search results
D3V41 Apr 23, 2026
2e129aa
fix: consolidate demographic merge into single atomic transaction
D3V41 May 20, 2026
ad93f63
fix: prevent lab routing failure for merged patients in HIN-match que…
D3V41 May 20, 2026
0c5694e
fix: prevent cross-patient PHI leakage in lab chart after unmerge
D3V41 May 20, 2026
410cbd1
fix: throw SecurityException instead of RuntimeException in Demograph…
D3V41 May 20, 2026
8813333
fix: scope tableExists() check to current catalog in DemographicMerge…
D3V41 May 20, 2026
0998c14
fix: correct column names in formBCAR2020Text INSERT in copyFormBCAR2…
D3V41 May 20, 2026
35314e1
fix: copy form_boolean_value rows for formONAREnhancedRecord in merge
D3V41 May 20, 2026
d1cf127
fix: parameterize HIN-match queries and use try-with-resources for JD…
D3V41 May 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions database/mysql/oscarinit.sql
Original file line number Diff line number Diff line change
Expand Up @@ -8247,16 +8247,16 @@ CREATE TABLE IF NOT EXISTS IssueGroupIssues (issueGroupId int not null, issue_id
--
-- Table structure for table `demographic_merged`
--
CREATE TABLE IF NOT EXISTS demographic_merged(
id INT(10) NOT NULL PRIMARY KEY AUTO_INCREMENT,
demographic_no INT(10) NOT NULL,
merged_to INT(10) NOT NULL,
deleted INT(1) NOT NULL DEFAULT 0,
`lastUpdateUser` varchar(6) default NULL,
`lastUpdateDate` date default NULL,
INDEX `dem_merged` (demographic_no, merged_to, deleted),
INDEX `dem_merged_dem` (demographic_no, deleted),
INDEX `dem_merged_merge` (merged_to, deleted)
CREATE TABLE IF NOT EXISTS demographic_merged (
id INT(10) NOT NULL PRIMARY KEY AUTO_INCREMENT,
primary_demographic_no INT(10) NULL DEFAULT NULL,
secondary_demographic_no VARCHAR(500) NULL DEFAULT NULL,
merged_demographic_no INT(10) NULL DEFAULT NULL,
event_type VARCHAR(20) NULL DEFAULT NULL,
provider_no VARCHAR(6) NULL DEFAULT NULL,
event_date DATETIME NULL DEFAULT NULL,
INDEX idx_dm_merged_demo_no (merged_demographic_no),
INDEX idx_dm_event_type (event_type)
);

--
Expand Down
20 changes: 15 additions & 5 deletions database/mysql/oscarinit_2025.sql
Original file line number Diff line number Diff line change
Expand Up @@ -772,15 +772,25 @@ ALTER TABLE `demographicArchive`
MODIFY COLUMN `myOscarUserName` VARCHAR(255);

--
-- Alter table structure for table `demographic_merged`, added constraints
-- Create demographic_merged_event for the new merge/unmerge audit event model.
-- The legacy demographic_merged table is left untouched so that a rollback to the
-- old merge code continues to work without any schema remediation.
--

ALTER TABLE `demographic_merged`
ADD CONSTRAINT `FKqev6qw9c8jc2f3w40p524h5xd`
FOREIGN KEY (`merged_to`) REFERENCES `demographic` (`demographic_no`);
CREATE TABLE IF NOT EXISTS `demographic_merged_event` (
`id` INT(10) NOT NULL PRIMARY KEY AUTO_INCREMENT,
`primary_demographic_no` INT(10) NULL DEFAULT NULL,
`secondary_demographic_no` VARCHAR(500) NULL DEFAULT NULL,
`merged_demographic_no` INT(10) NULL DEFAULT NULL,
`event_type` VARCHAR(20) NULL DEFAULT NULL,
`provider_no` VARCHAR(6) NULL DEFAULT NULL,
`event_date` DATETIME NULL DEFAULT NULL,
INDEX `idx_dme_merged_demo_no` (`merged_demographic_no`),
INDEX `idx_dme_event_type` (`event_type`)
);

--
-- Alter table structure for table `demographic_merged`, modified column sequence
-- Alter table structure for table `fax_config`
--

ALTER TABLE `fax_config`
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
-- Create a new table demographic_merged_event to record merge/unmerge audit events.
-- The existing demographic_merged table is left untouched so that a rollback to the
-- old merge code continues to work without any schema remediation.
CREATE TABLE IF NOT EXISTS demographic_merged_event (
id INT(10) NOT NULL PRIMARY KEY AUTO_INCREMENT,
primary_demographic_no INT(10) NULL DEFAULT NULL,
secondary_demographic_no VARCHAR(500) NULL DEFAULT NULL,
merged_demographic_no INT(10) NULL DEFAULT NULL,
event_type VARCHAR(20) NULL DEFAULT NULL,
provider_no VARCHAR(6) NULL DEFAULT NULL,
event_date DATETIME NULL DEFAULT NULL,
INDEX idx_dme_merged_demo_no (merged_demographic_no),
INDEX idx_dme_event_type (event_type)
);
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,10 @@ public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public Integer getCh1Id() {
return ch1Id;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,11 @@

import org.apache.tools.ant.util.DateUtils;
import org.hibernate.transform.ResultTransformer;
import ca.openosp.openo.commn.dao.DemographicDao;
import ca.openosp.openo.commn.model.Demographic;
import ca.openosp.openo.webserv.rest.to.model.DemographicSearchResult;

import ca.openosp.openo.demographic.data.DemographicMerged;

public class DemographicSearchResultTransformer implements ResultTransformer {

private DemographicDao demographicDao;
private SimpleDateFormat sdf = new SimpleDateFormat(DateUtils.ISO8601_DATE_PATTERN);
private DemographicMerged dm = new DemographicMerged();

public DemographicSearchResultTransformer() {
}
Expand All @@ -64,33 +58,6 @@ public Object transformTuple(Object[] tuple, String[] aliases) {
String providerLastName = (String) tuple[12];
String providerFirstName = (String) tuple[13];
String hin = (String) tuple[14];
Integer mergedTo = (Integer) tuple[15];

//more about this @ SF Bug #3575
if (mergedTo != null) {
//find and replace with the HEAD record info
Integer headDemographicNo = dm.getHead(demographicNo);
Demographic d = demographicDao.getDemographicById(headDemographicNo);

if (d != null) {
demographicNo = d.getDemographicNo();
lastName = d.getLastName();
firstName = d.getFirstName();
chartNo = d.getChartNo();
sex = d.getSex();
providerNo = d.getProviderNo();
rosterStatus = d.getRosterStatus();
patientStatus = d.getPatientStatus();
phone = d.getPhone();
year = d.getYearOfBirth();
month = d.getMonthOfBirth();
day = d.getDateOfBirth();
hin = d.getHin();
providerLastName = (d.getProvider() != null) ? d.getProvider().getLastName() : "";
providerFirstName = (d.getProvider() != null) ? d.getProvider().getFirstName() : "";
mergedTo = null;
}
}

Date dob = null;
try {
Expand All @@ -112,13 +79,4 @@ public List transformList(List collection) {
return collection;
}

public DemographicDao getDemographicDao() {
return demographicDao;
}

public void setDemographicDao(DemographicDao demographicDao) {
this.demographicDao = demographicDao;
}


}

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

55 changes: 53 additions & 2 deletions src/main/java/ca/openosp/openo/commn/dao/DemographicDao.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@
*/
public interface DemographicDao {

public List<Integer> getMergedDemographics(Integer demographicNo);

public Demographic getDemographic(String demographic_no);

public List getDemographics();
Expand Down Expand Up @@ -282,6 +280,59 @@ public List<Demographic> searchDemographicByExtKeyAndValueLikeAndStatus(Demograp
public List<Demographic> searchMergedDemographicByAddress(String addressStr, int limit, int offset,
String providerNo, boolean outOfDomain);

/**
* Finds active merged demographics (C records created by the merge engine) whose
* last name matches the given search string. Only records that appear in
* {@code demographic_merged_event} with {@code event_type = 'MERGE'} and have
* {@code patient_status = 'AC'} are returned.
*
* @param searchStr String last name prefix, or "last,first" for combined search
* @param limit int maximum number of results to return
* @param offset int pagination offset
* @return List&lt;Demographic&gt; matched active merged demographics
*/
public List<Demographic> findActiveMergedDemographicByName(String searchStr, int limit, int offset);

/**
* Finds active merged demographics (C records) by date of birth.
*
* @param dobStr String date of birth in yyyy-MM-dd format
* @param limit int maximum number of results
* @param offset int pagination offset
* @return List&lt;Demographic&gt; matched active merged demographics
*/
public List<Demographic> findActiveMergedDemographicByDOB(String dobStr, int limit, int offset);

/**
* Finds active merged demographics (C records) by phone number.
*
* @param phoneStr String phone number substring to match
* @param limit int maximum number of results
* @param offset int pagination offset
* @return List&lt;Demographic&gt; matched active merged demographics
*/
public List<Demographic> findActiveMergedDemographicByPhone(String phoneStr, int limit, int offset);

/**
* Finds active merged demographics (C records) by health insurance number.
*
* @param hinStr String HIN prefix to match
* @param limit int maximum number of results
* @param offset int pagination offset
* @return List&lt;Demographic&gt; matched active merged demographics
*/
public List<Demographic> findActiveMergedDemographicByHIN(String hinStr, int limit, int offset);

/**
* Finds active merged demographics (C records) by address.
*
* @param addressStr String address prefix to match
* @param limit int maximum number of results
* @param offset int pagination offset
* @return List&lt;Demographic&gt; matched active merged demographics
*/
public List<Demographic> findActiveMergedDemographicByAddress(String addressStr, int limit, int offset);

public List<Demographic> findDemographicByChartNo(String chartNoStr, int limit, int offset, String providerNo,
boolean outOfDomain);

Expand Down
Loading