cordova-plugin-crosswire-sword 0.2.11 → 0.2.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/RELEASENOTES.md +11 -0
- package/libs/android/arm64-v8a/libsword.so +0 -0
- package/libs/android/armeabi-v7a/libsword.so +0 -0
- package/libs/android/x86/libsword.so +0 -0
- package/libs/android/x86_64/libsword.so +0 -0
- package/libs/ios/SWORD.xcframework/ios-arm64/libSWORD.a +2 -2
- package/libs/ios/SWORD.xcframework/ios-arm64-simulator/libSWORD.a +2 -2
- package/package.json +4 -1
- package/plugin.xml +1 -1
- package/src/android/SWMgr.java +23 -0
- package/src/android/SWORD.java +48 -0
- package/src/ios/SWORD.swift +57 -4
- package/src/ios/flatapi.h +16 -0
- package/www/SWORD.js +18 -2
package/RELEASENOTES.md
CHANGED
|
@@ -20,6 +20,17 @@
|
|
|
20
20
|
-->
|
|
21
21
|
# Release Notes
|
|
22
22
|
|
|
23
|
+
### 0.2.13 (Oct 6, 2026)
|
|
24
|
+
* BibleSync: every call into the library is made under one lock, on both platforms. Its receive loop runs on a thread of the plugin's while the page's sends and questions arrive on Cordova's, and the library keeps no lock of its own; a verse sent as a packet was being received could be refused as "still receiving", or worse
|
|
25
|
+
* iOS: the engine header the Swift bridge compiles against is refreshed whenever the package is built
|
|
26
|
+
|
|
27
|
+
### 0.2.12 (Oct 5, 2026)
|
|
28
|
+
* BibleSync on a network that loses packets, as Wi-Fi does: each verse carries a sequence number and is sent three times, which a receiver shows once; a peer is kept through half an hour of silence, not one minute; a newcomer is answered at once, twice; a beacon every 10 seconds (biblesync 2.2.0 with pull requests 19 and 20)
|
|
29
|
+
* startBibleSync takes options { repeatCount, repeatDelayMS, peerLifetimeS }; the defaults are 2, 500 and 1800
|
|
30
|
+
* getBibleSyncStatus says whether a running session is still alive on the same network interface (off, alive, disabled, moved), so an app resumed from sleep or the background restarts BibleSync only when it must
|
|
31
|
+
* The page hears BibleSync's interface, its peers and its errors on both platforms ({ cmd: info | peer | error }); a beacon that cannot be sent while the phone sleeps no longer ends the session
|
|
32
|
+
* iOS: BibleSync is offered (features.bibleSync), the app carrying Apple's multicast entitlement; every received message had been dropped
|
|
33
|
+
|
|
23
34
|
### 0.2.11 (Oct 1, 2026)
|
|
24
35
|
* Study data (bookmarks and, in time, notes) in a folder of the user's choosing, named sword-studydata so several devices and SWORD apps can share it (doc/bookmarks-format.md in Bishop): a picked folder holding bookmarks/, or itself named sword-studydata, is used as it is, otherwise sword-studydata/ is made inside it
|
|
25
36
|
* iOS: the study-data folder may be in iCloud Drive or any app's folder; where a provider grants files but no folder (Google Drive), the bookmark files are picked in place (SWMgr_chooseDataFiles) or Bishop's own are saved there and opened once (SWMgr_exportDataFiles); a provider's file is rewritten in place so it keeps its identity
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
[diffend] Oversized file quarantined before diffing.
|
|
2
2
|
name: package/libs/ios/SWORD.xcframework/ios-arm64/libSWORD.a
|
|
3
|
-
size:
|
|
4
|
-
sha256:
|
|
3
|
+
size: 37343432 bytes
|
|
4
|
+
sha256: b0a320876d2a063731888664d4a30338e9fa1044e90c3474c343da2e94d7af50
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
[diffend] Oversized file quarantined before diffing.
|
|
2
2
|
name: package/libs/ios/SWORD.xcframework/ios-arm64-simulator/libSWORD.a
|
|
3
|
-
size:
|
|
4
|
-
sha256:
|
|
3
|
+
size: 37386424 bytes
|
|
4
|
+
sha256: da32b199627dac42856912d00b71a959e402f45eaf4b72777a30507765fcd26d
|
package/package.json
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cordova-plugin-crosswire-sword",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.13",
|
|
4
4
|
"description": "The SWORD Project Plugin",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"prepack": "cp ../../../include/defs.h ../../../include/flatapi.h src/ios/"
|
|
7
|
+
},
|
|
5
8
|
"files": [
|
|
6
9
|
"plugin.xml",
|
|
7
10
|
"libs",
|
package/plugin.xml
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
xmlns:rim="http://www.blackberry.com/ns/widgets"
|
|
5
5
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
6
6
|
id="cordova-plugin-crosswire-sword"
|
|
7
|
-
version="0.2.
|
|
7
|
+
version="0.2.13">
|
|
8
8
|
<name>cordova-plugin-crosswire-sword</name>
|
|
9
9
|
<description>The SWORD Project Plugin</description>
|
|
10
10
|
<license>GNU 2.0</license>
|
package/src/android/SWMgr.java
CHANGED
|
@@ -164,9 +164,32 @@ public class SWMgr {
|
|
|
164
164
|
public static interface BibleSyncListener {
|
|
165
165
|
public void navReceived(String osisRef);
|
|
166
166
|
public void chatReceived(String user, String message);
|
|
167
|
+
/** the interface address BibleSync is on */
|
|
168
|
+
public void infoReceived(String iface);
|
|
169
|
+
/**
|
|
170
|
+
* @param state 'A' a peer announced itself, 'S' it is a speaker we now listen to, 'D' a speaker went quiet
|
|
171
|
+
* @param who user @ address ('D': the uuid)
|
|
172
|
+
* @param what app version; device; uuid ('D': empty)
|
|
173
|
+
*/
|
|
174
|
+
public void peerReceived(char state, String who, String what);
|
|
175
|
+
/** the library could not send, or stopped itself: what it said, and its detail */
|
|
176
|
+
public void errorReceived(String message, String detail);
|
|
167
177
|
}
|
|
168
178
|
public native void startBibleSync(String appName, String userName, String passphrase, BibleSyncListener listener);
|
|
179
|
+
/**
|
|
180
|
+
* For the next startBibleSync; a negative value leaves that one as it is.
|
|
181
|
+
* @param repeatCount how many more times each verse is sent (nobody resends multicast); default 2
|
|
182
|
+
* @param repeatDelayMS at least this long between those; default 500
|
|
183
|
+
* @param peerLifetimeS a peer not heard from for this many seconds is given up; default 1800
|
|
184
|
+
*/
|
|
185
|
+
public native void setBibleSyncOptions(int repeatCount, int repeatDelayMS, int peerLifetimeS);
|
|
169
186
|
public native void stopBibleSync();
|
|
187
|
+
/**
|
|
188
|
+
* @return "off" (not running), "alive <address>",
|
|
189
|
+
* "disabled <address>" (the library shut itself down) or
|
|
190
|
+
* "moved <address> <address now>" (the network changed under it)
|
|
191
|
+
*/
|
|
192
|
+
public native String getBibleSyncStatus();
|
|
170
193
|
public native void sendBibleSyncMessage(String osisRef);
|
|
171
194
|
}
|
|
172
195
|
|
package/src/android/SWORD.java
CHANGED
|
@@ -552,6 +552,8 @@ Log.d(TAG, "SWModule_getRenderChapter");
|
|
|
552
552
|
final String appName = args.getString(0);
|
|
553
553
|
final String userName = args.getString(1);
|
|
554
554
|
final String passphrase = args.getString(2);
|
|
555
|
+
// repeatCount, repeatDelayMS, peerLifetimeS: -1 (or absent) keeps the default
|
|
556
|
+
mgr.setBibleSyncOptions(args.optInt(3, -1), args.optInt(4, -1), args.optInt(5, -1));
|
|
555
557
|
|
|
556
558
|
if (multicastLock == null) {
|
|
557
559
|
WifiManager wifi = (WifiManager) cordova.getActivity().getApplicationContext().getSystemService(Context.WIFI_SERVICE);
|
|
@@ -586,6 +588,42 @@ Log.d(TAG, "SWModule_getRenderChapter");
|
|
|
586
588
|
}
|
|
587
589
|
catch (Exception e) { e.printStackTrace(); }
|
|
588
590
|
}
|
|
591
|
+
public void infoReceived(String iface) {
|
|
592
|
+
try {
|
|
593
|
+
JSONObject m = new JSONObject();
|
|
594
|
+
m.put("cmd", "info");
|
|
595
|
+
m.put("interface", iface);
|
|
596
|
+
PluginResult result = new PluginResult(PluginResult.Status.OK, m);
|
|
597
|
+
result.setKeepCallback(true);
|
|
598
|
+
bibleSyncListener.sendPluginResult(result);
|
|
599
|
+
}
|
|
600
|
+
catch (Exception e) { e.printStackTrace(); }
|
|
601
|
+
}
|
|
602
|
+
public void peerReceived(char state, String who, String what) {
|
|
603
|
+
try {
|
|
604
|
+
JSONObject m = new JSONObject();
|
|
605
|
+
m.put("cmd", "peer");
|
|
606
|
+
m.put("state", state == 'A' ? "announce" : (state == 'S' ? "speaker" : "gone"));
|
|
607
|
+
m.put("who", who);
|
|
608
|
+
m.put("what", what);
|
|
609
|
+
PluginResult result = new PluginResult(PluginResult.Status.OK, m);
|
|
610
|
+
result.setKeepCallback(true);
|
|
611
|
+
bibleSyncListener.sendPluginResult(result);
|
|
612
|
+
}
|
|
613
|
+
catch (Exception e) { e.printStackTrace(); }
|
|
614
|
+
}
|
|
615
|
+
public void errorReceived(String message, String detail) {
|
|
616
|
+
try {
|
|
617
|
+
JSONObject m = new JSONObject();
|
|
618
|
+
m.put("cmd", "error");
|
|
619
|
+
m.put("message", message);
|
|
620
|
+
m.put("detail", detail);
|
|
621
|
+
PluginResult result = new PluginResult(PluginResult.Status.OK, m);
|
|
622
|
+
result.setKeepCallback(true);
|
|
623
|
+
bibleSyncListener.sendPluginResult(result);
|
|
624
|
+
}
|
|
625
|
+
catch (Exception e) { e.printStackTrace(); }
|
|
626
|
+
}
|
|
589
627
|
});
|
|
590
628
|
}
|
|
591
629
|
});
|
|
@@ -599,6 +637,16 @@ Log.d(TAG, "SWModule_getRenderChapter");
|
|
|
599
637
|
if (multicastLock != null && multicastLock.isHeld()) multicastLock.release();
|
|
600
638
|
callbackContext.success();
|
|
601
639
|
}
|
|
640
|
+
else if (action.equals("SWMgr_getBibleSyncStatus")) {
|
|
641
|
+
// "alive 10.0.0.5" -> { state, alive, interface, current }
|
|
642
|
+
String[] s = mgr.getBibleSyncStatus().split(" ");
|
|
643
|
+
JSONObject r = new JSONObject();
|
|
644
|
+
r.put("state", s[0]);
|
|
645
|
+
r.put("alive", s[0].equals("alive"));
|
|
646
|
+
r.put("interface", s.length > 1 ? s[1] : "");
|
|
647
|
+
r.put("current", s.length > 2 ? s[2] : (s.length > 1 ? s[1] : ""));
|
|
648
|
+
callbackContext.success(r);
|
|
649
|
+
}
|
|
602
650
|
else if (action.equals("SWMgr_setJavascript")) {
|
|
603
651
|
boolean val = args.getBoolean(0);
|
|
604
652
|
mgr.setJavascript(val);
|
package/src/ios/SWORD.swift
CHANGED
|
@@ -98,8 +98,8 @@ var mySWORDPlugin:SWORD? = nil
|
|
|
98
98
|
"version": libswordVersion,
|
|
99
99
|
// what the page may offer on iOS (SWORD.features)
|
|
100
100
|
// bibleSync: multicast needs com.apple.developer.networking.multicast,
|
|
101
|
-
//
|
|
102
|
-
"features": [ "dataStorage": true, "dataFiles": true, "sharedStorage": false, "bibleSync":
|
|
101
|
+
// which Apple granted the account on 2026-10-01 and Bishop's config.xml carries
|
|
102
|
+
"features": [ "dataStorage": true, "dataFiles": true, "sharedStorage": false, "bibleSync": true ]
|
|
103
103
|
] as [AnyHashable : Any]
|
|
104
104
|
self.commandDelegate!.send(CDVPluginResult(status: CDVCommandStatus_OK, messageAs: info), callbackId: command.callbackId)
|
|
105
105
|
}
|
|
@@ -1210,6 +1210,12 @@ debugPrint("initMgr, mgr: " + String(describing: mgr))
|
|
|
1210
1210
|
let appName = command.arguments[0] as? String ?? ""
|
|
1211
1211
|
let userName = command.arguments[1] as? String ?? ""
|
|
1212
1212
|
let passphrase = command.arguments[2] as? String ?? ""
|
|
1213
|
+
// optional: how often a verse is repeated and how far apart, and how long
|
|
1214
|
+
// a silent peer is kept (-1 or absent = the library's default)
|
|
1215
|
+
let opt = { (i: Int) -> Int32 in
|
|
1216
|
+
command.arguments.count > i ? Int32(truncatingIfNeeded: (command.arguments[i] as? Int) ?? -1) : -1
|
|
1217
|
+
}
|
|
1218
|
+
org_crosswire_sword_SWMgr_setBibleSyncOptions(mgr, opt(3), opt(4), opt(5))
|
|
1213
1219
|
bibleSyncCallbackID = command.callbackId
|
|
1214
1220
|
DispatchQueue.global().async {
|
|
1215
1221
|
mySWORDPlugin = self
|
|
@@ -1217,8 +1223,10 @@ debugPrint("initMgr, mgr: " + String(describing: mgr))
|
|
|
1217
1223
|
// a nav message carries no second string (flatapi passes 0)
|
|
1218
1224
|
let response1 = str1 == nil ? "" : String(cString: str1!)
|
|
1219
1225
|
let response2 = str2 == nil ? "" : String(cString: str2!)
|
|
1226
|
+
// (CChar("N") is Int8's failable parse of the string "N", i.e. nil,
|
|
1227
|
+
// which equals no command: every message was dropped that way)
|
|
1220
1228
|
if (mySWORDPlugin != nil && mySWORDPlugin!.bibleSyncCallbackID != "") {
|
|
1221
|
-
if (cmd == CChar("N")) {
|
|
1229
|
+
if (cmd == CChar(UInt8(ascii: "N"))) {
|
|
1222
1230
|
var retVal = [String:Any]()
|
|
1223
1231
|
retVal["cmd"] = "nav";
|
|
1224
1232
|
retVal["osisRef"] = response1;
|
|
@@ -1226,7 +1234,7 @@ debugPrint("initMgr, mgr: " + String(describing: mgr))
|
|
|
1226
1234
|
result.setKeepCallbackAs(true)
|
|
1227
1235
|
mySWORDPlugin!.commandDelegate!.send(result, callbackId: mySWORDPlugin!.bibleSyncCallbackID)
|
|
1228
1236
|
}
|
|
1229
|
-
else if (cmd == CChar("C") ) {
|
|
1237
|
+
else if (cmd == CChar(UInt8(ascii: "C")) ) {
|
|
1230
1238
|
var retVal = [String:Any]()
|
|
1231
1239
|
retVal["cmd"] = "chat";
|
|
1232
1240
|
retVal["user"] = response1;
|
|
@@ -1235,6 +1243,36 @@ debugPrint("initMgr, mgr: " + String(describing: mgr))
|
|
|
1235
1243
|
result.setKeepCallbackAs(true)
|
|
1236
1244
|
mySWORDPlugin!.commandDelegate!.send(result, callbackId: mySWORDPlugin!.bibleSyncCallbackID)
|
|
1237
1245
|
}
|
|
1246
|
+
else if (cmd == CChar(UInt8(ascii: "I"))) {
|
|
1247
|
+
// the interface address BibleSync is on
|
|
1248
|
+
var retVal = [String:Any]()
|
|
1249
|
+
retVal["cmd"] = "info";
|
|
1250
|
+
retVal["interface"] = response1;
|
|
1251
|
+
let result = CDVPluginResult(status: CDVCommandStatus_OK, messageAs: retVal)
|
|
1252
|
+
result.setKeepCallbackAs(true)
|
|
1253
|
+
mySWORDPlugin!.commandDelegate!.send(result, callbackId: mySWORDPlugin!.bibleSyncCallbackID)
|
|
1254
|
+
}
|
|
1255
|
+
else if (cmd == CChar(UInt8(ascii: "A")) || cmd == CChar(UInt8(ascii: "S")) || cmd == CChar(UInt8(ascii: "D"))) {
|
|
1256
|
+
// a peer announced itself, became a speaker we listen to, or went quiet
|
|
1257
|
+
var retVal = [String:Any]()
|
|
1258
|
+
retVal["cmd"] = "peer";
|
|
1259
|
+
retVal["state"] = cmd == CChar(UInt8(ascii: "A")) ? "announce" : (cmd == CChar(UInt8(ascii: "S")) ? "speaker" : "gone");
|
|
1260
|
+
retVal["who"] = response1; // user @ address ('gone': the uuid)
|
|
1261
|
+
retVal["what"] = response2; // app version; device; uuid
|
|
1262
|
+
let result = CDVPluginResult(status: CDVCommandStatus_OK, messageAs: retVal)
|
|
1263
|
+
result.setKeepCallbackAs(true)
|
|
1264
|
+
mySWORDPlugin!.commandDelegate!.send(result, callbackId: mySWORDPlugin!.bibleSyncCallbackID)
|
|
1265
|
+
}
|
|
1266
|
+
else if (cmd == CChar(UInt8(ascii: "E"))) {
|
|
1267
|
+
// the library stopped itself: what it said, and its detail
|
|
1268
|
+
var retVal = [String:Any]()
|
|
1269
|
+
retVal["cmd"] = "error";
|
|
1270
|
+
retVal["message"] = response1;
|
|
1271
|
+
retVal["detail"] = response2;
|
|
1272
|
+
let result = CDVPluginResult(status: CDVCommandStatus_OK, messageAs: retVal)
|
|
1273
|
+
result.setKeepCallbackAs(true)
|
|
1274
|
+
mySWORDPlugin!.commandDelegate!.send(result, callbackId: mySWORDPlugin!.bibleSyncCallbackID)
|
|
1275
|
+
}
|
|
1238
1276
|
}
|
|
1239
1277
|
});
|
|
1240
1278
|
|
|
@@ -1250,6 +1288,21 @@ debugPrint("initMgr, mgr: " + String(describing: mgr))
|
|
|
1250
1288
|
self.commandDelegate!.send(result, callbackId: command.callbackId)
|
|
1251
1289
|
}
|
|
1252
1290
|
|
|
1291
|
+
// "off" | "alive <addr>" | "disabled <addr>" | "moved <addr> <addr now>", as
|
|
1292
|
+
// { state, alive, interface, current }: the page asks before restarting on resume
|
|
1293
|
+
@objc(SWMgr_getBibleSyncStatus:)
|
|
1294
|
+
func SWMgr_getBibleSyncStatus(command: CDVInvokedUrlCommand) {
|
|
1295
|
+
initMgr()
|
|
1296
|
+
let status = String(cString: org_crosswire_sword_SWMgr_getBibleSyncStatus(mgr))
|
|
1297
|
+
let parts = status.split(separator: " ").map { String($0) }
|
|
1298
|
+
var retVal = [String:Any]()
|
|
1299
|
+
retVal["state"] = parts.count > 0 ? parts[0] : "off"
|
|
1300
|
+
retVal["alive"] = parts.count > 0 && parts[0] == "alive"
|
|
1301
|
+
retVal["interface"] = parts.count > 1 ? parts[1] : ""
|
|
1302
|
+
retVal["current"] = parts.count > 2 ? parts[2] : (parts.count > 1 ? parts[1] : "")
|
|
1303
|
+
self.commandDelegate!.send(CDVPluginResult(status: CDVCommandStatus_OK, messageAs: retVal), callbackId: command.callbackId)
|
|
1304
|
+
}
|
|
1305
|
+
|
|
1253
1306
|
@objc(SWMgr_stopBibleSync:)
|
|
1254
1307
|
func SWMgr_stopBibleSync(command: CDVInvokedUrlCommand) {
|
|
1255
1308
|
initMgr()
|
package/src/ios/flatapi.h
CHANGED
|
@@ -611,6 +611,22 @@ void SWDLLEXPORT org_crosswire_sword_SWMgr_startBibleSync
|
|
|
611
611
|
void SWDLLEXPORT org_crosswire_sword_SWMgr_stopBibleSync
|
|
612
612
|
(SWHANDLE hMgr);
|
|
613
613
|
|
|
614
|
+
/*
|
|
615
|
+
* Class: org_crosswire_android_sword_SWMgr
|
|
616
|
+
* Method: setBibleSyncOptions
|
|
617
|
+
* Signature: (III)V
|
|
618
|
+
*/
|
|
619
|
+
void SWDLLEXPORT org_crosswire_sword_SWMgr_setBibleSyncOptions
|
|
620
|
+
(SWHANDLE hMgr, int repeatCount, int repeatDelayMS, int peerLifetimeS);
|
|
621
|
+
|
|
622
|
+
/*
|
|
623
|
+
* Class: org_crosswire_android_sword_SWMgr
|
|
624
|
+
* Method: getBibleSyncStatus
|
|
625
|
+
* Signature: ()Ljava/lang/String;
|
|
626
|
+
*/
|
|
627
|
+
const char * SWDLLEXPORT org_crosswire_sword_SWMgr_getBibleSyncStatus
|
|
628
|
+
(SWHANDLE hMgr);
|
|
629
|
+
|
|
614
630
|
/*
|
|
615
631
|
* Class: org_crosswire_android_sword_SWMgr
|
|
616
632
|
* Method: sendBibleSyncMessage
|
package/www/SWORD.js
CHANGED
|
@@ -381,10 +381,16 @@ SWMgr.prototype.addExtraConfig = function(confBlob, callback) {
|
|
|
381
381
|
return retVal;
|
|
382
382
|
}
|
|
383
383
|
|
|
384
|
-
|
|
384
|
+
// options (all optional; the plugin's defaults otherwise):
|
|
385
|
+
// repeatCount how many more times each verse is sent, since nobody resends multicast (2)
|
|
386
|
+
// repeatDelayMS at least this long between those (500)
|
|
387
|
+
// peerLifetimeS a peer not heard from for this many seconds is given up (1800)
|
|
388
|
+
SWMgr.prototype.startBibleSync = function(appName, userName, passphrase, callback, options) {
|
|
389
|
+
var o = options || {};
|
|
390
|
+
var opt = function(v) { return (typeof v === 'number' && v >= 0) ? Math.floor(v) : -1; };
|
|
385
391
|
exec(callback,
|
|
386
392
|
function(err) { utils.alert('[ERROR] problem: ' + err); },
|
|
387
|
-
"SWORD", "SWMgr_startBibleSync", [appName, userName, passphrase]
|
|
393
|
+
"SWORD", "SWMgr_startBibleSync", [appName, userName, passphrase, opt(o.repeatCount), opt(o.repeatDelayMS), opt(o.peerLifetimeS)]
|
|
388
394
|
);
|
|
389
395
|
}
|
|
390
396
|
|
|
@@ -395,6 +401,16 @@ SWMgr.prototype.stopBibleSync = function() {
|
|
|
395
401
|
);
|
|
396
402
|
}
|
|
397
403
|
|
|
404
|
+
// whether a running BibleSync session is still worth keeping (after sleep or
|
|
405
|
+
// the background): { state: 'off'|'alive'|'disabled'|'moved', alive, interface,
|
|
406
|
+
// current }; null where the platform cannot say
|
|
407
|
+
SWMgr.prototype.getBibleSyncStatus = function(callback) {
|
|
408
|
+
exec(callback,
|
|
409
|
+
function(err) { callback(null); },
|
|
410
|
+
"SWORD", "SWMgr_getBibleSyncStatus", []
|
|
411
|
+
);
|
|
412
|
+
}
|
|
413
|
+
|
|
398
414
|
SWMgr.prototype.sendBibleSyncMessage = function(osisRef, callback) {
|
|
399
415
|
exec(callback?callback:function() {},
|
|
400
416
|
function(err) { utils.alert('[ERROR] problem: ' + err); },
|