SlideShare ist ein Scribd-Unternehmen logo
1 von 130
Downloaden Sie, um offline zu lesen
openCPQ
–
A React-Based Product-Configuration
Toolkit
Tim Geisler, Heribert Schütz
webXcerpt Software GmbH
tg@webxcerpt.com, hs@webxcerpt.com
MunichJS Meetup, 2015-05-13
Product Configuration
Product Configuration
Variants
Product Configuration
Variants
Parameters and Domains
Product Configuration
Variants
Parameters and Domains
Product Configuration
Variants
Parameters and Domains
Product Configuration
Variants
Parameters and Domains
Product Configuration
, Dependencies
Variants
Parameters and Domains
Product Configuration
, Dependencies
Variants
Parameters and Domains
Product Configuration
, Dependencies
Variants
Parameters and Domains
Product Configuration
, Dependencies
Variants
Parameters and Domains
Product Configuration
, Dependencies
Variants
Parameters and Domains
Product Configuration
, Dependencies
Variants
Parameters and Domains
Demo
Optical Transport
Demo Example:
Hierarchical Configuration
SwitchRackSolution Board (Module) Transceiver (Wavelength)
Demo
http://opencpq.webxcerpt.com/examples/optical-transport/
^
Business Processes
Configuration Engine
User
Configuration
Which particular variant
do I want to buy/sell?
Business Processes
Configuration Engine
User
Configuration
Which particular variant
do I want to buy/sell?
Manufacturing Plan
Visualization
Price(s)
Bill of Materials
...
Business Processes
Product Model
Configuration Engine
User
Configuration
Which variants of a product
are available?
Which particular variant
do I want to buy/sell?
Manufacturing Plan
Visualization
Price(s)
Bill of Materials
...
Business Processes
Modeling Tool
Modeler
Product Model
Configuration Engine
User
Configuration
Which variants of a product
are available?
Which particular variant
do I want to buy/sell?
Manufacturing Plan
Visualization
Price(s)
Bill of Materials
...
Business Processes
Modeling Tool
Modeler
Product Model
Configuration Engine
User
Configuration
Which variants of a product
are available?
Which particular variant
do I want to buy/sell?
Manufacturing Plan
Visualization
Price(s)
Bill of Materials
...
complex
(web)
applications
Business Processes
Modeling Tool
Modeler
Product Model
Configuration Engine
User
Configuration
Which variants of a product
are available?
Which particular variant
do I want to buy/sell?
Manufacturing Plan
Visualization
Price(s)
Bill of Materials
...
complex
(web)
applications
proprietary
format
Problem 1
Product Model
Modeling Tool
Business Processes
Modeler
Configuration Engine
User
Configuration
Which variants of a product
are available?
Which particular variant
do I want to buy/sell?
Manufacturing Plan
Visualization
Price(s)
Bill of Materials
...
Business Processes
Modeler
Configuration Engine
User
Configuration
Which variants of a product
are available?
Which particular variant
do I want to buy/sell?
Manufacturing Plan
Visualization
Price(s)
Bill of Materials
...
Customer-Specific
Modeling Language
Code Generator
Product Model
High-Level
Product Model
Customer-specific IDE
Business Processes
Modeler
Configuration Engine
User
Configuration
Which variants of a product
are available?
Which particular variant
do I want to buy/sell?
Manufacturing Plan
Visualization
Price(s)
Bill of Materials
...
Customer-Specific
Modeling Language
Code Generator
Product Model
High-Level
Product Model
Customer-specific IDE
● Text
● Notions like
„slot“, „board“, ...
Business Processes
Modeler
Configuration Engine
User
Configuration
Which variants of a product
are available?
Which particular variant
do I want to buy/sell?
Manufacturing Plan
Visualization
Price(s)
Bill of Materials
...
Customer-Specific
Modeling Language
Code Generator
Product Model
High-Level
Product Model
Customer-specific IDE
Based on
● Eclipse
● Xtext
● Text
● Notions like
„slot“, „board“, ...
Product Models
Product Models
● Product parameters
– Data types
– Ranges
Product Models
● Product parameters
– Data types
– Ranges
● Components
Product Models
● Product parameters
– Data types
– Ranges
● Components
● Dependencies between
parameters/components
Product Models
● Product parameters
– Data types
– Ranges
● Components
● Dependencies between
parameters/components
● Calculation of additional output
Product Models
● Product parameters
– Data types
– Ranges
● Components
● Dependencies between
parameters/components
● Calculation of additional output
Models are programs!
Modeling as Programming
Modeling as Programming
● Abstractions, data structures
Modeling as Programming
● Abstractions, data structures
● Programming tools
– Editors/IDEs
– Debuggers and profilers
– Revision control
– Test and CI frameworks
Modeling as Programming
● Abstractions, data structures
● Programming tools
– Editors/IDEs
– Debuggers and profilers
– Revision control
– Test and CI frameworks
● General purpose tools and languages
– Maturity
– Re-usable knowledge, may already be available
– Large communities and „ecosystems“
Problem 2
Configuring in the Browser
Configuring in the Browser
Implement configurators in JavaScript.
Configuring in the Browser
Implement configurators in JavaScript.
JavaScript is also
a reasonable choice for modeling.
Business Processes
Modeling Tool
Product Model
Configuration Engine
Manufacturing Plan
Visualization
Modeler User
Configuration
Which variants of a product
are available?
Which particular variant
do I want to buy/sell?
Price(s)
Bill of Materials
...
Business Processes
Manufacturing Plan
Visualization
Processes with openCPQ
Editor / IDE
Modeler
JavaScript Code
Browser
User
Configuration
Which variants of a product
are available?
Which particular variant
do I want to buy/sell?
Price(s)
Bill of Materials
...
openCPQ
Business Processes
Manufacturing Plan
Visualization
Processes with openCPQ
Editor / IDE
Modeler
JavaScript Code
Browser
User
Configuration
Which variants of a product
are available?
Which particular variant
do I want to buy/sell?
Price(s)
Bill of Materials
...
openCPQ
standard
components
Business Processes
Manufacturing Plan
Visualization
Processes with openCPQ
Editor / IDE
Modeler
JavaScript Code
Browser
User
Configuration
Which variants of a product
are available?
Which particular variant
do I want to buy/sell?
Price(s)
Bill of Materials
...
openCPQ
standard
components
expressive,
popular
Business Processes
Manufacturing Plan
Visualization
Processes with openCPQ
Editor / IDE
Modeler
JavaScript Code
Browser
User
Configuration
Which variants of a product
are available?
Which particular variant
do I want to buy/sell?
Price(s)
Bill of Materials
...
openCPQ
standard
components
light-weight
layer
expressive,
popular
– a Configurator Toolkit in JS
● Building-block library
– Components
– Dependencies
– a Configurator Toolkit in JS
● Building-block library
– Components
– Dependencies
● Combine building blocks with JavaScript
– a Configurator Toolkit in JS
● Building-block library
– Components
– Dependencies
● Combine building blocks with JavaScript
● Add application-specific building blocks
– a Configurator Toolkit in JS
● Building-block library
– Components
– Dependencies
● Combine building blocks with JavaScript
● Add application-specific building blocks
● A light-weight layer based on React and
Bootstrap
– a Configurator Toolkit in JS
– an Open-Source Project
Source code and links to live demos
available on Github:
https://github.com/webXcerpt/openCPQ
– an Open-Source Project
Source code and links to live demos
available on Github:
https://github.com/webXcerpt/openCPQ
Liberal MIT license
– an Open-Source Project
Source code and links to live demos
available on Github:
https://github.com/webXcerpt/openCPQ
Liberal MIT license
Use, adapt,
integrate, contribute!
– an Open-Source Project
How it Works
Change Propagation:
Non-Incremental
core
state
Change Propagation:
Non-Incremental
core
state inference
full
state
Change Propagation:
Non-Incremental
core
state
user
interfaceinference render
full
state
Change Propagation:
Non-Incremental
core
state
user
interfaceinference render
full
state
core
state
user
update
Change Propagation:
Non-Incremental
core
state
user
interfaceinference render
full
state
core
state
user
interface
full
state
user
update
inference render
Change Propagation:
Non-Incremental
core
state
user
interfaceinference render
full
state
core
state
user
interface
full
state
core
state
user
interface
full
state
user
update
user
update
inference render
inference render
Change Propagation:
Incremental
core
state
user
interface
full
state
user
update
core
state
user
interface
full
state
user
update
core
state
user
interface
full
state
Change Propagation:
Incremental
core
state
user
interface
full
state
user
update
derived
update
core
state
user
interface
full
state
user
update
core
state
user
interface
full
state
Change Propagation:
Incremental
core
state
user
interface
full
state
user
update
derived
update
derived
update
core
state
user
interface
full
state
user
update
core
state
user
interface
full
state
Change Propagation:
Incremental
core
state
user
interface
full
state
user
update
derived
update
derived
update
core
state
user
interface
full
state
user
update
derived
update
derived
update
core
state
user
interface
full
state
Change Propagation:
Mixed
core
state
user
interface
full
state
user
update
derived
update
core
state
user
interface
full
state
user
update
derived
update
core
state
user
interface
full
state
inference
inference
inference
React:
A JavaScript library for building user interfaces
React:
A JavaScript library for building user interfaces
● Unique approach:
– not a widget library
– not an MVC framework
React:
A JavaScript library for building user interfaces
● Unique approach:
– not a widget library
– not an MVC framework
● Virtual DOM ("VDOM"):
– Representation of the DOM tree as a JavaScript
data structure (cheap!)
React:
A JavaScript library for building user interfaces
● Unique approach:
– not a widget library
– not an MVC framework
● Virtual DOM ("VDOM"):
– Representation of the DOM tree as a JavaScript
data structure (cheap!)
● Upon each update:
React:
A JavaScript library for building user interfaces
● Unique approach:
– not a widget library
– not an MVC framework
● Virtual DOM ("VDOM"):
– Representation of the DOM tree as a JavaScript data
structure (cheap!)
● Upon each update:
– User code
● generates VDOM from your model
● possibly using XML templating integrated into JavaScript ("JSX")
React:
A JavaScript library for building user interfaces
● Unique approach:
– not a widget library
– not an MVC framework
● Virtual DOM ("VDOM"):
– Representation of the DOM tree as a JavaScript data structure
(cheap!)
● Upon each update:
– User code
● generates VDOM from your model
● possibly using XML templating integrated into JavaScript ("JSX")
– React
● diffs the VDOM with the previous VDOM
● applies only the diff to the actual DOM
Architecture
State
(JSON)State
(JSON)
Nodes
Nodes
VDOM
VDOM DOM
Types render()
apply
delta
Product
Model
Updates
Architecture
State
(JSON)State
(JSON)
Nodes
Nodes
VDOM
VDOM DOM
Types render()
apply
delta
Product
Model
Updates
Architecture
State
(JSON)State
(JSON)
Nodes
Nodes
VDOM
VDOM DOM
Types render()
apply
delta
Product
Model
Updates
Example Code: Product Model
State
(JSON)State
(JSON)
Nodes
Nodes
VDOM
VDOM DOM
Types render()
apply
delta
Product
Model
Updates
Product Model: Cases with Details
Product Model: Cases with Details
var configuration = CSelect([
unansweredCase("Select Configuration Mode"),
ccase("Switches", "Optical Switches",
CQuantifiedList({}, "Optical Switch",
opticalSwitches)),
ccase("Rack", "Racks",
CQuantifiedList({}, "Rack",
rack)),
ccase("Solution", "Solution",
solution),
]);
cases
details
Product Model: Cases with Details
var configuration = CSelect([
unansweredCase("Select Configuration Mode"),
ccase("Switches", "Optical Switches",
CQuantifiedList({}, "Optical Switch",
opticalSwitches)),
ccase("Rack", "Racks",
CQuantifiedList({}, "Rack",
rack)),
ccase("Solution", "Solution",
solution),
]);
cases
details
function configuration({caseId, details}) {
switch (caseId) {
case "unanswered": /* do nothing */ break;
case "Switches":
CQuantifiedList({}, "Optical Switch",
opticalSwitches)(details);
break;
case "Rack": ...; break;
case "Solution":
solution(details);
break;
}
}
Compare to
pseudocode:
Product Model: Cases with Details
var configuration = CSelect([
unansweredCase("Select Configuration Mode"),
ccase("Switches", "Optical Switches",
CQuantifiedList({}, "Optical Switch",
opticalSwitches)),
ccase("Rack", "Racks",
CQuantifiedList({}, "Rack",
rack)),
ccase("Solution", "Solution",
solution),
]);
cases
details
Data-Driven Product Modeling
Data-Driven Product Modeling
Data-Driven Product Modeling
Data-Driven Product Modeling
Data-Driven Product Modeling
function boards(isDoubleWidthSlot) {
return CSelect([
for (b of components.boards)
if (!b.doubleWidth || isDoubleWidthSlot)
ccaseBOM(b.name, b.label,
aggregate("power", b.power,
ports(b.ports)))
]);
}
Data-Driven Product Modeling
function boards(isDoubleWidthSlot) {
return CSelect([
for (b of components.boards)
if (!b.doubleWidth || isDoubleWidthSlot)
ccaseBOM(b.name, b.label,
aggregate("power", b.power,
ports(b.ports)))
]);
}
[for (… of …) if (…) …]
array comprehension
Data-Driven Product Modeling
function boards(isDoubleWidthSlot) {
return CSelect([
for (b of components.boards)
if (!b.doubleWidth || isDoubleWidthSlot)
ccaseBOM(b.name, b.label,
aggregate("power", b.power,
ports(b.ports)))
]);
}
Concise specification of complex models
Example Data: State
State
(JSON)State
(JSON)
Nodes
Nodes
VDOM
VDOM DOM
Types render()
apply
delta
Product
Model
Updates
Configuration State
{
"caseId": "Solution",
"detailValue": {
"project": {
"release": {
"caseId": "R2.0"
},
"UPS": true
},
"racks": [
{
"quantity": "4",
"value": {
"UPS": true,
"switches": [
…
]
}
}
]
}
}
Example Code: Node Rendering
State
(JSON)State
(JSON)
Nodes
Nodes
VDOM
VDOM DOM
Types render()
apply
delta
Product
Model
Updates
Selection Node (simplified)
class SelectNode extends Node {
//constructor(options) { this.__options = options; }
render() {
var {cases, currentCase, detailNode, updateTo} = this.__options;
return (
<div>
<DropdownButton title={currentCase.label}>
{[
for ({id, label} of cases)
<MenuItem onSelect={() => updateTo({caseId: id})}>
{label}
</MenuItem>
]}
</DropdownButton>
{detailNode.render()}
</div>
);
}
}
Selection Node (simplified)
class SelectNode extends Node {
//constructor(options) { this.__options = options; }
render() {
var {cases, currentCase, detailNode, updateTo} = this.__options;
return (
<div>
<DropdownButton title={currentCase.label}>
{[
for ({id, label} of cases)
<MenuItem onSelect={() => updateTo({caseId: id})}>
{label}
</MenuItem>
]}
</DropdownButton>
{detailNode.render()}
</div>
);
}
}
Inherited constructor
Unpack constructor
parameters.
Selection Node (simplified)
class SelectNode extends Node {
//constructor(options) { this.__options = options; }
render() {
var {cases, currentCase, detailNode, updateTo} = this.__options;
return (
<div>
<DropdownButton title={currentCase.label}>
{[
for ({id, label} of cases)
<MenuItem onSelect={() => updateTo({caseId: id})}>
{label}
</MenuItem>
]}
</DropdownButton>
{detailNode.render()}
</div>
);
}
}
Create a VDOM tree.
Selection Node (simplified)
class SelectNode extends Node {
//constructor(options) { this.__options = options; }
render() {
var {cases, currentCase, detailNode, updateTo} = this.__options;
return (
<div>
<DropdownButton title={currentCase.label}>
{[
for ({id, label} of cases)
<MenuItem onSelect={() => updateTo({caseId: id})}>
{label}
</MenuItem>
]}
</DropdownButton>
{detailNode.render()}
</div>
);
}
}
JSX:
HTML templates
in JavaScript
Selection Node (simplified)
class SelectNode extends Node {
//constructor(options) { this.__options = options; }
render() {
var {cases, currentCase, detailNode, updateTo} = this.__options;
return (
<div>
<DropdownButton title={currentCase.label}>
{[
for ({id, label} of cases)
<MenuItem onSelect={() => updateTo({caseId: id})}>
{label}
</MenuItem>
]}
</DropdownButton>
{detailNode.render()}
</div>
);
}
}
JSX:
HTML templates
in JavaScript
… also with „higher-level“
XML elements
(from react-bootstrap)
Selection Node (simplified)
class SelectNode extends Node {
//constructor(options) { this.__options = options; }
render() {
var {cases, currentCase, detailNode, updateTo} = this.__options;
return (
<div>
<DropdownButton title={currentCase.label}>
{[
for ({id, label} of cases)
<MenuItem onSelect={() => updateTo({caseId: id})}>
{label}
</MenuItem>
]}
</DropdownButton>
{detailNode.render()}
</div>
);
}
}
Interpolate JavaScript
expressions with {...}
Selection Node (simplified)
class SelectNode extends Node {
//constructor(options) { this.__options = options; }
render() {
var {cases, currentCase, detailNode, updateTo} = this.__options;
return (
<div>
<DropdownButton title={currentCase.label}>
{[
for ({id, label} of cases)
<MenuItem onSelect={() => updateTo({caseId: id})}>
{label}
</MenuItem>
]}
</DropdownButton>
{detailNode.render()}
</div>
);
}
}
array comprehension
Selection Node (simplified)
class SelectNode extends Node {
//constructor(options) { this.__options = options; }
render() {
var {cases, currentCase, detailNode, updateTo} = this.__options;
return (
<div>
<DropdownButton title={currentCase.label}>
{[
for ({id, label} of cases)
<MenuItem onSelect={() => updateTo({caseId: id})}>
{label}
</MenuItem>
]}
</DropdownButton>
{detailNode.render()}
</div>
);
}
}
Example Code: Types
State
(JSON)State
(JSON)
Nodes
Nodes
VDOM
VDOM DOM
Types render()
apply
delta
Product
Model
Updates
function ccase(id, label, type = CUnit()) {
return {id, label, type};
}
function CSelect(cases) {
return {
makeNode(ctx) {
var {state, updateTo} = ctx;
var {caseId, detailState} = state || {caseId: cases[0].id};
var currentCase = cases.find(x => x.id === caseId);
var detailNode = currentCase.type.makeNode({
...ctx,
state: detailState,
updateTo(newDetail) {
updateTo({caseId, detailState: newDetail});
}
});
return new SelectNode({cases, currentCase, detailNode, updateTo});
}
};
}
Selection Type (simplified)
function ccase(id, label, type = CUnit()) {
return {id, label, type};
}
function CSelect(cases) {
return {
makeNode(ctx) {
var {state, updateTo} = ctx;
var {caseId, detailState} = state || {caseId: cases[0].id};
var currentCase = cases.find(x => x.id === caseId);
var detailNode = currentCase.type.makeNode({
...ctx,
state: detailState,
updateTo(newDetail) {
updateTo({caseId, detailState: newDetail});
}
});
return new SelectNode({cases, currentCase, detailNode, updateTo});
}
};
}
Selection Type (simplified)
function ccase(id, label, type = CUnit()) {
return {id, label, type};
}
function CSelect(cases) {
return {
makeNode(ctx) {
var {state, updateTo} = ctx;
var {caseId, detailState} = state || {caseId: cases[0].id};
var currentCase = cases.find(x => x.id === caseId);
var detailNode = currentCase.type.makeNode({
...ctx,
state: detailState,
updateTo(newDetail) {
updateTo({caseId, detailState: newDetail});
}
});
return new SelectNode({cases, currentCase, detailNode, updateTo});
}
};
}
Selection Type (simplified)
function ccase(id, label, type = CUnit()) {
return {id, label, type};
}
function CSelect(cases) {
return {
makeNode(ctx) {
var {state, updateTo} = ctx;
var {caseId, detailState} = state || {caseId: cases[0].id};
var currentCase = cases.find(x => x.id === caseId);
var detailNode = currentCase.type.makeNode({
...ctx,
state: detailState,
updateTo(newDetail) {
updateTo({caseId, detailState: newDetail});
}
});
return new SelectNode({cases, currentCase, detailNode, updateTo});
}
};
}
Selection Type (simplified)
Nothing to configure
function ccase(id, label, type = CUnit()) {
return {id, label, type};
}
function CSelect(cases) {
return {
makeNode(ctx) {
var {state, updateTo} = ctx;
var {caseId, detailState} = state || {caseId: cases[0].id};
var currentCase = cases.find(x => x.id === caseId);
var detailNode = currentCase.type.makeNode({
...ctx,
state: detailState,
updateTo(newDetail) {
updateTo({caseId, detailState: newDetail});
}
});
return new SelectNode({cases, currentCase, detailNode, updateTo});
}
};
}
Selection Type (simplified)
function ccase(id, label, type = CUnit()) {
return {id, label, type};
}
function CSelect(cases) {
return {
makeNode(ctx) {
var {state, updateTo} = ctx;
var {caseId, detailState} = state || {caseId: cases[0].id};
var currentCase = cases.find(x => x.id === caseId);
var detailNode = currentCase.type.makeNode({
...ctx,
state: detailState,
updateTo(newDetail) {
updateTo({caseId, detailState: newDetail});
}
});
return new SelectNode({cases, currentCase, detailNode, updateTo});
}
};
}
Selection Type (simplified)
function ccase(id, label, type = CUnit()) {
return {id, label, type};
}
function CSelect(cases) {
return {
makeNode(ctx) {
var {state, updateTo} = ctx;
var {caseId, detailState} = state || {caseId: cases[0].id};
var currentCase = cases.find(x => x.id === caseId);
var detailNode = currentCase.type.makeNode({
...ctx,
state: detailState,
updateTo(newDetail) {
updateTo({caseId, detailState: newDetail});
}
});
return new SelectNode({cases, currentCase, detailNode, updateTo});
}
};
}
Selection Type (simplified)
function ccase(id, label, type = CUnit()) {
return {id, label, type};
}
function CSelect(cases) {
return {
makeNode(ctx) {
var {state, updateTo} = ctx;
var {caseId, detailState} = state || {caseId: cases[0].id};
var currentCase = cases.find(x => x.id === caseId);
var detailNode = currentCase.type.makeNode({
...ctx,
state: detailState,
updateTo(newDetail) {
updateTo({caseId, detailState: newDetail});
}
});
return new SelectNode({cases, currentCase, detailNode, updateTo});
}
};
}
Selection Type (simplified)
Context:
● state
● updateTo() (replace state)
● aggregators (bill of materials, …)
● ...
Injects application-specific data.
function ccase(id, label, type = CUnit()) {
return {id, label, type};
}
function CSelect(cases) {
return {
makeNode(ctx) {
var {state, updateTo} = ctx;
var {caseId, detailState} = state || {caseId: cases[0].id};
var currentCase = cases.find(x => x.id === caseId);
var detailNode = currentCase.type.makeNode({
...ctx,
state: detailState,
updateTo(newDetail) {
updateTo({caseId, detailState: newDetail});
}
});
return new SelectNode({cases, currentCase, detailNode, updateTo});
}
};
}
Selection Type (simplified)
Context:
● state
● updateTo() (replace state)
● aggregators (bill of materials, …)
● ...
Injects application-specific data.
function ccase(id, label, type = CUnit()) {
return {id, label, type};
}
function CSelect(cases) {
return {
makeNode(ctx) {
var {state, updateTo} = ctx;
var {caseId, detailState} = state || {caseId: cases[0].id};
var currentCase = cases.find(x => x.id === caseId);
var detailNode = currentCase.type.makeNode({
...ctx,
state: detailState,
updateTo(newDetail) {
updateTo({caseId, detailState: newDetail});
}
});
return new SelectNode({cases, currentCase, detailNode, updateTo});
}
};
}
Selection Type (simplified)
detailNode = detailType(ctx')
function ccase(id, label, type = CUnit()) {
return {id, label, type};
}
function CSelect(cases) {
return {
makeNode(ctx) {
var {state, updateTo} = ctx;
var {caseId, detailState} = state || {caseId: cases[0].id};
var currentCase = cases.find(x => x.id === caseId);
var detailNode = currentCase.type.makeNode({
...ctx,
state: detailState,
updateTo(newDetail) {
updateTo({caseId, detailState: newDetail});
}
});
return new SelectNode({cases, currentCase, detailNode, updateTo});
}
};
}
Selection Type (simplified)
detailNode = detailType(ctx')
updateTo() for detail node:
● do not modify surrounding state
● send new state to parent's updateTo()
=> easy undo/redo
function ccase(id, label, type = CUnit()) {
return {id, label, type};
}
function CSelect(cases) {
return {
makeNode(ctx) {
var {state, updateTo} = ctx;
var {caseId, detailState} = state || {caseId: cases[0].id};
var currentCase = cases.find(x => x.id === caseId);
var detailNode = currentCase.type.makeNode({
...ctx,
state: detailState,
updateTo(newDetail) {
updateTo({caseId, detailState: newDetail});
}
});
return new SelectNode({cases, currentCase, detailNode, updateTo});
}
};
}
Selection Type (simplified)
function ccase(id, label, type = CUnit()) {
return {id, label, type};
}
function CSelect(cases) {
return {
makeNode(ctx) {
var {state, updateTo} = ctx;
var {caseId, detailState} = state || {caseId: cases[0].id};
var currentCase = cases.find(x => x.id === caseId);
var detailNode = currentCase.type.makeNode({
...ctx,
state: detailState,
updateTo(newDetail) {
updateTo({caseId, detailState: newDetail});
}
});
return new SelectNode({cases, currentCase, detailNode, updateTo});
}
};
}
Selection Type (simplified)
Tools
Tools
● react.js
Tools
● react.js
● bootstrap with ( or ?)
Tools
● react.js
● bootstrap with ( or ?)
● react-bootstrap, react-widgets
Tools
● react.js
● bootstrap with ( or ?)
● react-bootstrap, react-widgets
● ( react JSX/esprima; ?)
Tools
● react.js
● bootstrap with ( or ?)
● react-bootstrap, react-widgets
● ( react JSX/esprima; ?)
● webpack ( / )
Tools
● react.js
● bootstrap with ( or ?)
● react-bootstrap, react-widgets
● ( react JSX/esprima; ?)
● webpack ( / )
● ( ),
Tools
● react.js
● bootstrap with ( or ?)
● react-bootstrap, react-widgets
● ( react JSX/esprima; ?)
● webpack ( / )
● ( ),
●
Summary
Summary
Take advantage of modern browser
technology for product configuration.
Summary
Take advantage of modern browser
technology for product configuration.
Powerful modeling based on JavaScript,
React, and openCPQ.
Summary
Take advantage of modern browser
technology for product configuration.
Powerful modeling based on JavaScript,
React, and openCPQ.
Flexible and fast user interface.
Summary
Take advantage of modern browser
technology for product configuration.
Powerful modeling based on JavaScript,
React, and openCPQ.
Flexible and fast user interface.
Use, adapt, integrate, contribute!
https://github.com/webXcerpt/openCPQ
Issues to Discuss
Issues to Discuss
● Use cases
– product configuration, software configuration
– questionnaires
– …?
Issues to Discuss
● Use cases
– product configuration, software configuration
– questionnaires
– …?
● Technologies
Issues to Discuss
● Use cases
– product configuration, software configuration
– questionnaires
– …?
● Technologies
● Cooperation
– Extensions: Integrations (SAP, Salesforce, ...),
Visualization, ...
– Student projects
– Application development

Weitere ähnliche Inhalte

Was ist angesagt?

Rhapsody Eclipse
Rhapsody EclipseRhapsody Eclipse
Rhapsody EclipseBill Duncan
 
Pragmatic Model Driven Development using openArchitectureWare
Pragmatic Model Driven Development using openArchitectureWarePragmatic Model Driven Development using openArchitectureWare
Pragmatic Model Driven Development using openArchitectureWareMichael Vorburger
 
Installing Installing IBM Rational Rhapsody Designer and Architect for MBSE
Installing Installing IBM Rational Rhapsody Designer and Architect for MBSEInstalling Installing IBM Rational Rhapsody Designer and Architect for MBSE
Installing Installing IBM Rational Rhapsody Designer and Architect for MBSEFraser Chadburn
 
Product wise computer vision development
Product wise computer vision developmentProduct wise computer vision development
Product wise computer vision developmentYoss Cohen
 
Getting started with IBM Rational Rhapsody in Ada
Getting started with IBM Rational Rhapsody in AdaGetting started with IBM Rational Rhapsody in Ada
Getting started with IBM Rational Rhapsody in AdaFrank Braun
 
Comparison of Programming Platforms
Comparison of Programming PlatformsComparison of Programming Platforms
Comparison of Programming PlatformsAnup Hariharan Nair
 
Buildingwebapplicationswith.net
Buildingwebapplicationswith.netBuildingwebapplicationswith.net
Buildingwebapplicationswith.netKolagani Veera
 
Workflow for Development, Release and Versioning with OSGi / bndtools- Real W...
Workflow for Development, Release and Versioning with OSGi / bndtools- Real W...Workflow for Development, Release and Versioning with OSGi / bndtools- Real W...
Workflow for Development, Release and Versioning with OSGi / bndtools- Real W...mfrancis
 
Model-Driven Development for Safety-Critical Software
Model-Driven Development for Safety-Critical SoftwareModel-Driven Development for Safety-Critical Software
Model-Driven Development for Safety-Critical Softwaregjuljo
 
GMF : Create your graphical DSL - EclipseCon 11
GMF : Create your graphical DSL - EclipseCon 11GMF : Create your graphical DSL - EclipseCon 11
GMF : Create your graphical DSL - EclipseCon 11Chauvin Mariot
 
STAF 在自動化測試上的延伸應用 -- TMSTAF (TrendMicro STAF)
STAF 在自動化測試上的延伸應用 -- TMSTAF (TrendMicro STAF)STAF 在自動化測試上的延伸應用 -- TMSTAF (TrendMicro STAF)
STAF 在自動化測試上的延伸應用 -- TMSTAF (TrendMicro STAF)pycontw
 
Randomization and Constraints - Workshop at BMS College
Randomization and Constraints - Workshop at BMS CollegeRandomization and Constraints - Workshop at BMS College
Randomization and Constraints - Workshop at BMS CollegeRamdas Mozhikunnath
 
Ui Modeling In Action With PMF, e4(XWT) And EGF
Ui Modeling In Action With PMF, e4(XWT) And EGFUi Modeling In Action With PMF, e4(XWT) And EGF
Ui Modeling In Action With PMF, e4(XWT) And EGFBENOIT_LANGLOIS
 

Was ist angesagt? (20)

Kumar_J
Kumar_JKumar_J
Kumar_J
 
Rhapsody Eclipse
Rhapsody EclipseRhapsody Eclipse
Rhapsody Eclipse
 
desktop_resume
desktop_resumedesktop_resume
desktop_resume
 
Diwakar Nag
Diwakar NagDiwakar Nag
Diwakar Nag
 
Pragmatic Model Driven Development using openArchitectureWare
Pragmatic Model Driven Development using openArchitectureWarePragmatic Model Driven Development using openArchitectureWare
Pragmatic Model Driven Development using openArchitectureWare
 
Installing Installing IBM Rational Rhapsody Designer and Architect for MBSE
Installing Installing IBM Rational Rhapsody Designer and Architect for MBSEInstalling Installing IBM Rational Rhapsody Designer and Architect for MBSE
Installing Installing IBM Rational Rhapsody Designer and Architect for MBSE
 
Product wise computer vision development
Product wise computer vision developmentProduct wise computer vision development
Product wise computer vision development
 
MPHS RC Design Flow
MPHS RC Design FlowMPHS RC Design Flow
MPHS RC Design Flow
 
CAN FD Stack Introduction & Related FAQ
CAN FD Stack Introduction & Related FAQCAN FD Stack Introduction & Related FAQ
CAN FD Stack Introduction & Related FAQ
 
Getting started with IBM Rational Rhapsody in Ada
Getting started with IBM Rational Rhapsody in AdaGetting started with IBM Rational Rhapsody in Ada
Getting started with IBM Rational Rhapsody in Ada
 
Comparison of Programming Platforms
Comparison of Programming PlatformsComparison of Programming Platforms
Comparison of Programming Platforms
 
Buildingwebapplicationswith.net
Buildingwebapplicationswith.netBuildingwebapplicationswith.net
Buildingwebapplicationswith.net
 
Workflow for Development, Release and Versioning with OSGi / bndtools- Real W...
Workflow for Development, Release and Versioning with OSGi / bndtools- Real W...Workflow for Development, Release and Versioning with OSGi / bndtools- Real W...
Workflow for Development, Release and Versioning with OSGi / bndtools- Real W...
 
Model-Driven Development for Safety-Critical Software
Model-Driven Development for Safety-Critical SoftwareModel-Driven Development for Safety-Critical Software
Model-Driven Development for Safety-Critical Software
 
GMF : Create your graphical DSL - EclipseCon 11
GMF : Create your graphical DSL - EclipseCon 11GMF : Create your graphical DSL - EclipseCon 11
GMF : Create your graphical DSL - EclipseCon 11
 
Resume
ResumeResume
Resume
 
STAF 在自動化測試上的延伸應用 -- TMSTAF (TrendMicro STAF)
STAF 在自動化測試上的延伸應用 -- TMSTAF (TrendMicro STAF)STAF 在自動化測試上的延伸應用 -- TMSTAF (TrendMicro STAF)
STAF 在自動化測試上的延伸應用 -- TMSTAF (TrendMicro STAF)
 
Randomization and Constraints - Workshop at BMS College
Randomization and Constraints - Workshop at BMS CollegeRandomization and Constraints - Workshop at BMS College
Randomization and Constraints - Workshop at BMS College
 
RFT - Ashish Mathur
RFT - Ashish MathurRFT - Ashish Mathur
RFT - Ashish Mathur
 
Ui Modeling In Action With PMF, e4(XWT) And EGF
Ui Modeling In Action With PMF, e4(XWT) And EGFUi Modeling In Action With PMF, e4(XWT) And EGF
Ui Modeling In Action With PMF, e4(XWT) And EGF
 

Ähnlich wie openCPQ - A React-Based Product-Configuration Toolkit

PHPFrameworkDay 2020 - Different software evolutions from Start till Release ...
PHPFrameworkDay 2020 - Different software evolutions from Start till Release ...PHPFrameworkDay 2020 - Different software evolutions from Start till Release ...
PHPFrameworkDay 2020 - Different software evolutions from Start till Release ...Alexandr Savchenko
 
"Different software evolutions from Start till Release in PHP product" Oleksa...
"Different software evolutions from Start till Release in PHP product" Oleksa..."Different software evolutions from Start till Release in PHP product" Oleksa...
"Different software evolutions from Start till Release in PHP product" Oleksa...Fwdays
 
Modern development paradigms
Modern development paradigmsModern development paradigms
Modern development paradigmsIvano Malavolta
 
The building blocks for a reusable front end - #imaodbc2015
The building blocks for a reusable front end - #imaodbc2015The building blocks for a reusable front end - #imaodbc2015
The building blocks for a reusable front end - #imaodbc2015Jonathan Challener
 
JArchitect Benefits
JArchitect BenefitsJArchitect Benefits
JArchitect BenefitsCoderGears
 
Introduction to Data Models & Cisco's NextGen Device Level APIs: an overview
Introduction to Data Models & Cisco's NextGen Device Level APIs: an overviewIntroduction to Data Models & Cisco's NextGen Device Level APIs: an overview
Introduction to Data Models & Cisco's NextGen Device Level APIs: an overviewCisco DevNet
 
Building A Product Assortment Recommendation Engine
Building A Product Assortment Recommendation EngineBuilding A Product Assortment Recommendation Engine
Building A Product Assortment Recommendation EngineDatabricks
 
COMPRO- WEB ALBUM & MOTION ANALYZER
COMPRO- WEB ALBUM  & MOTION ANALYZERCOMPRO- WEB ALBUM  & MOTION ANALYZER
COMPRO- WEB ALBUM & MOTION ANALYZERAshish Tanwer
 
Productionizing Machine Learning - Bigdata meetup 5-06-2019
Productionizing Machine Learning - Bigdata meetup 5-06-2019Productionizing Machine Learning - Bigdata meetup 5-06-2019
Productionizing Machine Learning - Bigdata meetup 5-06-2019Iulian Pintoiu
 
What's new in Portal and WCM 8.5
What's new in Portal and WCM 8.5What's new in Portal and WCM 8.5
What's new in Portal and WCM 8.5Vinayak Tavargeri
 
What’s new in Rational collaborative lifecycle management 2011?
What’s new in Rational collaborative lifecycle management 2011?What’s new in Rational collaborative lifecycle management 2011?
What’s new in Rational collaborative lifecycle management 2011?IBM Danmark
 
Software variability management - 2019
Software variability management - 2019Software variability management - 2019
Software variability management - 2019XavierDevroey
 
IncQuery_presentation_Incose_EMEA_WSEC.pptx
IncQuery_presentation_Incose_EMEA_WSEC.pptxIncQuery_presentation_Incose_EMEA_WSEC.pptx
IncQuery_presentation_Incose_EMEA_WSEC.pptxIncQuery Labs
 
[2015/2016] Modern development paradigms
[2015/2016] Modern development paradigms[2015/2016] Modern development paradigms
[2015/2016] Modern development paradigmsIvano Malavolta
 
Machine Learning Models in Production
Machine Learning Models in ProductionMachine Learning Models in Production
Machine Learning Models in ProductionDataWorks Summit
 
Delivering Developer Tools at Scale
Delivering Developer Tools at ScaleDelivering Developer Tools at Scale
Delivering Developer Tools at ScaleOracle Developers
 
Tutorial Expert How-To - Command Line Interface (CLI)
Tutorial Expert How-To - Command Line Interface (CLI)Tutorial Expert How-To - Command Line Interface (CLI)
Tutorial Expert How-To - Command Line Interface (CLI)PascalDesmarets1
 
Next-Generation Completeness and Consistency Management in the Digital Threa...
Next-Generation Completeness and Consistency Management in the Digital Threa...Next-Generation Completeness and Consistency Management in the Digital Threa...
Next-Generation Completeness and Consistency Management in the Digital Threa...Ákos Horváth
 
(ATS6-DEV02) Web Application Strategies
(ATS6-DEV02) Web Application Strategies(ATS6-DEV02) Web Application Strategies
(ATS6-DEV02) Web Application StrategiesBIOVIA
 

Ähnlich wie openCPQ - A React-Based Product-Configuration Toolkit (20)

PHPFrameworkDay 2020 - Different software evolutions from Start till Release ...
PHPFrameworkDay 2020 - Different software evolutions from Start till Release ...PHPFrameworkDay 2020 - Different software evolutions from Start till Release ...
PHPFrameworkDay 2020 - Different software evolutions from Start till Release ...
 
"Different software evolutions from Start till Release in PHP product" Oleksa...
"Different software evolutions from Start till Release in PHP product" Oleksa..."Different software evolutions from Start till Release in PHP product" Oleksa...
"Different software evolutions from Start till Release in PHP product" Oleksa...
 
Modern development paradigms
Modern development paradigmsModern development paradigms
Modern development paradigms
 
The building blocks for a reusable front end - #imaodbc2015
The building blocks for a reusable front end - #imaodbc2015The building blocks for a reusable front end - #imaodbc2015
The building blocks for a reusable front end - #imaodbc2015
 
JArchitect Benefits
JArchitect BenefitsJArchitect Benefits
JArchitect Benefits
 
Introduction to Data Models & Cisco's NextGen Device Level APIs: an overview
Introduction to Data Models & Cisco's NextGen Device Level APIs: an overviewIntroduction to Data Models & Cisco's NextGen Device Level APIs: an overview
Introduction to Data Models & Cisco's NextGen Device Level APIs: an overview
 
Building A Product Assortment Recommendation Engine
Building A Product Assortment Recommendation EngineBuilding A Product Assortment Recommendation Engine
Building A Product Assortment Recommendation Engine
 
COMPRO- WEB ALBUM & MOTION ANALYZER
COMPRO- WEB ALBUM  & MOTION ANALYZERCOMPRO- WEB ALBUM  & MOTION ANALYZER
COMPRO- WEB ALBUM & MOTION ANALYZER
 
Productionizing Machine Learning - Bigdata meetup 5-06-2019
Productionizing Machine Learning - Bigdata meetup 5-06-2019Productionizing Machine Learning - Bigdata meetup 5-06-2019
Productionizing Machine Learning - Bigdata meetup 5-06-2019
 
What's new in Portal and WCM 8.5
What's new in Portal and WCM 8.5What's new in Portal and WCM 8.5
What's new in Portal and WCM 8.5
 
What’s new in Rational collaborative lifecycle management 2011?
What’s new in Rational collaborative lifecycle management 2011?What’s new in Rational collaborative lifecycle management 2011?
What’s new in Rational collaborative lifecycle management 2011?
 
Software variability management - 2019
Software variability management - 2019Software variability management - 2019
Software variability management - 2019
 
IncQuery_presentation_Incose_EMEA_WSEC.pptx
IncQuery_presentation_Incose_EMEA_WSEC.pptxIncQuery_presentation_Incose_EMEA_WSEC.pptx
IncQuery_presentation_Incose_EMEA_WSEC.pptx
 
[2015/2016] Modern development paradigms
[2015/2016] Modern development paradigms[2015/2016] Modern development paradigms
[2015/2016] Modern development paradigms
 
Machine Learning Models in Production
Machine Learning Models in ProductionMachine Learning Models in Production
Machine Learning Models in Production
 
Delivering Developer Tools at Scale
Delivering Developer Tools at ScaleDelivering Developer Tools at Scale
Delivering Developer Tools at Scale
 
Open Source Soa
Open Source SoaOpen Source Soa
Open Source Soa
 
Tutorial Expert How-To - Command Line Interface (CLI)
Tutorial Expert How-To - Command Line Interface (CLI)Tutorial Expert How-To - Command Line Interface (CLI)
Tutorial Expert How-To - Command Line Interface (CLI)
 
Next-Generation Completeness and Consistency Management in the Digital Threa...
Next-Generation Completeness and Consistency Management in the Digital Threa...Next-Generation Completeness and Consistency Management in the Digital Threa...
Next-Generation Completeness and Consistency Management in the Digital Threa...
 
(ATS6-DEV02) Web Application Strategies
(ATS6-DEV02) Web Application Strategies(ATS6-DEV02) Web Application Strategies
(ATS6-DEV02) Web Application Strategies
 

Kürzlich hochgeladen

Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Andreas Granig
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfjoe51371421
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...Christina Lin
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantAxelRicardoTrocheRiq
 
Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...aditisharan08
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideChristina Lin
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...OnePlan Solutions
 
What is Binary Language? Computer Number Systems
What is Binary Language?  Computer Number SystemsWhat is Binary Language?  Computer Number Systems
What is Binary Language? Computer Number SystemsJheuzeDellosa
 
buds n tech IT solutions
buds n  tech IT                solutionsbuds n  tech IT                solutions
buds n tech IT solutionsmonugehlot87
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
cybersecurity notes for mca students for learning
cybersecurity notes for mca students for learningcybersecurity notes for mca students for learning
cybersecurity notes for mca students for learningVitsRangannavar
 
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝soniya singh
 
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfThe Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfkalichargn70th171
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEOrtus Solutions, Corp
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataBradBedford3
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...kellynguyen01
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
 
The Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfThe Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfPower Karaoke
 
What are the features of Vehicle Tracking System?
What are the features of Vehicle Tracking System?What are the features of Vehicle Tracking System?
What are the features of Vehicle Tracking System?Watsoo Telematics
 

Kürzlich hochgeladen (20)

Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdf
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service Consultant
 
Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
 
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...
 
What is Binary Language? Computer Number Systems
What is Binary Language?  Computer Number SystemsWhat is Binary Language?  Computer Number Systems
What is Binary Language? Computer Number Systems
 
buds n tech IT solutions
buds n  tech IT                solutionsbuds n  tech IT                solutions
buds n tech IT solutions
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
cybersecurity notes for mca students for learning
cybersecurity notes for mca students for learningcybersecurity notes for mca students for learning
cybersecurity notes for mca students for learning
 
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
 
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfThe Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
 
The Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfThe Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdf
 
What are the features of Vehicle Tracking System?
What are the features of Vehicle Tracking System?What are the features of Vehicle Tracking System?
What are the features of Vehicle Tracking System?
 

openCPQ - A React-Based Product-Configuration Toolkit