Abhishek Banthia
9 years ago
13 changed files with 10325 additions and 24 deletions
@ -0,0 +1,214 @@ |
|||||||
|
digraph G { |
||||||
|
node [shape=box]; |
||||||
|
"CLSAttributes" -> {}; |
||||||
|
"eisl" -> {}; |
||||||
|
"SecCustomTransform" -> {}; |
||||||
|
"StatusItemView" -> {}; |
||||||
|
"CLTimezoneCellView" -> "CommonStrings"; |
||||||
|
"cssmkrapi" -> {}; |
||||||
|
"cssmapi" -> {}; |
||||||
|
"DTTimePeriodCollection" -> "DTTimePeriodGroup"; |
||||||
|
"DTTimePeriodCollection" -> "DTError"; |
||||||
|
"SecTrust" -> {}; |
||||||
|
"ColoredButton" -> {}; |
||||||
|
"PFSubclassing" -> {}; |
||||||
|
"cssm" -> {}; |
||||||
|
"x509defs" -> {}; |
||||||
|
"SCPreferences" -> {}; |
||||||
|
"SecKey" -> {}; |
||||||
|
"cssmcli" -> {}; |
||||||
|
"SecAsn1Templates" -> {}; |
||||||
|
"SecAccessControl" -> {}; |
||||||
|
"PanelController" -> "StatusItemView"; |
||||||
|
"PanelController" -> "DateTools"; |
||||||
|
"PanelController" -> "MenubarController"; |
||||||
|
"PanelController" -> "CommonStrings"; |
||||||
|
"PanelController" -> "CLOneWindowController"; |
||||||
|
"PanelController" -> "Reachability"; |
||||||
|
"AuthorizationDB" -> {}; |
||||||
|
"main" -> "AppDelegate"; |
||||||
|
"PFFile" -> {}; |
||||||
|
"BFTask" -> {}; |
||||||
|
"SecKeychainSearch" -> {}; |
||||||
|
"SecDecodeTransform" -> "SecEncodeTransform"; |
||||||
|
"PFQuery" -> {}; |
||||||
|
"SecBase" -> {}; |
||||||
|
"Reachability" -> {}; |
||||||
|
"BFCancellationTokenRegistration" -> {}; |
||||||
|
"BFExecutor" -> {}; |
||||||
|
"SCDynamicStoreKey" -> {}; |
||||||
|
"PFAnonymousUtils" -> {}; |
||||||
|
"SCSchemaDefinitions" -> {}; |
||||||
|
"ApplicationDelegate" -> "MenubarController"; |
||||||
|
"ApplicationDelegate" -> "PanelController"; |
||||||
|
"ApplicationDelegate" -> "CommonStrings"; |
||||||
|
"ApplicationDelegate" -> "iRate"; |
||||||
|
"ApplicationDelegate" -> "iVersion"; |
||||||
|
"DTConstants" -> "DTError"; |
||||||
|
"SCDynamicStoreCopySpecific" -> {}; |
||||||
|
"SecImportExport" -> {}; |
||||||
|
"SecPolicySearch" -> {}; |
||||||
|
"PFConfig" -> {}; |
||||||
|
"certextensions" -> {}; |
||||||
|
"Parse" -> {}; |
||||||
|
"BFDefines" -> {}; |
||||||
|
"cssmtpi" -> {}; |
||||||
|
"SecItem" -> {}; |
||||||
|
"SCNetworkConnection" -> {}; |
||||||
|
"SecEncryptTransform" -> "SecTransform"; |
||||||
|
"CMSDecoder" -> {}; |
||||||
|
"SecStaticCode" -> {}; |
||||||
|
"Fabric" -> "FABAttributes"; |
||||||
|
"DateToolsViewController" -> "Colours"; |
||||||
|
"mds" -> {}; |
||||||
|
"SecRandom" -> {}; |
||||||
|
"cssmconfig" -> {}; |
||||||
|
"SecTrustedApplication" -> {}; |
||||||
|
"Bolts" -> {}; |
||||||
|
"CMSEncoder" -> {}; |
||||||
|
"CommonStrings" -> {}; |
||||||
|
"cssmerr" -> {}; |
||||||
|
"Answers" -> "ANSCompatibility"; |
||||||
|
"emmspi" -> {}; |
||||||
|
"MenubarController" -> "StatusItemView"; |
||||||
|
"SecTransform" -> {}; |
||||||
|
"PFACL" -> {}; |
||||||
|
"cssmspi" -> {}; |
||||||
|
"CLTimezoneData" -> {}; |
||||||
|
"SecureDownload" -> {}; |
||||||
|
"CLSLogging" -> "CLSAttributes"; |
||||||
|
"oidscrl" -> {}; |
||||||
|
"cssmdli" -> {}; |
||||||
|
"SecCodeHost" -> {}; |
||||||
|
"Security" -> {}; |
||||||
|
"PFSession" -> {}; |
||||||
|
"PFPush" -> {}; |
||||||
|
"SecAsn1Coder" -> {}; |
||||||
|
"cssmaci" -> {}; |
||||||
|
"SecureTransport" -> {}; |
||||||
|
"AppDelegate" -> "Colours"; |
||||||
|
"AppDelegate" -> "DateToolsViewController"; |
||||||
|
"AppDelegate" -> "TimePeriodsViewController"; |
||||||
|
"AppDelegate" -> "ExampleNavigationController"; |
||||||
|
"SecPolicy" -> {}; |
||||||
|
"CLOneWindowController" -> "CLAboutUsViewController"; |
||||||
|
"CLOneWindowController" -> "CLPreferencesViewController"; |
||||||
|
"CLOneWindowController" -> "CLAppearanceViewController"; |
||||||
|
"Crashlytics" -> "CLSAttributes"; |
||||||
|
"Crashlytics" -> "CLSReport"; |
||||||
|
"Crashlytics" -> "CLSLogging"; |
||||||
|
"Crashlytics" -> "CLSStackFrame"; |
||||||
|
"Crashlytics" -> "Answers"; |
||||||
|
"CodeSigning" -> {}; |
||||||
|
"SecKeychain" -> {}; |
||||||
|
"SecIdentitySearch" -> {}; |
||||||
|
"PFGeoPoint" -> {}; |
||||||
|
"TimePeriodsViewController" -> "DTTimePeriod"; |
||||||
|
"cssmapple" -> {}; |
||||||
|
"PFConstants" -> {}; |
||||||
|
"SystemConfiguration" -> {}; |
||||||
|
"oidscert" -> {}; |
||||||
|
"iRate" -> "CommonStrings"; |
||||||
|
"iRate" -> "PanelController"; |
||||||
|
"SecSignVerifyTransform" -> "SecTransform"; |
||||||
|
"Authorization" -> {}; |
||||||
|
"BFCancellationToken" -> {}; |
||||||
|
"emmtype" -> {}; |
||||||
|
"CLAboutUsViewController" -> "CLAppFeedbackWindowController"; |
||||||
|
"oids" -> {}; |
||||||
|
"PFInstallation" -> {}; |
||||||
|
"SecDigestTransform" -> "SecTransform"; |
||||||
|
"cssmkrspi" -> {}; |
||||||
|
"CLPreferencesViewController" -> "ApplicationDelegate"; |
||||||
|
"CLPreferencesViewController" -> "Reachability"; |
||||||
|
"CLPreferencesViewController" -> "PanelController"; |
||||||
|
"CLPreferencesViewController" -> "CommonStrings"; |
||||||
|
"CLPreferencesViewController" -> "Panel"; |
||||||
|
"SecReadTransform" -> {}; |
||||||
|
"DTTimePeriodChain" -> "DTTimePeriodGroup"; |
||||||
|
"DTTimePeriodChain" -> "DTError"; |
||||||
|
"CLSReport" -> "CLSAttributes"; |
||||||
|
"BFCancellationTokenSource" -> {}; |
||||||
|
"oidsalg" -> {}; |
||||||
|
"FABAttributes" -> {}; |
||||||
|
"SCPreferencesPath" -> {}; |
||||||
|
"SecACL" -> {}; |
||||||
|
"SecCertificateOIDs" -> {}; |
||||||
|
"CSCommon" -> {}; |
||||||
|
"ExampleNavigationController" -> "Colours"; |
||||||
|
"CLAppFeedbackWindowController" -> "CommonStrings"; |
||||||
|
"CLAppFeedbackWindowController" -> "CLOneWindowController"; |
||||||
|
"SCPreferencesSetSpecific" -> {}; |
||||||
|
"SecEncodeTransform" -> "SecTransform"; |
||||||
|
"PFObject" -> {}; |
||||||
|
"PFRelation" -> {}; |
||||||
|
"CLSStackFrame" -> "CLSAttributes"; |
||||||
|
"SecAsn1Types" -> {}; |
||||||
|
"mds_schema" -> {}; |
||||||
|
"SecCertificate" -> {}; |
||||||
|
"CipherSuite" -> {}; |
||||||
|
"PFUser" -> {}; |
||||||
|
"DateTools" -> "DTTimePeriod"; |
||||||
|
"DateTools" -> "DTTimePeriodGroup"; |
||||||
|
"DateTools" -> "DTConstants"; |
||||||
|
"DateTools" -> "DTTimePeriodCollection"; |
||||||
|
"DateTools" -> "DTTimePeriodChain"; |
||||||
|
"DateTools" -> "DTError"; |
||||||
|
"PFUserAuthenticationDelegate" -> {}; |
||||||
|
"SCNetworkReachability" -> {}; |
||||||
|
"CLRatingCellView" -> "CLAppFeedbackWindowController"; |
||||||
|
"CLRatingCellView" -> "iRate"; |
||||||
|
"SCNetwork" -> {}; |
||||||
|
"Colours" -> "TargetConditionals"; |
||||||
|
"AuthorizationPlugin" -> {}; |
||||||
|
"AuthorizationTags" -> {}; |
||||||
|
"SecAccess" -> {}; |
||||||
|
"BackgroundView" -> "ApplicationDelegate"; |
||||||
|
"BackgroundView" -> "CommonStrings"; |
||||||
|
"oidsattr" -> {}; |
||||||
|
"DTTimePeriod" -> {}; |
||||||
|
"cssmcspi" -> {}; |
||||||
|
"CLAppearanceViewController" -> "ApplicationDelegate"; |
||||||
|
"CLAppearanceViewController" -> "PanelController"; |
||||||
|
"CLAppearanceViewController" -> "CommonStrings"; |
||||||
|
"oidsbase" -> {}; |
||||||
|
"cssmtype" -> {}; |
||||||
|
"DHCPClientPreferences" -> {}; |
||||||
|
"PFAnalytics" -> {}; |
||||||
|
"SecTrustSettings" -> {}; |
||||||
|
"SecCode" -> {}; |
||||||
|
"AuthSession" -> {}; |
||||||
|
"Panel" -> {}; |
||||||
|
"SCDynamicStore" -> {}; |
||||||
|
"SecTask" -> {}; |
||||||
|
"SecRequirement" -> {}; |
||||||
|
"SecIdentity" -> {}; |
||||||
|
"iVersion" -> {}; |
||||||
|
"PFRole" -> {}; |
||||||
|
"DTTimePeriodGroup" -> "DTTimePeriod"; |
||||||
|
"ANSCompatibility" -> {}; |
||||||
|
"SCNetworkConfiguration" -> {}; |
||||||
|
"SCDynamicStoreCopyDHCPInfo" -> {}; |
||||||
|
"DTError" -> {}; |
||||||
|
"CaptiveNetwork" -> {}; |
||||||
|
"BFTaskCompletionSource" -> {}; |
||||||
|
"SecTransformReadTransform" -> {}; |
||||||
|
"BoltsVersion" -> {}; |
||||||
|
"CLCustomSliderCell" -> "CommonStrings"; |
||||||
|
"PFCloud" -> {}; |
||||||
|
"SecKeychainItem" -> {}; |
||||||
|
|
||||||
|
"DateToolsExample-Prefix" [color=red]; |
||||||
|
"Clocker-Prefix" [color=red]; |
||||||
|
|
||||||
|
edge [color=blue, dir=both]; |
||||||
|
"PanelController" -> "BackgroundView"; |
||||||
|
"CLTimezoneCellView" -> "PanelController"; |
||||||
|
"PanelController" -> "CLRatingCellView"; |
||||||
|
"TargetConditionals" [color=gray, style=dashed, fontcolor=gray] |
||||||
|
|
||||||
|
edge [color=black]; |
||||||
|
node [shape=plaintext]; |
||||||
|
"Categories" [label="PFObject+Subclass\nNSDate+DateTools"]; |
||||||
|
} |
||||||
|
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@ -0,0 +1,26 @@ |
|||||||
|
Copyright (c) 2013, Michael Bostock |
||||||
|
All rights reserved. |
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without |
||||||
|
modification, are permitted provided that the following conditions are met: |
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this |
||||||
|
list of conditions and the following disclaimer. |
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, |
||||||
|
this list of conditions and the following disclaimer in the documentation |
||||||
|
and/or other materials provided with the distribution. |
||||||
|
|
||||||
|
* The name Michael Bostock may not be used to endorse or promote products |
||||||
|
derived from this software without specific prior written permission. |
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
||||||
|
DISCLAIMED. IN NO EVENT SHALL MICHAEL BOSTOCK BE LIABLE FOR ANY DIRECT, |
||||||
|
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
||||||
|
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
||||||
|
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
||||||
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
||||||
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
@ -0,0 +1,121 @@ |
|||||||
|
// ===================================================
|
||||||
|
// =============== PARSING ===========================
|
||||||
|
// ===================================================
|
||||||
|
// Input
|
||||||
|
// { links : [ {source: sourceName, dest : destName} * ] }
|
||||||
|
// Output:
|
||||||
|
!function () { |
||||||
|
var objcdv = { |
||||||
|
version: "0.0.1" |
||||||
|
}; |
||||||
|
objcdv.parse_dependencies_graph = function (dependencies, regexp_color_matchers) { |
||||||
|
|
||||||
|
var nodes = []; |
||||||
|
var links = []; |
||||||
|
|
||||||
|
var nodesSet = {}; |
||||||
|
var prefixes = {}; |
||||||
|
|
||||||
|
var node_index = 0; |
||||||
|
|
||||||
|
// Parse all dependencies
|
||||||
|
// In format
|
||||||
|
|
||||||
|
var input_links = dependencies.links; |
||||||
|
|
||||||
|
var updatePrefixesDistribution = function(name) { |
||||||
|
var prefix = name.substring(0, 2); |
||||||
|
if (!(prefix in prefixes)) { |
||||||
|
prefixes[prefix] = 1; |
||||||
|
} else { |
||||||
|
prefixes[prefix]++; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
for (var i = 0; i < input_links.length; i++) { |
||||||
|
var link = input_links[i]; |
||||||
|
|
||||||
|
var source_node = nodesSet[link.source]; |
||||||
|
if (source_node == null) { |
||||||
|
nodesSet[link.source] = source_node = { idx :node_index++, name: link.source, source: 1, dest: 0 } |
||||||
|
} |
||||||
|
source_node.source++; |
||||||
|
|
||||||
|
var dest_node = nodesSet[link.dest]; |
||||||
|
if (dest_node == null) { |
||||||
|
nodesSet[link.dest] = dest_node = { idx :node_index++, name: link.dest, source: 0, dest: 1 } |
||||||
|
} |
||||||
|
dest_node.dest++; |
||||||
|
|
||||||
|
|
||||||
|
// Grouping by prefixes
|
||||||
|
updatePrefixesDistribution(link.source); |
||||||
|
updatePrefixesDistribution(link.dest); |
||||||
|
|
||||||
|
// Remapping links objects
|
||||||
|
links.push({ |
||||||
|
|
||||||
|
// d3 js properties
|
||||||
|
source: source_node.idx, |
||||||
|
target: dest_node.idx, |
||||||
|
|
||||||
|
// Additional link information
|
||||||
|
sourceNode: source_node, |
||||||
|
targetNode: dest_node |
||||||
|
}); |
||||||
|
|
||||||
|
console.log("Pushing link : source=" + source_node.idx + ", target=" + dest_node.idx); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
// Sorting prefixes, based on theirs frequency
|
||||||
|
var prefixes_arr = []; |
||||||
|
for (var key in prefixes) { |
||||||
|
prefixes_arr.push({key: key, value: prefixes[key] }); |
||||||
|
} |
||||||
|
var sorted_prefixes = prefixes_arr.slice(0).sort(function (a, b) { |
||||||
|
return b.value - a.value; |
||||||
|
}); |
||||||
|
|
||||||
|
// If we dont' have regexp_color_matchers, we'll set them up, based on prefixes
|
||||||
|
var group_regexp_identifiers = regexp_color_matchers; |
||||||
|
if (group_regexp_identifiers == null) { |
||||||
|
group_regexp_identifiers = []; |
||||||
|
for (var i = 0; i < sorted_prefixes.length; i++) { |
||||||
|
group_regexp_identifiers.push("^" + sorted_prefixes[i].key+".*"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Setting up nodes groups, based on the group_regexp_identifiers
|
||||||
|
var idx = 0; |
||||||
|
for (var p in nodesSet) { |
||||||
|
|
||||||
|
node = nodesSet[p]; |
||||||
|
node.group = 0; |
||||||
|
node.weight = node.source; // Calculating node weignt, based on the amount of item it depends on
|
||||||
|
|
||||||
|
for (var regexp_index = 0; regexp_index < group_regexp_identifiers.length; regexp_index++) { |
||||||
|
var re = new RegExp(group_regexp_identifiers[regexp_index], ""); |
||||||
|
if (p.match(re)) { |
||||||
|
node.group = regexp_index + 1; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
nodes.push(node); |
||||||
|
console.log(" Pushing node : IDX=" + idx + ", name=" + p + ", groupId=" + node.group + ", source=" + node.source + ", dest=" + node.dest + ", weight=" + node.weight); |
||||||
|
idx++; |
||||||
|
} |
||||||
|
|
||||||
|
return { nodes : nodes, links: links }; |
||||||
|
} |
||||||
|
|
||||||
|
if (typeof define === "function" && define.amd) { |
||||||
|
define(objcdv); |
||||||
|
} else if (typeof module === "object" && module.exports) { |
||||||
|
module.exports = objcdv; |
||||||
|
} else { |
||||||
|
this.objcdv = objcdv; |
||||||
|
} |
||||||
|
}(); |
||||||
|
|
@ -0,0 +1,65 @@ |
|||||||
|
|
||||||
|
|
||||||
|
.node.filtered { |
||||||
|
fill-opacity:0.3; |
||||||
|
stroke-opacity:0.3; |
||||||
|
} |
||||||
|
|
||||||
|
text.filtered { |
||||||
|
fill-opacity:0; |
||||||
|
stroke-opacity:0; |
||||||
|
} |
||||||
|
|
||||||
|
.link.filtered { |
||||||
|
stroke: #ddd; |
||||||
|
fill-opacity:0.1; |
||||||
|
stroke-opacity:0.1; |
||||||
|
} |
||||||
|
|
||||||
|
.node { |
||||||
|
stroke: #000; |
||||||
|
stroke-width: 0.5px; |
||||||
|
} |
||||||
|
|
||||||
|
.link { |
||||||
|
stroke: #999; |
||||||
|
stroke-opacity: .6; |
||||||
|
fill: none; |
||||||
|
stroke-width: 1.5px; |
||||||
|
pointer-events: none; |
||||||
|
} |
||||||
|
|
||||||
|
.marker#default { |
||||||
|
stroke: #999; |
||||||
|
fill:#999; |
||||||
|
pointer-events: none; |
||||||
|
} |
||||||
|
|
||||||
|
.marker#dependency { |
||||||
|
stroke: #900; |
||||||
|
fill:#900; |
||||||
|
pointer-events: none; |
||||||
|
} |
||||||
|
|
||||||
|
.marker#dependants { |
||||||
|
stroke: #090; |
||||||
|
fill:#090; |
||||||
|
pointer-events: none; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
text { |
||||||
|
stroke: #000; |
||||||
|
stroke-width: 0.5px; |
||||||
|
text-anchor:middle; |
||||||
|
font: 10px sans-serif; |
||||||
|
font-weight: normal; |
||||||
|
font-style: normal; |
||||||
|
pointer-events: none; |
||||||
|
} |
||||||
|
|
||||||
|
form { |
||||||
|
position: absolute; |
||||||
|
right: 10px; |
||||||
|
top: 10px; |
||||||
|
} |
@ -0,0 +1,484 @@ |
|||||||
|
<!DOCTYPE html> |
||||||
|
<meta charset="utf-8"> |
||||||
|
<head> |
||||||
|
<link rel="stylesheet" type="text/css" href="dependency.css"> |
||||||
|
</head> |
||||||
|
<body> |
||||||
|
<script src="Scripts/d3.v3.js"></script> |
||||||
|
<script src="origin.js"></script> |
||||||
|
|
||||||
|
<!-- ================================================= --> |
||||||
|
<!-- ===========ACTUAL HTML ================ --> |
||||||
|
<!-- ================================================= --> |
||||||
|
|
||||||
|
<form id="form"> |
||||||
|
<label><input type="range" name="circle_size" min="1" max="50" value="15"/> Circle size</label><br> |
||||||
|
<label><input type="range" name="charge_multiplier" min="1" max="500" value="100"/> Charge multiplier</label><br> |
||||||
|
<label><input type="range" name="link_strength" min="0.1" max="100" value="7"/> Link strength</label><br> |
||||||
|
<label><input type="checkbox" name="show_texts_near_circles" checked="checked"/> Show names</label><br> |
||||||
|
<input id="search_input" placeholder="Type regexp to filter nodes" style="width:100%;"><br> |
||||||
|
|
||||||
|
</form> |
||||||
|
<div id="chart"> |
||||||
|
<!-- Here the SVG will be placed--> |
||||||
|
</div> |
||||||
|
|
||||||
|
<script src="Scripts/parse.js"></script> |
||||||
|
<script> |
||||||
|
|
||||||
|
// =================================================== |
||||||
|
// =============== CONFIGURABLE PARAMS ============== |
||||||
|
// =================================================== |
||||||
|
|
||||||
|
var default_link_distance = 10; |
||||||
|
|
||||||
|
// How far can we change default_link_distance? |
||||||
|
// 0 - I don't care |
||||||
|
// 0.5 - Change it as you want, but it's preferrable to have default_link_distance |
||||||
|
// 1 - One does not change default_link_distance |
||||||
|
var default_link_strength = 0.7; |
||||||
|
|
||||||
|
// Should I comment this? |
||||||
|
var default_circle_radius = 15; |
||||||
|
|
||||||
|
// you can set it to true, but this will not help to understanf what's going on |
||||||
|
var show_texts_near_circles = true; |
||||||
|
var default_max_texts_length = 100; |
||||||
|
|
||||||
|
// Should we use regexp-based grouping or not |
||||||
|
var use_regexp_color_grouping_matchers = false; |
||||||
|
|
||||||
|
var charge_multiplier = 200; |
||||||
|
|
||||||
|
// Each item thet matches specified regexps will be placed to correspondent group with unique color |
||||||
|
var regexp_color_matchers = [ |
||||||
|
"^NI", // Nimbus |
||||||
|
"^UI", // UIKit |
||||||
|
"^NS", // Foundation |
||||||
|
"^CA", // Core animations |
||||||
|
]; |
||||||
|
|
||||||
|
var dependecy_graph = objcdv.parse_dependencies_graph(dependencies, use_regexp_color_grouping_matchers ? regexp_color_matchers : null); |
||||||
|
|
||||||
|
var w = window, |
||||||
|
d = document, |
||||||
|
e = d.documentElement, |
||||||
|
g = d.getElementsByTagName('body')[0], |
||||||
|
x = w.innerWidth || e.clientWidth || g.clientWidth, |
||||||
|
y = w.innerHeight|| e.clientHeight|| g.clientHeight; |
||||||
|
|
||||||
|
// =================================================== |
||||||
|
// =============== http://d3js.org/ Magic =========== |
||||||
|
// =================================================== |
||||||
|
|
||||||
|
// https://github.com/mbostock/d3/wiki/Ordinal-Scales#categorical-colors |
||||||
|
var color = d3.scale.category10(); |
||||||
|
var selectedIdx = -1 |
||||||
|
var selectedType = "normal" |
||||||
|
var selectedobject = {} |
||||||
|
|
||||||
|
var container = d3.select("#chart").append("svg") |
||||||
|
.attr("width", x) |
||||||
|
.attr("height", y) |
||||||
|
|
||||||
|
// =================================================== |
||||||
|
// =============== ZOOM LOGIC ======================== |
||||||
|
// =================================================== |
||||||
|
|
||||||
|
container.append("rect") |
||||||
|
.attr("width", x) |
||||||
|
.attr("height", y) |
||||||
|
.style("fill", "none") |
||||||
|
.style("pointer-events", "all") |
||||||
|
.call(d3.behavior.zoom().on("zoom", redraw)) |
||||||
|
|
||||||
|
function redraw() { |
||||||
|
svg.attr("transform", "translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")"); |
||||||
|
} |
||||||
|
|
||||||
|
// =================================================== |
||||||
|
// =============== FORCE LAYOUT ====================== |
||||||
|
// =================================================== |
||||||
|
|
||||||
|
var force = d3.layout.force() |
||||||
|
.charge(function(d) { return d.filtered ? 0 : -d.weight * charge_multiplier}) |
||||||
|
.linkDistance(function(l) { return l.source.filtered || l.target.filtered ? 500 : radius(l.source) + radius(l.target) + default_link_distance}) |
||||||
|
.size([x, y]) |
||||||
|
.nodes(d3.values(dependecy_graph.nodes)) |
||||||
|
.links(dependecy_graph.links) |
||||||
|
.linkStrength(function(l) { return l.source.filtered || l.target.filtered ? 0 : default_link_strength}) |
||||||
|
.start(); |
||||||
|
|
||||||
|
var svg = container.append('g') |
||||||
|
|
||||||
|
// =================================================== |
||||||
|
// =============== MARKERS SETUP ================== |
||||||
|
// =================================================== |
||||||
|
|
||||||
|
svg.append("defs").selectAll("marker") |
||||||
|
.data(["default", "dependency", "dependants"]) |
||||||
|
.enter().append("marker") |
||||||
|
.attr("id", function(d) { return d; }) |
||||||
|
.attr("viewBox", "0 -5 10 10") |
||||||
|
.attr("refX", 10) |
||||||
|
.attr("refY", 0) |
||||||
|
.attr("markerWidth", 10) |
||||||
|
.attr("markerHeight", 10) |
||||||
|
.attr("orient", "auto") |
||||||
|
.attr("class", "marker") |
||||||
|
.append("path") |
||||||
|
.attr("d", "M0,-5L10,0L0,5"); |
||||||
|
|
||||||
|
|
||||||
|
// =================================================== |
||||||
|
// =============== LINKS SETUP ================== |
||||||
|
// =================================================== |
||||||
|
|
||||||
|
var link = svg.append("g").selectAll("path") |
||||||
|
.data(dependecy_graph.links) |
||||||
|
.enter().append("path") |
||||||
|
.attr("class", "link") |
||||||
|
.attr("marker-end", "url(#default)") |
||||||
|
.style("stroke-width", function(d) { return Math.sqrt(1); }) |
||||||
|
|
||||||
|
// =================================================== |
||||||
|
// =============== NODES SETUP ================== |
||||||
|
// =================================================== |
||||||
|
|
||||||
|
var node = svg.append("g").selectAll("circle.node") |
||||||
|
.data(dependecy_graph.nodes) |
||||||
|
.enter().append("circle") |
||||||
|
.attr("r", radius) |
||||||
|
.style("fill", function(d) { return color(d.group) }) |
||||||
|
.attr("class", "node") |
||||||
|
.attr("source", function(d) { return d.source}) |
||||||
|
.attr("dest", function(d) { return d.dest}) |
||||||
|
.call(force.drag) |
||||||
|
.on("click", select_node) |
||||||
|
.on("contextmenu", select_recursively_node) |
||||||
|
|
||||||
|
// =================================================== |
||||||
|
// =============== TEXT NODES SETUP ============= |
||||||
|
// =================================================== |
||||||
|
|
||||||
|
var text = svg.append("g").selectAll("text") |
||||||
|
.data(force.nodes()) |
||||||
|
.enter().append("text") |
||||||
|
.attr("visibility", "visible") |
||||||
|
.text(function(d) { return d.name.substring(0, default_max_texts_length) }); |
||||||
|
|
||||||
|
// =================================================== |
||||||
|
// =============== FORCE UPDATE ============= |
||||||
|
// =================================================== |
||||||
|
|
||||||
|
force.on("tick", function() { |
||||||
|
svg.selectAll(".node").attr("r", radius); |
||||||
|
link.attr("d", link_line); |
||||||
|
node.attr("transform", transform ); |
||||||
|
if (show_texts_near_circles) { |
||||||
|
text.attr("transform", transform); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
// =================================================== |
||||||
|
// =============== HELPER FUNCTIONS ============= |
||||||
|
// =================================================== |
||||||
|
function link_line(d) { |
||||||
|
var dx = d.target.x - d.source.x, |
||||||
|
dy = d.target.y - d.source.y, |
||||||
|
dr = Math.sqrt(dx * dx + dy * dy); |
||||||
|
|
||||||
|
var rsource = radius(d.sourceNode)/dr; |
||||||
|
var rdest = radius(d.targetNode)/dr; |
||||||
|
var startX = d.source.x + dx * rsource; |
||||||
|
var startY = d.source.y + dy * rsource; |
||||||
|
|
||||||
|
var endX = d.target.x - dx * rdest; |
||||||
|
var endY = d.target.y - dy * rdest; |
||||||
|
return "M" + startX+ "," + startY + "L" + endX+ "," + endY; |
||||||
|
} |
||||||
|
|
||||||
|
function transform(d) { |
||||||
|
return "translate(" + d.x + "," + d.y + ")"; |
||||||
|
} |
||||||
|
|
||||||
|
function radius(d) { |
||||||
|
return default_circle_radius + default_circle_radius * d.source / 10; |
||||||
|
} |
||||||
|
|
||||||
|
/* |
||||||
|
Window resize update |
||||||
|
*/ |
||||||
|
w.onresize = function(){ |
||||||
|
x = w.innerWidth || e.clientWidth || g.clientWidth ; |
||||||
|
y = w.innerHeight|| e.clientHeight|| g.clientHeight; |
||||||
|
|
||||||
|
container.attr("width", x ).attr("height", y); |
||||||
|
force.size([x, y]).start(); |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
// =================================================== |
||||||
|
// =============== SELECTING_NODE ============= |
||||||
|
// =================================================== |
||||||
|
|
||||||
|
function deselect_node(d) { |
||||||
|
delete d.fixed |
||||||
|
selectedIdx = -1 |
||||||
|
selectedobject = {}; |
||||||
|
svg.selectAll('circle, path, text') |
||||||
|
.classed('filtered', false) |
||||||
|
.each(function(node) { |
||||||
|
node.filtered = false |
||||||
|
}) |
||||||
|
.transition() |
||||||
|
|
||||||
|
svg.selectAll('.link') |
||||||
|
.attr("marker-end", "url(#default)") |
||||||
|
.classed('filtered', false) |
||||||
|
.transition() |
||||||
|
|
||||||
|
|
||||||
|
force.start(); |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
function select_node(d) { |
||||||
|
if (d3.event.defaultPrevented) return |
||||||
|
|
||||||
|
// Deselect if needed |
||||||
|
if (d.idx == selectedIdx && selectedType == "normal") { deselect_node(d); return } |
||||||
|
|
||||||
|
// Update selected object |
||||||
|
delete selectedobject.fixed |
||||||
|
selectedIdx = d.idx |
||||||
|
selectedobject = d |
||||||
|
selectedobject.fixed = true |
||||||
|
selectedType = "normal" |
||||||
|
|
||||||
|
// Figure out the neighboring node id's with brute strength because the graph is small |
||||||
|
var nodeNeighbors = |
||||||
|
dependecy_graph.links |
||||||
|
.filter(function(link) { |
||||||
|
return link.source.index === d.index || link.target.index === d.index;}) |
||||||
|
.map(function(link) { |
||||||
|
return link.source.index === d.index ? link.target.index : link.source.index; |
||||||
|
} |
||||||
|
); |
||||||
|
|
||||||
|
// Fade out all circles |
||||||
|
svg.selectAll('circle') |
||||||
|
.classed('filtered', true) |
||||||
|
.each(function(node){ |
||||||
|
node.filtered = true; |
||||||
|
node.neighbours = false; |
||||||
|
}).transition() |
||||||
|
|
||||||
|
|
||||||
|
svg.selectAll('text') |
||||||
|
.classed('filtered', true) |
||||||
|
.transition() |
||||||
|
|
||||||
|
|
||||||
|
svg.selectAll('.link'). |
||||||
|
transition() |
||||||
|
.attr("marker-end", "") |
||||||
|
|
||||||
|
|
||||||
|
// Higlight all circle and texts |
||||||
|
svg.selectAll('circle, text') |
||||||
|
.filter(function(node) { |
||||||
|
return nodeNeighbors.indexOf(node.index) > -1 || node.index == d.index; |
||||||
|
}) |
||||||
|
.classed('filtered', false) |
||||||
|
.each(function(node) { |
||||||
|
node.filtered = false; |
||||||
|
node.neighbours = true; |
||||||
|
}) |
||||||
|
.transition() |
||||||
|
|
||||||
|
// Higlight links |
||||||
|
svg.selectAll('.link') |
||||||
|
.filter(function(link) { |
||||||
|
return link.source.index === d.index || link.target.index == d.index |
||||||
|
}) |
||||||
|
.classed('filtered', false) |
||||||
|
.attr("marker-end", function(l) { return l.source.index === d.index ? "url(#dependency)" : "url(#dependants)"}) |
||||||
|
.transition() |
||||||
|
|
||||||
|
force.start(); |
||||||
|
} |
||||||
|
|
||||||
|
function select_recursively_node(d) { |
||||||
|
if (d3.event.defaultPrevented) return |
||||||
|
|
||||||
|
// Don't show context menu :) |
||||||
|
d3.event.preventDefault() |
||||||
|
|
||||||
|
// Deselect if needed |
||||||
|
if (d.idx == selectedIdx && selectedType == "recursive") { deselect_node(d); return } |
||||||
|
|
||||||
|
// Update selected object |
||||||
|
delete selectedobject.fixed |
||||||
|
selectedIdx = d.idx |
||||||
|
selectedobject = d |
||||||
|
selectedobject.fixed = true |
||||||
|
selectedType = "recursive" |
||||||
|
|
||||||
|
// Figure out the neighboring node id's with brute strength because the graph is small |
||||||
|
var neighbours = {} |
||||||
|
var nodeNeighbors = |
||||||
|
dependecy_graph.links |
||||||
|
.filter(function(link) { |
||||||
|
return link.source.index === d.index}) |
||||||
|
.map(function(link) { |
||||||
|
var idx = link.source.index === d.index ? link.target.index : link.source.index; |
||||||
|
if (link.source.index === d.index) { |
||||||
|
console.log("Step 0. Adding ",dependecy_graph.nodes[idx].name) |
||||||
|
neighbours[idx] = 1; |
||||||
|
} |
||||||
|
return idx; |
||||||
|
} |
||||||
|
); |
||||||
|
|
||||||
|
// Next part - neighbours of neigbours |
||||||
|
var currentsize = Object.keys(neighbours).length |
||||||
|
var nextSize = 0; |
||||||
|
var step = 1; |
||||||
|
while (nextSize != currentsize) { |
||||||
|
console.log("Current size " + currentsize + " Next size is " + nextSize) |
||||||
|
currentsize = nextSize |
||||||
|
dependecy_graph.links |
||||||
|
.filter(function(link) { |
||||||
|
return neighbours[link.source.index] != undefined}) |
||||||
|
.map(function(link) { |
||||||
|
var idx = link.target.index; |
||||||
|
console.log("Step "+step+". Adding ",dependecy_graph.nodes[idx].name + " From " + dependecy_graph.nodes[link.source.index].name ) |
||||||
|
|
||||||
|
neighbours[idx] = 1; |
||||||
|
return idx; |
||||||
|
} |
||||||
|
); |
||||||
|
nextSize = Object.keys(neighbours).length |
||||||
|
step = step + 1 |
||||||
|
} |
||||||
|
|
||||||
|
neighbours[d.index] = 1 |
||||||
|
nodeNeighbors = Object.keys(neighbours).map(function(neibour) { |
||||||
|
return parseInt(neibour); |
||||||
|
}) |
||||||
|
|
||||||
|
|
||||||
|
// Fade out all circles |
||||||
|
svg.selectAll('circle') |
||||||
|
.classed('filtered', true) |
||||||
|
.each(function(node){ |
||||||
|
node.filtered = true; |
||||||
|
node.neighbours = false; |
||||||
|
}).transition() |
||||||
|
|
||||||
|
|
||||||
|
svg.selectAll('text') |
||||||
|
.classed('filtered', true) |
||||||
|
.transition() |
||||||
|
|
||||||
|
|
||||||
|
svg.selectAll('.link'). |
||||||
|
transition() |
||||||
|
.attr("marker-end", "") |
||||||
|
|
||||||
|
|
||||||
|
// Higlight all circle and texts |
||||||
|
svg.selectAll('circle, text') |
||||||
|
.filter(function(node) { |
||||||
|
return nodeNeighbors.indexOf(node.index) > -1 || node.index == d.index; |
||||||
|
}) |
||||||
|
.classed('filtered', false) |
||||||
|
.each(function(node) { |
||||||
|
node.filtered = false; |
||||||
|
node.neighbours = true; |
||||||
|
}) |
||||||
|
.transition() |
||||||
|
|
||||||
|
// Higlight links |
||||||
|
svg.selectAll('.link') |
||||||
|
.filter(function(link) { |
||||||
|
return nodeNeighbors.indexOf(link.source.index) > -1 |
||||||
|
}) |
||||||
|
.classed('filtered', false) |
||||||
|
.attr("marker-end", function(l) { return l.source.index === d.index ? "url(#dependency)" : "url(#dependants)"}) |
||||||
|
.transition() |
||||||
|
|
||||||
|
force.start(); |
||||||
|
} |
||||||
|
|
||||||
|
</script> |
||||||
|
|
||||||
|
<script> |
||||||
|
// =================================================== |
||||||
|
// =============== INPUTS HANDLING ============== |
||||||
|
// =================================================== |
||||||
|
d3.selectAll("input").on("change", function change() { |
||||||
|
|
||||||
|
if (this.name == "circle_size") { |
||||||
|
default_circle_radius = parseInt(this.value); |
||||||
|
force.linkDistance(function(l) { return radius(l.source) + radius(l.target) + default_link_distance;}) |
||||||
|
force.start(); |
||||||
|
} |
||||||
|
|
||||||
|
if (this.name == "charge_multiplier") { |
||||||
|
charge_multiplier = parseInt(this.value); |
||||||
|
force.start(); |
||||||
|
} |
||||||
|
|
||||||
|
if (this.name == "link_strength") { |
||||||
|
default_link_strength = parseInt(this.value) / 10; |
||||||
|
force.linkStrength(default_link_strength); |
||||||
|
force.start(); |
||||||
|
} |
||||||
|
|
||||||
|
if (this.name == "show_texts_near_circles") { |
||||||
|
text.attr("visibility", this.checked ? "visible" : "hidden") |
||||||
|
show_texts_near_circles = this.checked |
||||||
|
force.start(); |
||||||
|
} |
||||||
|
|
||||||
|
}); |
||||||
|
</script> |
||||||
|
|
||||||
|
|
||||||
|
<script> |
||||||
|
// =================================================== |
||||||
|
// =============== LIVE FILTERING ============== |
||||||
|
// =================================================== |
||||||
|
d3.select("#search_input").on("input", function () { |
||||||
|
// Filter all items |
||||||
|
console.log("Input changed to" + this.value) |
||||||
|
deselect_node(selectedobject); |
||||||
|
|
||||||
|
if (this.value && this.value.length) { |
||||||
|
var re = new RegExp(this.value, "i"); |
||||||
|
svg.selectAll('circle, text') |
||||||
|
.classed('filtered', function(node) { |
||||||
|
var filtered = !node.name.match(re); |
||||||
|
node.filtered = filtered; |
||||||
|
node.neighbours = !filtered; |
||||||
|
return filtered; |
||||||
|
}) |
||||||
|
.transition() |
||||||
|
|
||||||
|
svg.selectAll('.link') |
||||||
|
.classed('filtered', function(l) { |
||||||
|
var filtered = !(l.sourceNode.name.match(re) && l.targetNode.name.match(re)); |
||||||
|
return filtered; |
||||||
|
}) |
||||||
|
.attr("marker-end", function (l) { |
||||||
|
var filtered = !(l.sourceNode.name.match(re) && l.targetNode.name.match(re)); |
||||||
|
return filtered ? "" : "url(#default)" |
||||||
|
}) |
||||||
|
.transition() |
||||||
|
|
||||||
|
force.start(); |
||||||
|
} |
||||||
|
}); |
||||||
|
</script> |
@ -0,0 +1,119 @@ |
|||||||
|
var dependencies = { |
||||||
|
links: |
||||||
|
[ |
||||||
|
{ "source" : "ApplicationDelegate", "dest" : "Crashlytics" }, |
||||||
|
{ "source" : "ApplicationDelegate", "dest" : "Fabric" }, |
||||||
|
{ "source" : "ApplicationDelegate", "dest" : "MenubarController" }, |
||||||
|
{ "source" : "ApplicationDelegate", "dest" : "PFAnalytics" }, |
||||||
|
{ "source" : "ApplicationDelegate", "dest" : "PanelController" }, |
||||||
|
{ "source" : "ApplicationDelegate", "dest" : "Parse" }, |
||||||
|
{ "source" : "ApplicationDelegate", "dest" : "iRate" }, |
||||||
|
{ "source" : "ApplicationDelegate", "dest" : "iVersion" }, |
||||||
|
{ "source" : "CLAboutUsViewController", "dest" : "CLAppFeedbackWindowController" }, |
||||||
|
{ "source" : "CLAppFeedbackWindowController", "dest" : "CLOneWindowController" }, |
||||||
|
{ "source" : "CLAppFeedbackWindowController", "dest" : "PFObject" }, |
||||||
|
{ "source" : "CLOneWindowController", "dest" : "CLAboutUsViewController" }, |
||||||
|
{ "source" : "CLOneWindowController", "dest" : "CLAppearanceViewController" }, |
||||||
|
{ "source" : "CLOneWindowController", "dest" : "CLPreferencesViewController" }, |
||||||
|
{ "source" : "CLPreferencesViewController", "dest" : "PFObject" }, |
||||||
|
{ "source" : "CLPreferencesViewController", "dest" : "Reachability" }, |
||||||
|
{ "source" : "CLRatingCellView", "dest" : "CLAppFeedbackWindowController" }, |
||||||
|
{ "source" : "CLRatingCellView", "dest" : "iRate" }, |
||||||
|
{ "source" : "CLTimezoneCellView", "dest" : "PanelController" }, |
||||||
|
{ "source" : "DTTimePeriodChain", "dest" : "DTError" }, |
||||||
|
{ "source" : "DTTimePeriodChain", "dest" : "DTTimePeriod" }, |
||||||
|
{ "source" : "DTTimePeriodChain", "dest" : "DTTimePeriodGroup" }, |
||||||
|
{ "source" : "DTTimePeriodCollection", "dest" : "DTError" }, |
||||||
|
{ "source" : "DTTimePeriodCollection", "dest" : "DTTimePeriod" }, |
||||||
|
{ "source" : "DTTimePeriodCollection", "dest" : "DTTimePeriodGroup" }, |
||||||
|
{ "source" : "MenubarController", "dest" : "StatusItemView" }, |
||||||
|
{ "source" : "NSDate+DateTools", "dest" : "DTError" }, |
||||||
|
{ "source" : "PanelController", "dest" : "CLOneWindowController" }, |
||||||
|
{ "source" : "PanelController", "dest" : "Crashlytics" }, |
||||||
|
{ "source" : "PanelController", "dest" : "Reachability" }, |
||||||
|
{ "source" : "ApplicationDelegate", "dest" : "MenubarController" }, |
||||||
|
{ "source" : "ApplicationDelegate", "dest" : "StatusItemView" }, |
||||||
|
{ "source" : "ApplicationDelegate", "dest" : "PanelController" }, |
||||||
|
{ "source" : "ApplicationDelegate", "dest" : "CLOneWindowController" }, |
||||||
|
{ "source" : "ApplicationDelegate", "dest" : "CLPreferencesViewController" }, |
||||||
|
{ "source" : "ApplicationDelegate", "dest" : "CLAboutUsViewController" }, |
||||||
|
{ "source" : "ApplicationDelegate", "dest" : "CLAppFeedbackWindowController" }, |
||||||
|
{ "source" : "ApplicationDelegate", "dest" : "CLAppearanceViewController" }, |
||||||
|
{ "source" : "ApplicationDelegate", "dest" : "BackgroundView" }, |
||||||
|
{ "source" : "BackgroundView", "dest" : "ApplicationDelegate" }, |
||||||
|
{ "source" : "BackgroundView", "dest" : "MenubarController" }, |
||||||
|
{ "source" : "BackgroundView", "dest" : "StatusItemView" }, |
||||||
|
{ "source" : "BackgroundView", "dest" : "PanelController" }, |
||||||
|
{ "source" : "BackgroundView", "dest" : "CLOneWindowController" }, |
||||||
|
{ "source" : "BackgroundView", "dest" : "CLPreferencesViewController" }, |
||||||
|
{ "source" : "BackgroundView", "dest" : "CLAboutUsViewController" }, |
||||||
|
{ "source" : "BackgroundView", "dest" : "CLAppFeedbackWindowController" }, |
||||||
|
{ "source" : "BackgroundView", "dest" : "CLAppearanceViewController" }, |
||||||
|
{ "source" : "CLAboutUsViewController", "dest" : "CLAppFeedbackWindowController" }, |
||||||
|
{ "source" : "CLAppearanceViewController", "dest" : "ApplicationDelegate" }, |
||||||
|
{ "source" : "CLAppearanceViewController", "dest" : "MenubarController" }, |
||||||
|
{ "source" : "CLAppearanceViewController", "dest" : "StatusItemView" }, |
||||||
|
{ "source" : "CLAppearanceViewController", "dest" : "PanelController" }, |
||||||
|
{ "source" : "CLAppearanceViewController", "dest" : "CLOneWindowController" }, |
||||||
|
{ "source" : "CLAppearanceViewController", "dest" : "CLPreferencesViewController" }, |
||||||
|
{ "source" : "CLAppearanceViewController", "dest" : "CLAboutUsViewController" }, |
||||||
|
{ "source" : "CLAppearanceViewController", "dest" : "CLAppFeedbackWindowController" }, |
||||||
|
{ "source" : "CLAppearanceViewController", "dest" : "BackgroundView" }, |
||||||
|
{ "source" : "CLAppFeedbackWindowController", "dest" : "PFObject" }, |
||||||
|
{ "source" : "CLAppFeedbackWindowController", "dest" : "PFACL" }, |
||||||
|
{ "source" : "CLOneWindowController", "dest" : "CLPreferencesViewController" }, |
||||||
|
{ "source" : "CLOneWindowController", "dest" : "CLAboutUsViewController" }, |
||||||
|
{ "source" : "CLOneWindowController", "dest" : "CLAppFeedbackWindowController" }, |
||||||
|
{ "source" : "CLOneWindowController", "dest" : "CLAppearanceViewController" }, |
||||||
|
{ "source" : "CLPreferencesViewController", "dest" : "Panel" }, |
||||||
|
{ "source" : "CLPreferencesViewController", "dest" : "PFObject" }, |
||||||
|
{ "source" : "CLPreferencesViewController", "dest" : "PFACL" }, |
||||||
|
{ "source" : "CLPreferencesViewController", "dest" : "ApplicationDelegate" }, |
||||||
|
{ "source" : "CLPreferencesViewController", "dest" : "MenubarController" }, |
||||||
|
{ "source" : "CLPreferencesViewController", "dest" : "StatusItemView" }, |
||||||
|
{ "source" : "CLPreferencesViewController", "dest" : "PanelController" }, |
||||||
|
{ "source" : "CLPreferencesViewController", "dest" : "CLOneWindowController" }, |
||||||
|
{ "source" : "CLPreferencesViewController", "dest" : "CLAboutUsViewController" }, |
||||||
|
{ "source" : "CLPreferencesViewController", "dest" : "CLAppFeedbackWindowController" }, |
||||||
|
{ "source" : "CLPreferencesViewController", "dest" : "CLAppearanceViewController" }, |
||||||
|
{ "source" : "CLPreferencesViewController", "dest" : "BackgroundView" }, |
||||||
|
{ "source" : "CLPreferencesViewController", "dest" : "Reachability" }, |
||||||
|
{ "source" : "CLRatingCellView", "dest" : "CLAppFeedbackWindowController" }, |
||||||
|
{ "source" : "CLRatingCellView", "dest" : "PanelController" }, |
||||||
|
{ "source" : "CLRatingCellView", "dest" : "CLOneWindowController" }, |
||||||
|
{ "source" : "CLRatingCellView", "dest" : "CLPreferencesViewController" }, |
||||||
|
{ "source" : "CLRatingCellView", "dest" : "CLAboutUsViewController" }, |
||||||
|
{ "source" : "CLRatingCellView", "dest" : "CLAppearanceViewController" }, |
||||||
|
{ "source" : "CLRatingCellView", "dest" : "BackgroundView" }, |
||||||
|
{ "source" : "CLTimezoneCellView", "dest" : "PanelController" }, |
||||||
|
{ "source" : "CLTimezoneCellView", "dest" : "CLOneWindowController" }, |
||||||
|
{ "source" : "CLTimezoneCellView", "dest" : "CLPreferencesViewController" }, |
||||||
|
{ "source" : "CLTimezoneCellView", "dest" : "CLAboutUsViewController" }, |
||||||
|
{ "source" : "CLTimezoneCellView", "dest" : "CLAppFeedbackWindowController" }, |
||||||
|
{ "source" : "CLTimezoneCellView", "dest" : "CLAppearanceViewController" }, |
||||||
|
{ "source" : "CLTimezoneCellView", "dest" : "BackgroundView" }, |
||||||
|
{ "source" : "DTTimePeriodChain", "dest" : "DTTimePeriod" }, |
||||||
|
{ "source" : "DTTimePeriodCollection", "dest" : "DTTimePeriod" }, |
||||||
|
{ "source" : "DTTimePeriodGroup", "dest" : "DTTimePeriod" }, |
||||||
|
{ "source" : "iRate", "dest" : "PanelController" }, |
||||||
|
{ "source" : "iRate", "dest" : "CLOneWindowController" }, |
||||||
|
{ "source" : "iRate", "dest" : "CLPreferencesViewController" }, |
||||||
|
{ "source" : "iRate", "dest" : "CLAboutUsViewController" }, |
||||||
|
{ "source" : "iRate", "dest" : "CLAppFeedbackWindowController" }, |
||||||
|
{ "source" : "iRate", "dest" : "CLAppearanceViewController" }, |
||||||
|
{ "source" : "iRate", "dest" : "BackgroundView" }, |
||||||
|
{ "source" : "MenubarController", "dest" : "StatusItemView" }, |
||||||
|
{ "source" : "PanelController", "dest" : "CLOneWindowController" }, |
||||||
|
{ "source" : "PanelController", "dest" : "CLPreferencesViewController" }, |
||||||
|
{ "source" : "PanelController", "dest" : "CLAboutUsViewController" }, |
||||||
|
{ "source" : "PanelController", "dest" : "CLAppFeedbackWindowController" }, |
||||||
|
{ "source" : "PanelController", "dest" : "CLAppearanceViewController" }, |
||||||
|
{ "source" : "PanelController", "dest" : "BackgroundView" }, |
||||||
|
{ "source" : "PanelController", "dest" : "StatusItemView" }, |
||||||
|
{ "source" : "PanelController", "dest" : "CLRatingCellView" }, |
||||||
|
{ "source" : "PanelController", "dest" : "CLTimezoneCellView" }, |
||||||
|
{ "source" : "PanelController", "dest" : "Reachability" }, |
||||||
|
{ "source" : "Reachability", "dest" : "CFStringRef" }, |
||||||
|
] |
||||||
|
} |
||||||
|
; |
Loading…
Reference in new issue